获取错误将未初始化的集合引用到关联数组

时间:2017-10-04 14:44:03

标签: oracle collections plsql associative-array

我正在创建的包中使用关联数组,我收到错误ORA-06531:如果我在批量收集到数组之前尝试获取计数(TBL.COUNT),则引用未初始化的集合。

我发现我可以使用EXISTS(1)来检查是否有东西而不是计数但是如果我没有批量收集它,我如何得到我需要用于下一行的索引?

loc_idx := TBL.COUNT; 
OR  
TBL(TBL.COUNT+1) := blah;

我的想法是你不需要初始化关联数组,而不像嵌套表和varrays

这是我正在使用的一个例子

TYPE invc_ln_item_type                  IS TABLE OF invc_ln_item%ROWTYPE;
invc_ln_item_tbl                        invc_ln_item_type; 

用作以下proc的输入

    PROCEDURE CREATE_INVC_LN_ITEM(P_LN_ITEM_TYPE_CD IN 
                                  invc_ln_item.ln_item_type_cd%TYPE, 
                                  P_LN_ITEM_SBTYPE_CD IN 
                                  invc_ln_item.ln_item_sbtype_cd%TYPE, 
                                  P_INVC_PK IN invc.invc_pk%TYPE,
                                  P_INVC_LN_ITEM_TBL IN OUT 
                                  invc_ln_item_type)
    IS
    loc_inv_ln_item_rec INVC_LN_ITEM%ROWTYPE;
    loc_idx             NUMBER;
BEGIN

    loc_idx := P_INVC_LN_ITEM_TBL.COUNT + 1;

    INSERT INTO APP.INVC_LN_ITEM (INVC_LN_ITEM_PK, 
                                  INSRT_DT, 
                                  INSRT_USER, 
                                  LAST_UPDT_DT, 
                                  LAST_UPDT_USER, 
                                  LN_ITEM_TYPE_CD, 
                                  LN_ITEM_SBTYPE_CD, 
                                  INVC_PK, 
                                  UNITS, 
                                  AMT)
                          VALUES (null,
                                  null,
                                  null,
                                  null,
                                  null,
                                  P_LN_ITEM_TYPE_CD,
                                  P_LN_ITEM_SBTYPE_CD,
                                  P_INVC_PK,
                                  0,
                                  0)
                        RETURNING INVC_LN_ITEM_PK, 
                                  INSRT_DT, 
                                  INSRT_USER, 
                                  LAST_UPDT_DT, 
                                  LAST_UPDT_USER, 
                                  LN_ITEM_TYPE_CD, 
                                  LN_ITEM_SBTYPE_CD, 
                                  INVC_PK, 
                                  UNITS, 
                                  AMT
                             INTO loc_inv_ln_item_rec; 

    P_INVC_LN_ITEM_TBL(loc_idx) := loc_inv_ln_item_rec;

END;

然后像

那样被调用
CREATE_INVC_LN_ITEM(P_BILLG_PRFL_LN_ITEM_REC.ln_item_type_cd, 
                                    billg_prfl_ln_item_sbtype_tbl(c).ln_item_sbtype_cd, 
                                    invc_rec.invc_pk,
                                    invc_ln_item_tbl); 

上述案例中的错误发生在:     loc_idx:= P_INVC_LN_ITEM_TBL.COUNT + 1;

[错误]执行(39:1):ORA-06531:未初始化集合的参考

1 个答案:

答案 0 :(得分:0)

关联数组没有递增索引。您不需要初始化关联数组,并且使用array.COUNT不会引发关联数组的异常(与集合不同)。

DECLARE
  TYPE arraytype IS TABLE OF VARCHAR2(20) INDEX BY VARCHAR2(2);

  array arraytype;
  idx VARCHAR2(2);
BEGIN
  DBMS_OUTPUT.PUT_LINE( array.COUNT ); -- 0
  array('A') := 'AAAA';
  DBMS_OUTPUT.PUT_LINE( array.COUNT ); -- 1
  array(array.COUNT + 1) := 'BBBB';
  DBMS_OUTPUT.PUT_LINE( array.COUNT ); -- 2
  array('7') := 'DDDD';
  DBMS_OUTPUT.PUT_LINE( array.COUNT ); -- 3

  idx := array.FIRST;
  WHILE idx IS NOT NULL LOOP
    DBMS_OUTPUT.PUT_LINE( idx || ' - ' || array(idx) );
    idx := array.NEXT( idx );
  END LOOP;
END;
/

如果您希望使用递增索引,则需要考虑关联数组是否是要使用的正确类型以及集合或VARRAY是否会更好。

如果您正在使用集合(非关联数组):

DECLARE
  TYPE arraytype IS TABLE OF VARCHAR2(20);

  array arraytype;
BEGIN
  array := arraytype(); -- Initialise
  DBMS_OUTPUT.PUT_LINE( array.COUNT ); -- 0
  array.EXTEND;                        -- Extend by 1 element
  array(1) := 'AAAA';
  DBMS_OUTPUT.PUT_LINE( array.COUNT ); -- 1
  array.EXTEND(1);                     -- Number of elements to extend by
  array(array.COUNT) := 'BBBB';
  DBMS_OUTPUT.PUT_LINE( array.COUNT ); -- 2
  array.EXTEND;
  array(3) := 'DDDD';
  DBMS_OUTPUT.PUT_LINE( array.COUNT ); -- 3

  FOR idx IN 1 .. array.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE( idx || ' - ' || array(idx) );
  END LOOP;
END;
/