Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将此过程正确转换为PLSQL块?对未初始化函数的引用_Sql_Oracle_Plsql - Fatal编程技术网

如何将此过程正确转换为PLSQL块?对未初始化函数的引用

如何将此过程正确转换为PLSQL块?对未初始化函数的引用,sql,oracle,plsql,Sql,Oracle,Plsql,下面的块编译正确。(编辑了不重要的部分) 但是,当我尝试将其转换为plsql块时 DECLARE TYPE test_h IS TABLE OF VARCHAR2(100) INDEX BY VARCHAR2(100); test_h_list test_h; --ORA-06531: Reference to uninitialized collection :-( TYPE l_ids IS TABLE OF VARCHAR(100); l_id_list l_ids; BEGIN

下面的块编译正确。(编辑了不重要的部分)

但是,当我尝试将其转换为plsql块时

DECLARE
TYPE test_h IS TABLE OF VARCHAR2(100) INDEX BY VARCHAR2(100); 
test_h_list test_h; --ORA-06531: Reference to uninitialized collection  :-(
TYPE l_ids IS TABLE OF VARCHAR(100);
l_id_list l_ids;

BEGIN 
  test_h_list('A'):='Apple'; 
  test:=test_h_list.FIRST;
  WHILE test IS NOT NULL LOOP
    BEGIN
    SELECT  tbl1.l_id BULK COLLECT INTO l_id_list
    WHERE ....
    ....
    ....
  END;
我得到了上面注释的“ORA-06531:Reference to uninitialized collection”错误。我试着四处搜索,发现并基于这些例子

我想到了这个

DECLARE
TYPE test_h IS TABLE OF VARCHAR2(100) INDEX BY VARCHAR2(100); 
test_h_list test_h := test_h();
TYPE l_ids IS TABLE OF VARCHAR(100);
l_id_list l_ids :=l_ids();


BEGIN 
  test_h_list.EXTEND(100);
  l_ids.EXTEND(100);
  test_h_list('A'):='Apple'; 
  test:=test_h_list.FIRST;
  WHILE test IS NOT NULL LOOP
    BEGIN
    SELECT  tbl1.l_id BULK COLLECT INTO l_id_list
    WHERE ....
    ....
    ....
  END;
但这会引发一个错误,即PLS-00222:此范围中不存在名为“test_h”的函数。你知道我遗漏了什么吗

MCVE

剧本-

DECLARE
TYPE test_h IS TABLE OF VARCHAR2(100) INDEX BY VARCHAR2(100);
test_h_list test_h := test_h(); --Line 3
TYPE l_ids IS TABLE OF VARCHAR(100);
l_id_list l_ids := l_ids();
test_str VARCHAR(50);

BEGIN 
  test_h_list.EXTEND(100);
  l_id_list.EXTEND(100);
  test_h_list('App'):='1'; 
  test_h_list('Red'):='2'; 
  test_str:=test_h_list.FIRST;
  WHILE test_str IS NOT NULL LOOP
    BEGIN
    SELECT  TABLE1.DEPT  BULK COLLECT INTO l_id_list
    FROM    TABLE1
    WHERE   TABLE1.NAME = test_str;

    FOR indx IN 1..l_id_list.COUNT
      LOOP

                         DBMS_OUTPUT.PUT_LINE( l_id_list(indx));


      END LOOP;
    test_str:=test_h_list.NEXT(test_str);
    EXCEPTION
    WHEN OTHERS THEN -- Just print  the failure to logs
           NULL;

    END;
  END LOOP;
END; 
/
错误报告-

Error starting at line 1 in command:
DECLARE
TYPE test_h IS TABLE OF VARCHAR2(100) INDEX BY VARCHAR2(100);
test_h_list test_h := test_h();
TYPE l_ids IS TABLE OF VARCHAR(100);
l_id_list l_ids := l_ids();
test_str VARCHAR(50);

BEGIN 
  test_h_list.EXTEND(100);
  l_id_list.EXTEND(100);
  test_h_list('App'):='1'; 
  test_h_list('Red'):='2'; 
  test_str:=test_h_list.FIRST;
  WHILE test_str IS NOT NULL LOOP
    BEGIN
    SELECT  TABLE1.DEPT  BULK COLLECT INTO l_id_list
    FROM    TABLE1
    WHERE   TABLE1.NAME = test_str;

    FOR indx IN 1..l_id_list.COUNT
      LOOP

                         DBMS_OUTPUT.PUT_LINE( l_id_list(indx));


      END LOOP;
    test_str:=test_h_list.NEXT(test_str);
    EXCEPTION
    WHEN OTHERS THEN 
           NULL;

    END;
  END LOOP;
END; 
Error report:
ORA-06550: line 3, column 23:
PLS-00222: no function with name 'TEST_H' exists in this scope
ORA-06550: line 3, column 13:
PL/SQL: Item ignored
ORA-06550: line 9, column 3:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 9, column 3:
PL/SQL: Statement ignored
ORA-06550: line 11, column 3:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 11, column 3:
PL/SQL: Statement ignored
ORA-06550: line 12, column 3:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 12, column 3:
PL/SQL: Statement ignored
ORA-06550: line 13, column 13:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 13, column 3:
PL/SQL: Statement ignored
ORA-06550: line 27, column 15:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 27, column 5:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:
Elapsed: 00:00:00.011

在MCVE中,您混合了不同类型的PL/SQL表。您的
test\u h
类型已编制索引,因此不需要初始化,也无法扩展,因为它是稀疏表类型。因此,删除
:=test_h()
extend
行可以实现以下功能:

DECLARE
TYPE test_h IS TABLE OF VARCHAR2(100) INDEX BY VARCHAR2(100);
test_h_list test_h; -- do no instantiate := test_h(); --Line 3
TYPE l_ids IS TABLE OF VARCHAR(100);
l_id_list l_ids := l_ids();
test_str VARCHAR(50);

BEGIN 
  -- test_h_list.EXTEND(100); -- do not extend either
  l_id_list.EXTEND(100);
  test_h_list('App'):='1'; 
  test_h_list('Red'):='2'; 
  test_str:=test_h_list.FIRST;
  WHILE test_str IS NOT NULL LOOP
    BEGIN
    SELECT  TABLE1.DEPT  BULK COLLECT INTO l_id_list
    FROM    TABLE1
    WHERE   TABLE1.NAME = test_str;

    FOR indx IN 1..l_id_list.COUNT
      LOOP

                         DBMS_OUTPUT.PUT_LINE( l_id_list(indx));


      END LOOP;
    test_str:=test_h_list.NEXT(test_str);
    EXCEPTION
    WHEN OTHERS THEN -- Just print  the failure to logs
           NULL;

    END;
  END LOOP;
END; 
/

PL/SQL procedure successfully completed.
您最初的第一个匿名块没有做这两件事,并且对于
test_h
具有相同的稀疏表类型,因此不应该得到ORA-06531。如果您从类型定义中删除VARCHAR2(100)的
索引,您可能会看到它,但这不是您显示的内容

您还可以通过尝试引用
l_id_list
的元素而不进行初始化来获得它,但正如问题中所述,它总是由循环中的大容量收集隐式初始化,即使查询的实际表是空的,您只会有一个空的PL/SQL表


最初显示的代码不会抛出错误;MCVE正在做一些不同的事情,比第一个更接近您的第二个匿名块。

我没有看到您的第一个匿名块中的错误-声明了
test
并注释掉了循环,以及过程版本。您的过程是成功执行还是只是编译?你能把它转换成一个,并显示错误堆栈来确定哪一行实际抛出了错误吗?第二个匿名块中应出现错误。不管你在第一篇文章中做错了什么,似乎都是在你不幸编辑的代码中。@AlexPoole。。我将上传MCVE,但在此之前我有一个快速的问题-你使用的是什么版本的Oracle?根据问题中的链接,如果小于等于10,我不确定你是否会遇到这个问题。我在11.2.0.4中运行了它。您在哪个版本中看到错误?与
test\u h\u list
相比,从
l\u id\u list
的引用中得到错误的可能性更大,因为后者是索引的,不需要初始化。但您所显示的内容将始终初始化它,即使它是空的。这就是为什么需要一个可复制的例子。除了需要声明“test”这一事实之外,这对我来说是有效的。当你遇到“ORA-06531”错误时,你确定你有“VARCHAR2(100)”索引吗?如果省略了…
索引,我可以看出您发布的代码(或多或少)可能会导致该错误。
DECLARE
TYPE test_h IS TABLE OF VARCHAR2(100) INDEX BY VARCHAR2(100);
test_h_list test_h; -- do no instantiate := test_h(); --Line 3
TYPE l_ids IS TABLE OF VARCHAR(100);
l_id_list l_ids := l_ids();
test_str VARCHAR(50);

BEGIN 
  -- test_h_list.EXTEND(100); -- do not extend either
  l_id_list.EXTEND(100);
  test_h_list('App'):='1'; 
  test_h_list('Red'):='2'; 
  test_str:=test_h_list.FIRST;
  WHILE test_str IS NOT NULL LOOP
    BEGIN
    SELECT  TABLE1.DEPT  BULK COLLECT INTO l_id_list
    FROM    TABLE1
    WHERE   TABLE1.NAME = test_str;

    FOR indx IN 1..l_id_list.COUNT
      LOOP

                         DBMS_OUTPUT.PUT_LINE( l_id_list(indx));


      END LOOP;
    test_str:=test_h_list.NEXT(test_str);
    EXCEPTION
    WHEN OTHERS THEN -- Just print  the failure to logs
           NULL;

    END;
  END LOOP;
END; 
/

PL/SQL procedure successfully completed.