web-dev-qa-db-ja.com

PL SQL ForループSys_RefCursor

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で実行できますか?私はフェッチ/ 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

(fetch into/whileループではなく)sys_refcursorを介してforループするメカニズムはありますか?たぶん、私が知らない12cの新しいもの…?

6
0909EM

SYS_REFCURSORは、事前に宣言された弱い参照カーソルです。フェッチせずにsys_refcursorをループするメカニズムはありません。また、弱いrefcursorを通常のカーソルと比較することはできず、動作が異なります。結果を一時的に保持するために割り当てられるバッファスペースです。 PLSQLブロックで以下のステートメントを実行すると、PLSQLエンジンはPLSQL変数を理解せず、エラーをスローします

curループのx

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

SYS_REFCURSORを返す場合、パッケージにOUTパラメータを定義しなかったため、以下のステートメントも失敗します。

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;
6
XING