我正在使用Oracle 12c。在PL / SQL中,我可以执行此操作
set serveroutput on
declare
begin
for x in (select 1 as y from dual) loop
dbms_output.put_line(x.y);
end loop;
end;
Run Code Online (Sandbox Code Playgroud)
我也可以做...
set serveroutput on
declare
cursor c1 is
select 1 as y from dual;
begin
for x in c1 loop
dbms_output.put_line(x.y);
end loop;
end;
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很好。但是我可以使用sys_refcursor来做到这一点吗?我知道我可以使用fetch / while循环来做到这一点,但更喜欢for循环语法(我认为这样更干净)...
set serveroutput on
declare
cur sys_refcursor;
begin
cur := Package.GetData(1234);
fetch cur into y;
while cur%FOUND loop
dbms_output.put_line(y);
fetch cur into y;
end loop;
end;
Run Code Online (Sandbox Code Playgroud)
我想要做...
set serveroutput on
declare
cur sys_refcursor;
begin
cur := PACKAGE.GetData(1234); -- This returns a sys_refcursor
for x in cur loop
dbms_output.put_line(x.y);
end loop;
end;
Error report -
ORA-06550: line 5, column 16:
PLS-00221: 'cur' is not a procedure or is undefined
Run Code Online (Sandbox Code Playgroud)
是否存在用于通过sys_refcursor进行循环的机制(而不是获取/ while循环)?也许我不知道的关于12c的新事物...?
SYS_REFCURSOR只是一个预先声明的弱引用游标。没有这种机制可以sys_refcursor不进行获取就进行循环。同样,您也无法将弱反射器与普通光标进行比较,它们的工作方式有所不同。这是一个缓冲区空间,用于临时保存结果。当您在PLSQL块中运行以下语句时,PLSQL引擎无法PLSQL将其理解为变量,并引发错误
对于x in cur loop
PLS-00221: 'CUR' is not a procedure or is undefined
Run Code Online (Sandbox Code Playgroud)
此外,下面的语句也将失败,因为如果您OUT引用Package时未为其定义参数,则它不会SYS_REFCURSOR。
cur:= PACKAGE.GetData(1234);
您可以获取的内容,SYS_REFCURSOR然后显示如下:
declare
a SYS_REFCURSOR;
v_emp_id employee.emp_id%type;
begin
--- This is a procedure with OUT parameter as SYS_REFCURSOR
dynmc_selec(emp_output=>a);
loop
FETCH a INTO v_emp_id;
EXIT WHEN a%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_emp_id );
end loop;
end;
Run Code Online (Sandbox Code Playgroud)