PL SQL For Loop Sys_RefCursor

时间:2017-03-09 14:41:06

标签: 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;

我也可以这样做......

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;

到目前为止,这么好。但我可以用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;

我想做...

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

是否存在循环通过sys_refcursor的机制(而不是fetch into / while循环)?也许在12c中我不知道的新东西......?

1 个答案:

答案 0 :(得分:4)

SYS_REFCURSOR仅仅是一个预先声明的弱引用游标。没有这样的机制来循环sys_refcursor而不提取。此外,您无法将弱refcursor与普通光标进行比较,它们的工作方式也不同。它是一个缓冲空间,用于临时保存结果。当您在PLSQL块中运行以下语句时,PLSQL引擎无法将其理解为PLSQL变量并抛出错误

  

用于cur循环中的x

PLS-00221: 'CUR' is not a procedure or is undefined

除了重新引用OUT之外,下面的语句也会失败,因为你没有为包定义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;