Oracle 对未初始化的集合PL/SQL的引用

Oracle 对未初始化的集合PL/SQL的引用,oracle,stored-procedures,plsql,Oracle,Stored Procedures,Plsql,当我运行包含以下详细信息的存储过程时,我收到了对未初始化集合的引用ORA-06531: 用户定义的数据类型: CREATE OR REPLACE TYPE T IS TABLE OF VARCHAR2; 存储过程定义: CREATE OR REPLACE PROCEDURE TEST ( u IN T, v OUT T) IS BEGIN FOR i IN u.FIRST..u.LAST LOOP v(i) := u(i); END LOOP; END; 我使用以下方法调用该

当我运行包含以下详细信息的存储过程时,我收到了对未初始化集合的引用
ORA-06531:

用户定义的数据类型:

CREATE OR REPLACE TYPE T IS TABLE OF VARCHAR2;
存储过程定义:

CREATE OR REPLACE PROCEDURE TEST ( u IN T, v OUT T)
IS
BEGIN
  FOR i IN u.FIRST..u.LAST LOOP
    v(i) := u(i);
  END LOOP;
END;
我使用以下方法调用该过程:

DECLARE
  v_t T;
  u_t T;
BEGIN
  v_t := T();
  v_t.EXTEND(2);

  v_t(1) := "This is test1";
  v_t(2) := "This is test2";
  TEST(v_t, u_t);
END;

今天我有一个类似的问题,你必须初始化你的u_t变量,检查答案以获得更多信息,在你的测试过程中,你将
v
声明为一个OUT参数-这意味着过程需要初始化过程中的输出集合(例如
v:=t();
)。即使将调用块更改为initialize
u\u t
,这也不会有帮助,因为
u\u t
集合不会传入过程-它只接收过程传递回的内容

按如下方式更改代码:

CREATE OR REPLACE PROCEDURE TEST ( u IN T, v OUT T) IS
  i NUMBER := u.FIRST;
BEGIN
  v := T();
  v.EXTEND(u.COUNT);

  IF i IS NOT NULL THEN
    LOOP
      v(i) := u(i);
      i := u.NEXT(i);
      EXIT WHEN i IS NULL;
    END LOOP;
  END IF;
END TEST;

DECLARE
  v_t T;
  u_t T;
BEGIN
  v_t := T();
  v_t.EXTEND(2);

  v_t(1) := 'This is test1';
  v_t(2) := 'This is test2';

  TEST(v_t, u_t);

  FOR i IN u_t.FIRST..u_t.LAST LOOP
    DBMS_OUTPUT.PUT_LINE(u_t(i));
  END LOOP;
END;
请注意,PL/SQL中的字符串常量必须用单引号括起来,而不是用双引号括起来

此外,在过程和调用块中使用具有相反含义的类似变量名只会增加混淆。养成使用有意义的名字的习惯,以后你会避免很多困惑


共享和享受。

u\u t
不是未初始化的…如果此测试的全部目的是简单地复制
u
集合,那么
v
集合可以简单地分配给
u
集合,即使没有
u
也可以先初始化。无需使用
for
循环来执行逐元素复制。此外,如果
v
集合恰好是稀疏的,则会引发
no\u data\u found
异常。我还试图用JDBC程序执行这个过程。我没有将它打印到dbms_输出,而是简单地将它赋给out参数并从out参数中提取输出。工作起来很有魅力!非常感谢你@NicholasKrasnov-关于“使用分配而不是FOR循环”,你是对的。然而,在本例中,OP似乎可以使用如何手动执行集合管理的演示,因此我认为最好是“修复”FOR循环实现。我使用
FIRST
NEXT
收集方法重写了测试过程来处理稀疏情况。谢谢@bob jarvis恢复monica我认为值得一提的是,如果在过程内部声明type
T
,如果在调用代码中再次声明type
T
,我们将得到
PLS-00306
。我遵循了这个准则,偶然发现了这个。