PL SQL For循环Sys_RefCursor

090*_*9EM 5 plsql oracle12c

我正在使用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的新事物...?

XIN*_*ING 5

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)

  • 弱引用游标和普通游标的工作方式可能不同,但我认为 Oracle 会提供一些语法糖,允许我将一个游标视为另一个游标,以便在 for 循环中使用。也就是说,如果做不到,那就是答案。 (2认同)