如何解决ORA-06530 对 PL/SQL 过程中未初始化复合错误的引用
create or replace PACKAGE BODY "DTS_INVOICE_RESEARCH_PKG" AS
PROCEDURE DO_RESEARCH (IN_ROW_TBL IN OUT NOcopY DTS.DTS_CARRIER_ROW_TBL,OUT_ROW_VARRAY IN OUT NOcopY DTS.DTS_CARRIER_ROW_RETURN_VARRAY)
AS
TYPE CARRIER_ROW_REC_COLLECTION IS TABLE OF DTS.DTS_CARRIER_ROW_REC INDEX BY VARCHAR2(50);
COUNTER INTEGER := 0;
TRACKING_NUMBER VARCHAR2(50);
ROW_COLLECTION CARRIER_ROW_REC_COLLECTION; --K,V pair of tracking number and CARRIER_ROW_REC
--This cursor finds all tracking numbers which already exist in the INVOICE_CARTON table
--If they already exist,that means the tracking number was prevIoUsly invoiced
CURSOR C1 IS
SELECT /*+ ParaLLEL(8) */ TRACKING_NUMBER
FROM DTS.DTS_INVOICE_CARTON
WHERE TRACKING_NUMBER IN
(SELECT TRACKING_NUMBER FROM TABLE(IN_ROW_TBL));
CURSOR C2 IS
select do.PROMISE_DATE,do.CUSTOMER_ID,do.region_id,upper(trim(dm.market)) market,count(do.CUSTOMER_ID) carton_count,dc.TRACKING_NUMBER TRACKING_NUMBER
from dts.dts_order_container dc,dts.dts_order do,dts.dts_route_matrix dm,dts.dts_invoice_ctr ct
where ct.region_id = dm.region_id
and ct.market_id = dm.market_id
and ct.vendor_id = dm.carrier_id
and dm.region_id = do.region_id
and dm.route_id = do.route_id
and do.order_number = dc.order_number
and dm.carrier_id IN (SELECT disTINCT dm.CARRIER_ID FROM TABLE(IN_ROW_TBL))
and dm.active = 'Y' --William,ensures we only reference active RM rows,fixes NAIT-28235
and dm.carrier_mode not in ('LTL','usps','PF','OTHER','Other','UPS')
and do.ORDER_NUMBER in (SELECT disTINCT do.ORDER_NUMBER FROM TABLE(IN_ROW_TBL))
and upper(trim(dm.market)) not like 'FURNITURE' --remove any markets that have 'furniture' in them
group by do.PROMISE_DATE,upper(trim(dm.market)),dc.tracking_number
having count(do.CUSTOMER_ID) = 1
order by do.PROMISE_DATE,do.REGION_ID,do.CUSTOMER_ID;
C1_REC C1%rOWTYPE;
C2_REC C2%rOWTYPE;
BEGIN
OUT_ROW_VARRAY := DTS.DTS_CARRIER_ROW_RETURN_VARRAY();
OUT_ROW_VARRAY.EXTEND (IN_ROW_TBL.COUNT);
--Loops through the input table to create a collection for easy object updating
FOR IDX1 IN 1..IN_ROW_TBL.COUNT LOOP
--Stores the payable order statuses for each tracking number,if applicable
--The storing happens before the object is transferred into the collection
BEGIN
SELECT NVL(TO_NUMBER(ORDER_STATUS,'99'),0)
INTO IN_ROW_TBL(IDX1).ORDER_STATUS --sets the current object's edi status
FROM DTS.DTS_ORDER_STATUS_LOG
WHERE ORDER_NUMBER = IN_ROW_TBL(IDX1).ORDER_NUMBER
AND TRACKING_NUMBER = IN_ROW_TBL(IDX1).TRACKING_NUMBER
AND ORDER_STATUS IN ('50','51','52','07')
AND ROWNUM < 2; --ensures we don't get multple results and choke
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
ROW_COLLECTION(IN_ROW_TBL(IDX1).TRACKING_NUMBER) := IN_ROW_TBL(IDX1);
END LOOP;
--Loop through the cursor,and update the invoiced flag of whichever tracking numbers
--are returned by the cursor
OPEN C1;
LOOP
FETCH C1 INTO C1_REC;
EXIT WHEN C1%NOTFOUND;
--SET THE INVOICED FLAG FOR THE CARRIER_REC WHICH IS ASSOCIATED WITH THE TRACKING NUMBER WE FOUND
ROW_COLLECTION(C1_REC.TRACKING_NUMBER).INVOICED := 1; --INVOICED SHOULD EITHER BE 1 OR 0,SETTING TO 1 MEANS INVOICED
END LOOP;
CLOSE C1;
OPEN C2;
LOOP
FETCH C2 INTO C2_REC;
EXIT WHEN C2%NOTFOUND;
--SET THE INVOICED FLAG FOR THE CARRIER_REC WHICH IS ASSOCIATED WITH THE TRACKING NUMBER WE FOUND
ROW_COLLECTION(C2_REC.TRACKING_NUMBER).IS_SINGLE_CARTON := 1; --INVOICED SHOULD EITHER BE 1 OR 0,SETTING TO 1 MEANS INVOICED -- getting error at this line
END LOOP;
CLOSE C2;
--These are both control variables for iterating through the collection and storing
--the CARRIER_ROW objects in the output array
TRACKING_NUMBER := ROW_COLLECTION.FirsT;
COUNTER := 1;
--Loop through the collection to copy the ROW_REC objects into the output varray
WHILE TRACKING_NUMBER IS NOT NULL
LOOP
OUT_ROW_VARRAY(COUNTER) := ROW_COLLECTION(TRACKING_NUMBER);
TRACKING_NUMBER := ROW_COLLECTION.NEXT(TRACKING_NUMBER);
COUNTER := COUNTER + 1;
END LOOP;
END DO_RESEARCH;
END DTS_INVOICE_RESEARCH_PKG;
-> 一种对象类型为:
CREATE OR REPLACE TYPE "DTS"."DTS_CARRIER_ROW_REC" FORCE AS OBJECT
(
ORDER_NUMBER VARCHAR2(25 BYTE),TRACKING_NUMBER VARCHAR2(50 BYTE),ROW_NUMBER INT,INVOICED INT,ORDER_STATUS INT,CARRIER_ID VARCHAR2(20),IS_SINGLE_CARTON INT
);
ORA-06530: Reference to uninitialized composite
ORA-06512: at "DTS.DTS_INVOICE_RESEARCH_PKG",line 89
ORA-06512: at line 2
解决方法
除了你的包中的几个弱点(见我的评论),看起来你用未初始化的值调用了这个过程。
CREATE OR REPLACE TYPE DTS_CARRIER_ROW_TBL AS TABLE OF NUMBER;
CREATE OR REPLACE PROCEDURE DO_RESEARCH(IN_ROW_TBL IN DTS_CARRIER_ROW_TBL) IS
BEGIN
DBMS_OUTPUT.PUT_LINE ( 'Result: ' || IN_ROW_TBL.COUNT );
END;
/
和电话:
DECLARE
IN_ROW_TBL DTS_CARRIER_ROW_TBL;
BEGIN
DO_RESEARCH(IN_ROW_TBL);
END;
ORA-06531: Reference to uninitialized collection
ORA-06512: at "DO_RESEARCH",line 3
ORA-06512: at line 4
DECLARE
IN_ROW_TBL DTS_CARRIER_ROW_TBL := DTS_CARRIER_ROW_TBL();
BEGIN
DO_RESEARCH(IN_ROW_TBL);
END;
Result: 0
,
你的 ROW_COLLECTION 是 DTS.DTS_CARRIER_ROW_REC 的关联数组,它是 object
并且需要初始化,所以只需添加
if not ROW_COLLECTION.exists(C1_REC.TRACKING_NUMBER)
then ROW_COLLECTION(C1_REC.TRACKING_NUMBER) := DTS.DTS_CARRIER_ROW_REC(null,null,null);
end if;
如果你想用空值来初始化它或者
if not ROW_COLLECTION.exists(C1_REC.TRACKING_NUMBER)
then ROW_COLLECTION(C1_REC.TRACKING_NUMBER) := IN_ROW_TBL(C1_REC.TRACKING_NUMBER);
如果它必须从 IN_ROW_TBL 获取初始值。
在第 80 行和第 89 行之前:
ROW_COLLECTION(C1_REC.TRACKING_NUMBER).INVOICED := 1; --INVOICED SHOULD EITHER BE 1 OR 0,SETTING TO 1 MEANS INVOICED
ROW_COLLECTION(C2_REC.TRACKING_NUMBER).IS_SINGLE_CARTON := 1; --INVOICED SHOULD EITHER BE 1 OR 0,SETTING TO 1 MEANS INVOICED -- getting error at this line
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。