为啥我在尝试调用过程时得到 ORA-06531: reference to uninitialized collection?

Posted

技术标签:

【中文标题】为啥我在尝试调用过程时得到 ORA-06531: reference to uninitialized collection?【英文标题】:Why do I get ORA-06531: reference to uninitialized collection while trying to call procedure?为什么我在尝试调用过程时得到 ORA-06531: reference to uninitialized collection? 【发布时间】:2020-09-14 12:36:59 【问题描述】:

我正在尝试调用过程 my_package.procedure_test,如下所示:

declare
   v_counter BINARY_INTEGER := 1;
   a  tbl_familles;
   v_mytable tbl_familles;
begin
  
  PK_SOA_Famille_Test.get_famille('zz','zz', v_mytable);

  while v_counter <= v_mytable.count
   loop
      Dbms_Output.Put_Line(v_mytable(v_counter).nom);
      v_counter := v_counter + 1;
   end loop;
  
end;

但我得到了例外:

ORA-06531:对未初始化集合的引用

包定义:

CREATE OR REPLACE Package PK_SOA_Famille_Test as

PROCEDURE get_famille
(num_ass IN VARCHAR2, num_indd IN VARCHAR2,
OutTableParam OUT tbl_familles);
end PK_SOA_Famille_Test;

程序主体:

CREATE OR REPLACE PACKAGE BODY PK_SOA_Famille_Test AS
  PROCEDURE get_famille
  (num_ass IN VARCHAR2, num_indd IN VARCHAR2, OutTableParam OUT tbl_familles) IS
      v_counter number := 0;      
            
      Cursor C_typ_famille
        (
            num_ass varchar2 ,num_indd varchar2
        ) Is
        SELECT  nom, prenom, num_imm ,num_ind ,nat_int ,dat_naiss, num_cin, der_stat, der_sit, datsit, indpere, indmere
           from typ_famille
           where (num_imm = num_ass AND num_ind = num_indd) ;
        C2 C_typ_famille%ROWTYPE;
      
  BEGIN

  IF   num_indd is null then 
  
     for EmpCursor in
         (select nom,prenom,num_imm ,num_ind, nat_int, dat_naiss, num_cin, der_stat, der_sit, datsit, indpere, indmere
           from typ_famille
           where num_imm = num_ass)
           
     loop
       v_counter := v_counter + 1;
       OutTableParam(v_counter).nom := EmpCursor.nom;
       OutTableParam(v_counter).prenom := EmpCursor.prenom;
       OutTableParam(v_counter).num_imm := EmpCursor.num_imm;
       OutTableParam(v_counter).num_ind := EmpCursor.num_ind;
       OutTableParam(v_counter).nat_int  := EmpCursor.nat_int ;
       OutTableParam(v_counter).dat_naiss := EmpCursor.dat_naiss;
       OutTableParam(v_counter).num_cin := EmpCursor.num_cin;
       OutTableParam(v_counter).der_stat := EmpCursor.der_stat;
       OutTableParam(v_counter).der_sit := EmpCursor.der_sit;
       OutTableParam(v_counter).datsit := EmpCursor.datsit;
       OutTableParam(v_counter).indpere := EmpCursor.indpere;
       OutTableParam(v_counter).indmere := EmpCursor.indmere;
    end loop; 
        
END IF ;
  END get_famille;
END PK_SOA_Famille_Test;
/

我还创建了类型 rec_famille 作为对象和 tbl_familles 作为模式级别的 rec_famille 表。

【问题讨论】:

你试过初始化变量v_mytable吗?声明变量时尝试像这样初始化它v_mytable tbl_familles := tbl_familles(); 【参考方案1】:

num_inddNOT NULLPK_SOA_Famille_Test.get_famille 实际上什么都不做。这使OutTableParam 未初始化。正如 EJ Egyed 建议的那样,您可以在 IF 语句中使用 OutTableParam := tbl_familles(); 包含 ELSE。

此外,循环游标来填充集合是一种浪费:您应该改用BULK COLLECT。

CREATE OR REPLACE PACKAGE BODY pk_soa_famille_test IS
  PROCEDURE get_famille(num_ass       IN VARCHAR2,
                        num_indd      IN VARCHAR2,
                        outtableparam OUT) IS
  
  BEGIN
  
    IF num_indd IS NULL THEN
      SELECT nom,
             prenom,
             num_imm,
             num_ind,
             nat_int,
             dat_naiss,
             num_cin,
             der_stat,
             der_sit,
             datsit,
             indpere,
             indmere
        BULK COLLECT
        INTO outtableparam
        FROM typ_famille
       WHERE num_imm = num_ass;
    ELSE
      outtableparam := tbl_familles;
    END IF;
  END get_famille;
END pk_soa_famille_test;

【讨论】:

以上是关于为啥我在尝试调用过程时得到 ORA-06531: reference to uninitialized collection?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 升级后的 ORA-06531

ORA-06531: 引用未初始化的收集 的问题解决

为啥我在尝试保存时得到黑色矩形而不是我的位图

为啥我在尝试创建新的 qml 文件时得到 QmlCachedGenerateCode?

为啥我在尝试调用 CDHtmlDialog::OnInitDialog() 时看到崩溃

为啥我在使用 CustomListAdapter 时得到不同大小的列表行,即使我尝试为自定义列表行提供特定值