前一阵子优化了个SQL,原代码如下:
前一阵子,优化了一个SQL,原代码如下:
create or replace package body CUX_INV_DEAD_STOCK_DETAIL_PKG is
/* ================================================================================
* PROGRAM NAME:
* CUX_INV_DEAD_STOCK_DETAIL_PKG
*
* PROGRAM STRUCTURE:
*
* ==============================================================================*/
g_error varchar2(500);
g_debug varchar2(500);
procedure outlog(g_message in varchar2) is
begin
fnd_file.PUT_LINE(fnd_file.LOG,g_message);
end outlog; --输出日志
procedure output(g_message in varchar2) is
begin
fnd_file.PUT_LINE(fnd_file.OUTPUT,g_message);
dbms_output.put_line(g_message);
end output; --输出
/* =================================================================================
* FUNCTION / PROCEDURE
* NAME : INV_DEAD_STOCK_DETAIL_MAIN
* DESCRIPTION: CUX:呆滞物料统计表
*
* ==================================================================================*/
procedure inv_dead_stock_detail_main(o_errcode out varchar2,
o_errmess out varchar2,
p_org_id in number, --业务实体
p_item_category in varchar2, --物料类型
p_inventory_item_f in varchar2, --物料从
p_inventory_item_t in varchar2, --物料至
p_dead_days in number --呆滞天数
) is
v_print_date varchar2(30); --打印日期
v_ou varchar2(30); --业务实体
v_item_category varchar2(100); --物料类型
v_inventory_item_f varchar2(100); --物料从
v_inventory_item_t varchar2(100); --物料至
v_dead_days varchar2(10); --呆滞天数
cursor c1 is
select b.organization_id,
b.item_category,
b.item_sub_category,
b.segment1,
b.description,
b.primary_unit_of_measure,
b.item_cost,
b.onhand_quantity,
b.onhand_amount,
b.last_transaction_date,
b.dead_stock_days
from (select a.organization_id,
a.item_category,
a.item_sub_category,
a.segment1,
a.description,
a.primary_unit_of_measure,
a.item_cost,
a.onhand_quantity,
a.onhand_amount,
max(mmt.transaction_date) last_transaction_date,
trunc(sysdate - max(mmt.transaction_date)) dead_stock_days
from mtl_material_transactions mmt,
(select msib.organization_id,
msib.inventory_item_id,
mcb.segment1 item_category, --物料大类
mcb.segment2 item_sub_category, --物料小类
msib.segment1,
msib.description,
--onhand.transaction_uom_code,
msib.primary_unit_of_measure,
cic.item_cost,
sum(onhand.transaction_quantity) onhand_quantity,
(cic.item_cost * sum(onhand.transaction_quantity)) onhand_amount
from mtl_system_items_b msib,
cst_item_costs cic,
mtl_categories_b mcb,
mtl_item_categories mic,
mtl_onhand_quantities_detail onhand
where 1 = 1
and msib.inventory_item_id = onhand.inventory_item_id
and msib.organization_id = onhand.organization_id
and onhand.inventory_item_id = cic.inventory_item_id
and onhand.organization_id = cic.organization_id
and mcb.category_id = mic.category_id
and mic.inventory_item_id=msib.inventory_item_id
and mic.organization_id=msib.organization_id
and mcb.structure_id = 101
and mic.category_set_id = 1
and cic.cost_type_id = 3
and onhand.organization_id = p_org_id
--and msib.inventory_item_id=3073
and mcb.segment2=nvl(p_item_category,mcb.segment2)
and substr(onhand.subinventory_code,1,1)not in ('E','B')
and msib.segment1 between nvl(p_inventory_item_f,msib.segment1) and nvl(p_inventory_item_t,msib.segment1)
group by msib.organization_id,
msib.inventory_item_id,
mcb.segment1,
mcb.segment2,
msib.segment1,
msib.description,
msib.primary_unit_of_measure,
cic.item_cost) a
where 1 = 1
and a.organization_id = mmt.organization_id
and a.inventory_item_id = mmt.inventory_item_id
and mmt.transaction_type_id <>24
group by a.organization_id,
a.item_category,
a.item_sub_category,
a.segment1,
a.description,
a.primary_unit_of_measure,
a.item_cost,
a.onhand_quantity,
a.onhand_amount) b
where b.dead_stock_days > nvl(p_dead_days,0);
begin
--处理报表头信息
g_debug := '初始化公司LOGO和输入条件';
--获取打印日期
select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS')
into v_print_date
from dual;
--获取业务实体
select trim(hou.name)
into v_ou
from hr_operating_units hou
where hou.organization_id = p_org_id;
--获取物料类型
v_item_category:=trim(p_item_category);
--获取物料从
v_inventory_item_f:=trim(p_inventory_item_f);
--获取物料至
v_inventory_item_t:=trim(p_inventory_item_t);
--获取物料呆滞天数
v_dead_days:=to_char(p_dead_days);
--开始输出报表头信息
g_debug :='输出打印日期和用户输入条件';
output('<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by Oracle Reports version 10.1.2.3.0 -->
<CUXINVDEADSTOCK>
<LIST_G_REPORT>');
output('<PRINT_DATE>' || v_print_date || '</PRINT_DATE>');
output('<OU>' || v_ou || '</OU>');
output('<ITEM_CATEGORY>' || v_item_category || '</ITEM_CATEGORY>');
output('<INVENTORY_ITEM_F>' || v_inventory_item_f || '</INVENTORY_ITEM_F>');
output('<INVENTORY_ITEM_T>' || v_inventory_item_t || '</INVENTORY_ITEM_T>');
output('<DEAD_DAYS>' || v_dead_days || '</DEAD_DAYS>');
--主体数据内循环开始
g_debug :='主体数据内循环开始';
for c1r in c1 loop
output('<G_REPORT>');
output('<CATEGORY_CODE>' || c1r.item_category ||'.'|| c1r.item_sub_category || '</CATEGORY_CODE>');
output('<ITEM_CODE>' || c1r.segment1 || '</ITEM_CODE>');
output('<ITEM_DESCRIPTION>' || cux_common_pkg.Xml_Format(c1r.description) || '</ITEM_DESCRIPTION>');
output('<ITEM_UOM>' || c1r.primary_unit_of_measure || '</ITEM_UOM>');
output('<ITEM_ONHAND>' || c1r.Onhand_Quantity || '</ITEM_ONHAND>');
output('<LAST_TRANSACTION>' || to_char(c1r.last_transaction_date,'YYYY-MM-DD HH24:MI:SS') || '</LAST_TRANSACTION>');
output('<DEAD_STOCK_DAYS>' || c1r.Dead_Stock_Days || '</DEAD_STOCK_DAYS>');
output('<ITEM_COST>' || c1r.Item_Cost || '</ITEM_COST>');
output('<ONHAND_AMOUNT>' || c1r.onhand_amount || '</ONHAND_AMOUNT>');
output('</G_REPORT>');
end loop;
output('</LIST_G_REPORT>');
output('</CUXINVDEADSTOCK>');
exception
when others then
g_error := SQLERRM;
INSERT INTO session_log --记录异常信息到异常表
VALUES
(SYSDATE, 'INVENTORY', 'CUX_INV_DEAD_STOCK_DETAIL_PKG', g_debug, g_error);
COMMIT;
outlog('出现错误');
end inv_dead_stock_detail_main;
end CUX_INV_DEAD_STOCK_DETAIL_PKG;
这段代码运行的环境是oracle EBS R12中的一个查询呆滞物料的报表,运行的环境为IBM小机P系列(印象中应该P750)+v7000存储,这个报表跑出来的时间是最长达35分钟,在另一个低点的测试环境中用了将近七小时(具体配置就不提了),用10046 trace 出来的结果为(只取其中的主要的一段):
SELECT B.ORGANIZATION_ID, B.ITEM_CATEGORY, B.ITEM_SUB_CATEGORY, B.SEGMENT1,
B.DESCRIPTION, B.PRIMARY_UNIT_OF_MEASURE, B.ITEM_COST, B.ONHAND_QUANTITY,
B.ONHAND_AMOUNT, B.LAST_TRANSACTION_DATE, B.DEAD_STOCK_DAYS
FROM
(SELECT A.ORGANIZATION_ID, A.ITEM_CATEGORY, A.ITEM_SUB_CATEGORY, A.SEGMENT1,
A.DESCRIPTION, A.PRIMARY_UNIT_OF_MEASURE, A.ITEM_COST, A.ONHAND_QUANTITY,
A.ONHAND_AMOUNT, MAX(MMT.TRANSACTION_DATE) LAST_TRANSACTION_DATE,
TRUNC(SYSDATE - MAX(MMT.TRANSACTION_DATE)) DEAD_STOCK_DAYS FROM
MTL_MATERIAL_TRANSACTIONS MMT, (SELECT MSIB.ORGANIZATION_ID,
MSIB.INVENTORY_ITEM_ID, MCB.SEGMENT1 ITEM_CATEGORY, MCB.SEGMENT2
ITEM_SUB_CATEGORY, MSIB.SEGMENT1, MSIB.DESCRIPTION,
MSIB.PRIMARY_UNIT_OF_MEASURE, CIC.ITEM_COST,
SUM(ONHAND.TRANSACTION_QUANTITY) ONHAND_QUANTITY, (CIC.ITEM_COST *
SUM(ONHAND.TRANSACTION_QUANTITY)) ONHAND_AMOUNT FROM MTL_SYSTEM_ITEMS_B
MSIB, CST_ITEM_COSTS CIC, MTL_CATEGORIES_B MCB, MTL_ITEM_CATEGORIES MIC,
MTL_ONHAND_QUANTITIES_DETAIL ONHAND WHERE 1 = 1 AND MSIB.INVENTORY_ITEM_ID =
ONHAND.INVENTORY_ITEM_ID AND MSIB.ORGANIZATION_ID = ONHAND.ORGANIZATION_ID
AND ONHAND.INVENTORY_ITEM_ID = CIC.INVENTORY_ITEM_ID AND
ONHAND.ORGANIZATION_ID = CIC.ORGANIZATION_ID AND MCB.CATEGORY_ID =
MIC.CATEGORY_ID AND MIC.INVENTORY_ITEM_ID=MSIB.INVENTORY_ITEM_ID AND
MIC.ORGANIZATION_ID=MSIB.ORGANIZATION_ID AND MCB.STRUCTURE_ID = 101 AND
MIC.CATEGORY_SET_ID = 1 AND CIC.COST_TYPE_ID = 3 AND ONHAND.ORGANIZATION_ID
= :B4 AND MCB.SEGMENT2=NVL(:B3 ,MCB.SEGMENT2) AND
SUBSTR(ONHAND.SUBINVENTORY_CODE,1,1)NOT IN ('E','B') AND MSIB.SEGMENT1
BETWEEN NVL(:B2 ,MSIB.SEGMENT1) AND NVL(:B1 ,MSIB.SEGMENT1) GROUP BY
MSIB.ORGANIZATION_ID, MSIB.INVENTORY_ITEM_ID, MCB.SEGMENT1, MCB.SEGMENT2,
MSIB.SEGMENT1, MSIB.DESCRIPTION, MSIB.PRIMARY_UNIT_OF_MEASURE,
CIC.ITEM_COST) A WHERE 1 = 1 AND A.ORGANIZATION_ID = MMT.ORGANIZATION_ID
AND A.INVENTORY_ITEM_ID = MMT.INVENTORY_ITEM_ID AND MMT.TRANSACTION_TYPE_ID
<>24 GROUP BY A.ORGANIZATION_ID, A.ITEM_CATEGORY, A.ITEM_SUB_CATEGORY,
A.SEGMENT1, A.DESCRIPTION, A.PRIMARY_UNIT_OF_MEASURE, A.ITEM_COST,
A.ONHAND_QUANTITY, A.ONHAND_AMOUNT) B WHERE B.DEAD_STOCK_DAYS > NVL(:B5 ,0)
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 259.38 7987.81 1336813 28643548 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 259.38 7987.81 1336813 28643548 0 0
Misses in library cache during parse: 0
Optimizer goal: ALL_ROWS
Parsing user id: 44 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
0 FILTER (cr=0 pr=0 pw=0 time=0 us)
0 HASH GROUP BY (cr=0 pr=0 pw=0 time=0 us cost=408 size=138 card=1)
2382290 NESTED LOOPS (cr=28643548 pr=1336813 pw=0 time=7771837034 us)
2384353 NESTED LOOPS (cr=26956486 pr=38996 pw=0 time=133943370 us cost=407 size=4968 card=36)
4323 VIEW (cr=26927194 pr=19148 pw=0 time=51978 us cost=377 size=118 card=1)
4323 HASH GROUP BY (cr=26927194 pr=19148 pw=0 time=32507 us)
39226 CONCATENATION (cr=26927194 pr=19148 pw=0 time=200800799 us)
39226 FILTER (cr=26927194 pr=19148 pw=0 time=200782622 us)
39226 NESTED LOOPS (cr=26927194 pr=19148 pw=0 time=200762465 us)
39226 NESTED LOOPS (cr=26874154 pr=13992 pw=0 time=169916397 us cost=261 size=152 card=1)
39249 NESTED LOOPS (cr=26795777 pr=9888 pw=0 time=150089655 us cost=259 size=134 card=1)
4592133 NESTED LOOPS (cr=17625783 pr=6874 pw=0 time=110462727 us cost=247 size=1368 card=12)
4592133 MERGE JOIN CARTESIAN (cr=10739 pr=402 pw=0 time=6150125 us cost=223 size=612 card=12)
117 TABLE ACCESS BY INDEX ROWID MTL_CATEGORIES_B (cr=11 pr=10 pw=0 time=17429 us cost=4 size=34 card=1)
117 INDEX RANGE SCAN MTL__CATEGORIES_B_N2 (cr=1 pr=1 pw=0 time=560 us cost=1 size=0 card=29)(object id 118829)
4592133 BUFFER SORT (cr=10728 pr=392 pw=0 time=4082113 us cost=219 size=884 card=52)
39249 TABLE ACCESS BY INDEX ROWID MTL_ONHAND_QUANTITIES_DETAIL (cr=10728 pr=392 pw=0 time=709319 us cost=219 size=884 card=52)
39249 INDEX RANGE SCAN MTL_ONHAND_QUANTITIES_N5 (cr=385 pr=385 pw=0 time=575783 us cost=204 size=0 card=52)(object id 120237)
4592133 TABLE ACCESS BY INDEX ROWID MTL_SYSTEM_ITEMS_B (cr=17615044 pr=6472 pw=0 time=0 us cost=2 size=63 card=1)
4592133 INDEX UNIQUE SCAN MTL_SYSTEM_ITEMS_B_U1 (cr=9171958 pr=1125 pw=0 time=0 us cost=1 size=0 card=1)(object id 120986)
39249 INDEX UNIQUE SCAN MTL_ITEM_CATEGORIES_U1 (cr=9169994 pr=3014 pw=0 time=0 us cost=1 size=20 card=1)(object id 119585)
39226 INDEX UNIQUE SCAN CST_ITEM_COSTS_U1 (cr=78377 pr=4104 pw=0 time=0 us cost=1 size=0 card=1)(object id 208817)
39226 TABLE ACCESS BY INDEX ROWID CST_ITEM_COSTS (cr=53040 pr=5156 pw=0 time=0 us cost=2 size=18 card=1)
0 FILTER (cr=0 pr=0 pw=0 time=0 us)
0 NESTED LOOPS (cr=0 pr=0 pw=0 time=0 us)
0 NESTED LOOPS (cr=0 pr=0 pw=0 time=0 us cost=115 size=152 card=1)
0 NESTED LOOPS (cr=0 pr=0 pw=0 time=0 us cost=113 size=134 card=1)
0 NESTED LOOPS (cr=0 pr=0 pw=0 time=0 us cost=110 size=117 card=1)
0 MERGE JOIN CARTESIAN (cr=0 pr=0 pw=0 time=0 us cost=46 size=6208 card=64)
0 TABLE ACCESS BY INDEX ROWID MTL_CATEGORIES_B (cr=0 pr=0 pw=0 time=0 us cost=4 size=34 card=1)
0 INDEX RANGE SCAN MTL__CATEGORIES_B_N2 (cr=0 pr=0 pw=0 time=0 us cost=1 size=0 card=29)(object id 118829)
0 BUFFER SORT (cr=0 pr=0 pw=0 time=0 us cost=42 size=17262 card=274)
0 TABLE ACCESS BY INDEX ROWID MTL_SYSTEM_ITEMS_B (cr=0 pr=0 pw=0 time=0 us cost=42 size=17262 card=274)
0 INDEX RANGE SCAN MTL_SYSTEM_ITEMS_B_U2 (cr=0 pr=0 pw=0 time=0 us cost=7 size=0 card=49)(object id 408422)
0 INDEX UNIQUE SCAN MTL_ITEM_CATEGORIES_U1 (cr=0 pr=0 pw=0 time=0 us cost=1 size=20 card=1)(object id 119585)
0 TABLE ACCESS BY INDEX ROWID MTL_ONHAND_QUANTITIES_DETAIL (cr=0 pr=0 pw=0 time=0 us cost=3 size=17 card=1)
0 INDEX RANGE SCAN MTL_ONHAND_QUANTITIES_N4 (cr=0 pr=0 pw=0 time=0 us cost=2 size=0 card=1)(object id 120239)
0 INDEX UNIQUE SCAN CST_ITEM_COSTS_U1 (cr=0 pr=0 pw=0 time=0 us cost=1 size=0 card=1)(object id 208817)
0 TABLE ACCESS BY INDEX ROWID CST_ITEM_COSTS (cr=0 pr=0 pw=0 time=0 us cost=2 size=18 card=1)
2384353 INDEX RANGE SCAN MTL_MATERIAL_TRANSACTIONS_N1 (cr=29292 pr=19848 pw=0 time=97162036 us cost=3 size=0 card=41)(object id 119944)
2382290 TABLE ACCESS BY INDEX ROWID MTL_MATERIAL_TRANSACTIONS (cr=1687062 pr=1297817 pw=0 time=0 us cost=31 size=720 card=36)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
db file sequential read 1336813 0.64 7789.24
latch free 1 0.00 0.00
从上面的执行计划中可以看到,大量的nested loops中逻辑读与物理读很大,而在外层嵌套中表
MTL_MATERIAL_TRANSACTIONS的数据量大,消耗的时间7771,837034us 即将近七小时,改写方案如下:
1.先创建临时表,用来存放内层结果:
2.将传进来的参数作判断处理,
3.将最外层表与内层结果用hash 返回结果;
结果如下:
CREATE GLOBAL TEMPORARY TABLE CUX.DEAD_MT
(
ORGANIZATION_ID NUMBER, --MSIB_ORGANIZATION_ID
INVENTORY_ITEM_ID NUMBER, --MSIB_INVENTORY_ITEM_ID
item_category VARCHAR2(40 BYTE), -- MCB_SEGMENT1 item_category, --物料大类
item_sub_category VARCHAR2(40 BYTE), -- MCB_SEGMENT2 item_sub_category, --物料小类
SEGMENT1 VARCHAR2(40 BYTE), --MSIB_SEGMENT1
DESCRIPTION VARCHAR2(240 BYTE), --MSIB_DESCRIPTION
PRIMARY_UNIT_OF_MEASURE VARCHAR2(25 BYTE), --MSIB_PRIMARY_UNIT_OF_MEASURE
ITEM_COST NUMBER, --CIC_ITEM_COST
ONHAND_QUANTITY NUMBER, --sum(onhand.transaction_quantity) onhand_quantity,
ONHAND_AMOUNT NUMBER --(cic.item_cost * sum(onhand.transaction_quantity))
)
ON COMMIT DELETE ROWS;
create or replace package body CUX_INV_DEAD_STOCK_DETAIL_PKG is
/* ================================================================================
* PROGRAM NAME:
* CUX_INV_DEAD_STOCK_DETAIL_PKG
*
* ==============================================================================*/
g_error varchar2(500);
g_debug varchar2(500);
procedure outlog(g_message in varchar2) is
begin
fnd_file.PUT_LINE(fnd_file.LOG,g_message);
end outlog; --输出日志
procedure output(g_message in varchar2) is
begin
fnd_file.PUT_LINE(fnd_file.OUTPUT,g_message);
dbms_output.put_line(g_message);
end output; --输出
/* =================================================================================
* FUNCTION / PROCEDURE
* NAME : INV_DEAD_STOCK_DETAIL_MAIN
*
* ==================================================================================*/
procedure inv_dead_stock_detail_main(o_errcode out varchar2,
o_errmess out varchar2,
p_org_id in number, --业务实体
p_item_category in varchar2, --物料类型
p_inventory_item_f in varchar2, --物料从
p_inventory_item_t in varchar2, --物料至
p_dead_days in number --呆滞天数
) is
v_print_date varchar2(30); --打印日期
v_ou varchar2(30); --业务实体
v_item_category varchar2(100); --物料类型
v_inventory_item_f varchar2(100); --物料从
v_inventory_item_t varchar2(100); --物料至
v_dead_days varchar2(10); --呆滞天数
cursor c1 is
select b.organization_id,
b.item_category,
b.item_sub_category,
b.segment1,
b.description,
b.primary_unit_of_measure,
b.item_cost,
b.onhand_quantity,
b.onhand_amount,
b.last_transaction_date,
b.dead_stock_days
from(
select /*+use_hash(mmt ,a)*/
a.ORGANIZATION_ID,
a.item_category,
-- a.INVENTORY_ITEM_ID,
a.item_sub_category,
a.segment1,
a.description,
a.primary_unit_of_measure,
a.item_cost,
a.onhand_quantity,
a.onhand_amount,
max(mmt.transaction_date) last_transaction_date,
trunc(TO_DATE('2015-3-30 11:36:00','YYYY-MM-DD HH24:MI:SS') - max(mmt.transaction_date)) dead_stock_days
--trunc(sysdate - max(mmt.transaction_date)) dead_stock_days
from mtl_material_transactions mmt, DEAD_MT a
where 1 = 1
and a.organization_id = mmt.organization_id
and a.inventory_item_id = mmt.inventory_item_id
and mmt.transaction_type_id <>24
and a.item_sub_category=nvl(p_item_category,a.item_sub_category)
--and a.segment1 between nvl(null,a.segment1) and nvl(null,a.segment1)
group by a.organization_id,
a.item_category,
a.item_sub_category,
a.segment1,
a.description,
a.primary_unit_of_measure,
a.item_cost,
a.onhand_quantity,
a.onhand_amount) b
where b.dead_stock_days > nvl(p_dead_days,0);
begin
if (p_inventory_item_f is null and p_inventory_item_t is null)
then
insert /* +append*/into DEAD_MT
select msib.organization_id,
msib.inventory_item_id,
mcb.segment1 item_category, --物料大类
mcb.segment2 item_sub_category, --物料小类
msib.segment1,
msib.description,
--onhand.transaction_uom_code,
msib.primary_unit_of_measure,
cic.item_cost,
sum(onhand.transaction_quantity) onhand_quantity,
(cic.item_cost * sum(onhand.transaction_quantity)) onhand_amount
from mtl_system_items_b msib,
cst_item_costs cic,
mtl_categories_b mcb,
mtl_item_categories mic,
mtl_onhand_quantities_detail onhand
where 1=1
and msib.inventory_item_id = onhand.inventory_item_id
and msib.organization_id = onhand.organization_id
and onhand.inventory_item_id = cic.inventory_item_id
and onhand.organization_id = cic.organization_id
and mcb.category_id = mic.category_id
and mic.inventory_item_id=msib.inventory_item_id
and mic.organization_id=msib.organization_id
and mcb.structure_id = 101
and mic.category_set_id = 1
and cic.cost_type_id = 3
and onhand.organization_id = p_org_id
--and msib.inventory_item_id=3073
-- and mcb.segment2=nvl(null,mcb.segment2) and mcb.segment2=nvl(p_item_category,mcb.segment2)
and substr(onhand.subinventory_code,1,1)not in ('E','B')
-- and msib.segment1 between nvl(null,msib.segment1) and nvl(null,msib.segment1)
-- and msib.segment1 between nvl(p_inventory_item_f,msib.segment1) and nvl(p_inventory_item_t,msib.segment1)
group by msib.organization_id,
msib.inventory_item_id,
mcb.segment1,
mcb.segment2,
msib.segment1,
msib.description,
msib.primary_unit_of_measure,
cic.item_cost;
end if;
if ( p_inventory_item_f is not null and p_inventory_item_t is not null)
then
insert into DEAD_MT
select msib.organization_id,
msib.inventory_item_id,
mcb.segment1 item_category, --物料大类
mcb.segment2 item_sub_category, --物料小类
msib.segment1,
msib.description,
--onhand.transaction_uom_code,
msib.primary_unit_of_measure,
cic.item_cost,
sum(onhand.transaction_quantity) onhand_quantity,
(cic.item_cost * sum(onhand.transaction_quantity)) onhand_amount
from mtl_system_items_b msib,
cst_item_costs cic,
mtl_categories_b mcb,
mtl_item_categories mic,
mtl_onhand_quantities_detail onhand
where 1=1
and msib.inventory_item_id = onhand.inventory_item_id
and msib.organization_id = onhand.organization_id
and onhand.inventory_item_id = cic.inventory_item_id
and onhand.organization_id = cic.organization_id
and mcb.category_id = mic.category_id
and mic.inventory_item_id=msib.inventory_item_id
and mic.organization_id=msib.organization_id
and mcb.structure_id = 101
and mic.category_set_id = 1
and cic.cost_type_id = 3
and onhand.organization_id = p_org_id
--and msib.inventory_item_id=3073
--and mcb.segment2=nvl(null,mcb.segment2)
--and mcb.segment2=p_item_category
and substr(onhand.subinventory_code,1,1)not in ('E','B')
-- and msib.segment1 between nvl(null,msib.segment1) and nvl(null,msib.segment1)
and msib.segment1 between p_inventory_item_f and p_inventory_item_t
group by msib.organization_id,
msib.inventory_item_id,
mcb.segment1,
mcb.segment2,
msib.segment1,
msib.description,
msib.primary_unit_of_measure,
cic.item_cost;
end if;
if ( p_inventory_item_f is not null and p_inventory_item_t is null)
then
insert into DEAD_MT
select msib.organization_id,
msib.inventory_item_id,
mcb.segment1 item_category, --物料大类
mcb.segment2 item_sub_category, --物料小类
msib.segment1,
msib.description,
--onhand.transaction_uom_code,
msib.primary_unit_of_measure,
cic.item_cost,
sum(onhand.transaction_quantity) onhand_quantity,
(cic.item_cost * sum(onhand.transaction_quantity)) onhand_amount
from mtl_system_items_b msib,
cst_item_costs cic,
mtl_categories_b mcb,
mtl_item_categories mic,
mtl_onhand_quantities_detail onhand
where 1=1
and msib.inventory_item_id = onhand.inventory_item_id
and msib.organization_id = onhand.organization_id
and onhand.inventory_item_id = cic.inventory_item_id
and onhand.organization_id = cic.organization_id
and mcb.category_id = mic.category_id
and mic.inventory_item_id=msib.inventory_item_id
and mic.organization_id=msib.organization_id
and mcb.structure_id = 101
and mic.category_set_id = 1
and cic.cost_type_id = 3
and onhand.organization_id = p_org_id
--and msib.inventory_item_id=3073
--and mcb.segment2=nvl(null,mcb.segment2)
and mcb.segment2=p_item_category
and substr(onhand.subinventory_code,1,1)not in ('E','B')
-- and msib.segment1 between nvl(null,msib.segment1) and nvl(null,msib.segment1)
and msib.segment1 between p_inventory_item_f and msib.segment1
group by msib.organization_id,
msib.inventory_item_id,
mcb.segment1,
mcb.segment2,
msib.segment1,
msib.description,
msib.primary_unit_of_measure,
cic.item_cost;
end if;
--处理报表头信息
g_debug := '初始化公司LOGO和输入条件';
--获取打印日期
select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS')
into v_print_date
from dual;
--获取业务实体
select trim(hou.name)
into v_ou
from hr_operating_units hou
where hou.organization_id = p_org_id;
--获取物料类型
v_item_category:=trim(p_item_category);
--获取物料从
v_inventory_item_f:=trim(p_inventory_item_f);
--获取物料至
v_inventory_item_t:=trim(p_inventory_item_t);
--获取物料呆滞天数
v_dead_days:=to_char(p_dead_days);
--开始输出报表头信息
g_debug :='输出打印日期和用户输入条件';
output('<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by Oracle Reports version 10.1.2.3.0 -->
<CUXINVDEADSTOCK>
<LIST_G_REPORT>');
output('<PRINT_DATE>' || v_print_date || '</PRINT_DATE>');
output('<OU>' || v_ou || '</OU>');
output('<ITEM_CATEGORY>' || v_item_category || '</ITEM_CATEGORY>');
output('<INVENTORY_ITEM_F>' || v_inventory_item_f || '</INVENTORY_ITEM_F>');
output('<INVENTORY_ITEM_T>' || v_inventory_item_t || '</INVENTORY_ITEM_T>');
output('<DEAD_DAYS>' || v_dead_days || '</DEAD_DAYS>');
--主体数据内循环开始
g_debug :='主体数据内循环开始';
for c1r in c1 loop
output('<G_REPORT>');
output('<CATEGORY_CODE>' || c1r.item_category ||'.'|| c1r.item_sub_category || '</CATEGORY_CODE>');
output('<ITEM_CODE>' || c1r.segment1 || '</ITEM_CODE>');
output('<ITEM_DESCRIPTION>' || cux_common_pkg.Xml_Format(c1r.description) || '</ITEM_DESCRIPTION>');
output('<ITEM_UOM>' || c1r.primary_unit_of_measure || '</ITEM_UOM>');
output('<ITEM_ONHAND>' || c1r.Onhand_Quantity || '</ITEM_ONHAND>');
output('<LAST_TRANSACTION>' || to_char(c1r.last_transaction_date,'YYYY-MM-DD HH24:MI:SS') || '</LAST_TRANSACTION>');
output('<DEAD_STOCK_DAYS>' || c1r.Dead_Stock_Days || '</DEAD_STOCK_DAYS>');
output('<ITEM_COST>' || c1r.Item_Cost || '</ITEM_COST>');
output('<ONHAND_AMOUNT>' || c1r.onhand_amount || '</ONHAND_AMOUNT>');
output('</G_REPORT>');
end loop;
output('</LIST_G_REPORT>');
output('</CUXINVDEADSTOCK>');
exception
when others then
g_error := SQLERRM;
INSERT INTO session_log --记录异常信息到异常表
VALUES
(SYSDATE, 'INVENTORY', 'CUX_INV_DEAD_STOCK_DETAIL_PKG', g_debug, g_error);
COMMIT;
outlog('出现错误');
end inv_dead_stock_detail_main;
end CUX_INV_DEAD_STOCK_DETAIL_PKG;
这样变更后,在正式环境中运行的时为3分钟46秒,测试环境,从7小时变是20分钟。
转载于:https://blog.51cto.com/jonsen/1628995