0

オフィスで Oracle 9i サーバーを実行しています。私は、sys_refcursor を out パラメータとして別のパッケージに (他の in パラメータとともに) 渡す手順に取り組んでいます。呼び出されたプロシージャがカーソルに返すさまざまな列のレコードとして型を定義できました。次に、次のようなコードでループできます。

LOOP
   fetch o_results into v_rec;
   exit when o_results%notfound;
   dbms_output.put_line(v_rec.some_id);
end loop;

行タイプ全体を宣言する必要がなく、1 つの列のみをプルする方法はありますか? 私は次のようなものを試しました:

LOOP
  fetch o_results.some_id into v_id;
  exit when o_results%notfound;
  dbms_output.put_line(v_id);
end loop;

しかし、それはうまくいきませんでした。他のアイデアはありますか?

4

1 に答える 1

1

いいえ、カーソルが複数の列を含む結果セットを返す場合、単一の列をレコード以外のローカル変数にフェッチすることはできません。ただし、いくつかの選択肢があります。

弱く型付けされたカーソルではなく、強く型付けされたカーソルを宣言する場合は、新しいコレクションを宣言するのではなく、そのカーソル定義に基づいてローカル変数を宣言できます。

create or replace procedure cursor_proc
as
  cursor emp_cur
      is
   select empno, ename
     from emp;
  l_row emp_cur%rowtype;
begin
  open emp_cur;
  loop
    fetch emp_cur into l_row;
    exit when emp_cur%notfound;
    dbms_output.put_line( l_row.ename );
  end loop;
  close emp_cur;
end;

または、弱く型付けされた ref カーソルが特定のオブジェクトのすべての列を常に返すことがわかっている場合は、ローカル変数宣言をそのオブジェクトに固定できます。カーソルが選択するビューを宣言することで、いつでもこれを機能させることができます。例えば

create or replace view vw_emp
as
select ename, empno
  from emp

create or replace procedure cursor_proc2
as
  emp_cur sys_refcursor;
  l_row   vw_emp%rowtype;
begin
  open emp_cur for select * from vw_emp;
  loop
    fetch emp_cur into l_row;
    exit when emp_cur%notfound;
    dbms_output.put_line( l_row.ename );
  end loop;
  close emp_cur;
end;

最後に、暗黙カーソルを使用すると、Oracle はコレクション型を暗黙的に宣言します。

create or replace procedure cursor_proc3
as
begin
  for emp in (select ename, empno from emp)
  loop
    dbms_output.put_line( emp.ename );
  end loop;
end;
于 2011-05-18T03:28:33.110 に答える