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

Posted

技术标签:

【中文标题】获取对关联数组的未初始化集合的错误引用【英文标题】:Getting the error Reference to uninitialized collection to associative arrays 【发布时间】:2017-10-04 14:44:03 【问题描述】:

我在我正在创建的包中使用关联数组,我收到错误 ORA-06531: Reference to uninitialized collection if I try to get the count (TBL.COUNT) before I have bulk collect into the array.

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

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

我的想法是,与嵌套表和可变数组不同,您不需要初始化关联数组

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

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

用作以下过程的输入

    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: 引用未初始化的集合

【问题讨论】:

你确定你使用的是关联数组吗?请分享代码。编辑:如果您的集合将被密集填充,您为什么要使用(或尝试使用)关联数组? Reference to uninitialized collection PL/SQL的可能重复 上面列出的帖子是针对嵌套表的。这篇文章是关于关联数组的 如果有人好奇,我解决了这个问题。在定义类型时,我忘记了:INDEX BY PLS_INTEGER @programmerNOOB When defining the TYPE, I forgot the: INDEX BY PLS_INTEGER 那么您的集合不再作为关联数组存在。它已转换为嵌套表,这就是为您发布上述链接的原因。像Reference to uninitialized collection PL/SQL 这样的错误也只发生在嵌套表中,因为在关联数组中我们不需要初始化任何东西。所以实际上这是一个指针,`Goran Stefanović` 指出的非常好, 【参考方案1】:

关联数组没有递增索引。您不需要初始化关联数组,使用 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;
/

【讨论】:

这也是我的想法,所以我只是想知道我是如何得到这个的。我已经在规范级别定义了 AA,并将它们传递给包内的 procs。这可能与它有关吗?我会尝试在原帖中添加更多内容

以上是关于获取对关联数组的未初始化集合的错误引用的主要内容,如果未能解决你的问题,请参考以下文章

对静态 constexpr 数据成员的未定义引用错误

Java并发AtomicReferenceArray类

在 PHP 中将多维关联数组展平为一维引用数组

Laravel 5.1 从原始数据库(或只是一个数组)创建集合或关联数组

Java基础学习:集合篇

将带有引用的关联数组作为值保存在教义-mongodb中