在您从手册中引用的文本中,请注意它是专门讨论“从光标变量获取的子程序”。你的例子都没有这样做,因此引用与它们无关。
但是,如果子程序打开并从游标变量中取出,那么在这种情况下使用OUT似乎没有任何问题:
SQL> variable c refcursor
SQL> set serveroutput on
SQL> create or replace procedure no_good (c OUT sys_refcursor)
2 as
3 my_dummy dual.dummy%type;
4 begin
5 open c for select dummy from dual union all select dummy from dual;
6 fetch c into my_dummy;
7 dbms_output.put_line( my_dummy );
8 end;
9 /
Procedure created.
SQL> exec no_good( :c )
X
PL/SQL procedure successfully completed.
SQL> print c
D
-
X
我认为该文本实际上试图使两个点彼此独立。首先,如果要将任何已打开的游标变量传递到子程序中,该子程序将从中获取,则该参数必须声明为IN或IN OUT。其次,如果要将游标变量传递给子程序,然后将其打开,则必须将参数声明为OUT或IN OUT。无论您是否真的关心将游标变量的值传递回调用者,都是如此:
SQL> create or replace procedure no_good (c IN sys_refcursor)
2 as
3 my_dummy dual.dummy%type;
4 begin
5 open c for select dummy from dual;
6 fetch c into my_dummy;
7 dbms_output.put_line( my_dummy );
8 close c;
9 end;
10 /
Warning: Procedure created with compilation errors.
SQL> show error
Errors for PROCEDURE NO_GOOD:
LINE/COL ERROR
-------- -----------------------------------------------------------------
5/6 PL/SQL: SQL Statement ignored
5/11 PLS-00361: IN cursor 'C' cannot be OPEN'ed
可以通过更改参数模式来修复此错误,但实际上简单地将游标变量设置为局部变量而不是参数似乎更有意义。