PLS-00382:在循环调用的存储过程上打开 REF CURSOR 时“表达式类型错误”

问题描述 投票:0回答:1

我有一个外部存储过程,它在循环中调用内部存储过程。内部存储过程返回一个由 2 部分组成的

REF CURSOR
,(1)
V_SUCCESSFUL_COUNT
(2)
V_RESPONSE_CODE
。我的外部存储过程正在将所有内部 SP 调用中的这些对收集到相应的数组中,
V_SUCCESSFUL_COUNTS
V_RESPONSE_CODES
。首先,它打开内部 SP 的游标,将两个部分提取到变量中,然后将这些变量添加到数组中。

PROCEDURE OUTER_SP(PARAM1, .., P_REF_CURSOR REF CURSOR)
AS
    ..
    V_SUCCESSFUL_COUNT      NUMBER;
    V_RESPONSE_CODE         VARCHAR2(10);
    V_SUCCESSFUL_COUNTS     REF_TYPE_NUM_TABLE := REF_TYPE_NUM_TABLE(); /* Cumulative Successful Counts */
    V_RESPONSE_CODES        REF_VARCHAR2_ARRAY_TABLE := REF_VARCHAR2_ARRAY_TABLE(); /* Cumulative Response Codes */
    V_REF_CURSOR            SYS_REFCURSOR; /* Result from each inner SP */

    FOR i IN 1 .. P_REF_ID_LIST.COUNT LOOP
                    SP_INNER(PARAM1,
                             PARAM2,
                             ...
                             V_REF_CURSOR);

        /* Add V_SUCCESSFUL_COUNT, V_RESPONSE_CODE outputs from this call to collections */
        OPEN V_REF_CURSOR /* Error here! */;
        FETCH V_REF_CURSOR INTO V_SUCCESSFUL_COUNT, V_RESPONSE_CODE;
        V_SUCCESSFUL_COUNTS.EXTEND;
        V_SUCCESSFUL_COUNTS(V_SUCCESSFUL_COUNTS.COUNT) := V_SUCCESSFUL_COUNT;
        V_RESPONSE_CODES.EXTEND;
        V_RESPONSE_CODES(V_RESPONSE_CODES.COUNT) := V_RESPONSE_CODE;
        CLOSE V_REF_CURSOR /* Error here! */;
    END LOOP;

当我尝试从每个内部 SP 调用检索结果时,我在

OPEN V_REF_CURSOR
/
CLOSE V_REF_CURSOR
行上收到此错误:

PLS-00382:表达式类型错误

它不喜欢我在调用

FETCH V_REF_CURSOR
之前打开内部SP的光标。

如果我删除这些

OPEN V_REF_CURSOR
/
CLOSE V_REF_CURSOR
行并直接转到
FETCH V_REF_CURSOR
,则没有语法错误并且 SP 可以编译,但添加到数组中的结果不正确(
NULL
),因为我当我运行这个外部 SP 时可以看到。

oracle
1个回答
0
投票

我怀疑是

SP_INNER
没有返回任何东西。

这是一个演示,展示了如何做到这一点(如果一切顺利)。

这是一个返回一些数据的查询;它用于

SP_INNER

SQL> select ename, sal from emp where deptno = 10;

ENAME             SAL
---------- ----------
CLARK            2450
KING             5000
MILLER           1300

我的

SP_INNER
程序真的很简单;这里唯一“重要”的事情是用于引用游标的查询确实返回一些东西:

SQL> create or replace procedure sp_inner(par_rc out sys_refcursor)
  2  is
  3  begin
  4    open par_rc for
  5      select ename, sal from emp where deptno = 10;
  6  end;
  7  /

Procedure created.

SQL> set serveroutput on;

模拟您的匿名 PL/SQL 块

OUTER_SP
:

SQL> declare
  2    l_rc    sys_refcursor;
  3    l_ename emp.ename%type;
  4    l_sal   emp.sal%type;
  5  begin
  6    sp_inner(l_rc);
  7    loop
  8      fetch l_rc into l_ename, l_sal;
  9      exit when l_rc%notfound;
 10      dbms_output.put_line(l_ename||' - '||l_sal);
 11    end loop;
 12  end;
 13  /
CLARK - 2450
KING - 5000
MILLER - 1300

PL/SQL procedure successfully completed.

SQL>

如您所见,输出反映了

select
语句本身返回的内容,因此 - 它有效

由于您没有得到任何信息,请检查

SP_INNER
正在做什么。

© www.soinside.com 2019 - 2024. All rights reserved.