Oracleでsys_refcursorをいつどのように使用するか


回答:


10

カーソルは、クエリの結果セットへのポインタです。を返すsys_refcursorことにより、クライアントは必要に応じてクエリから行をいくつでもフェッチすることもできます。ステートフルアプリケーションでは、これを使用して結果をページングできます。

カーソルは、フェッチする行数と停止するタイミングをクライアントに完全に委ねるため、配列を返すPL / SQL関数を作成するよりも柔軟性があります。そうは言っても、この追加の柔軟性が役立つケースはあまり見当たりません。

sys_refcursorは型が弱いため、from句やwhere句だけでなく、列の数や型も異なるクエリへのポインタを返すことができることに注意してください。または、結果セットの列が固定されている厳密に型指定されたカーソルを使用できます。

これにより、次のように、さまざまなクエリを返す関数を作成できます。

create function get_data ( type varchar2 ) return sys_refcursor as
  ret_cur sys_refcursor;
begin

  if type = 'EMP' then
    open ret_cur for select * from emp;
  elsif type = 'DEPT' then
    open ret_cur for select * from dept;
  end if;

  return ret_cur;
end;

ただし、sys_refcursor上記のような一般的な「クエリを開く」関数を作成するために使用している場合は、おそらく何か間違っているでしょう!


@Chris ...サンプル関数が「間違っている」のはなぜですか?
ジョニー・ウー

2
@JohnnyWu「何でも取得」機能は管理が難しくなります。すべてのケースで正しい結果が得られることを確認するために、どのようにテストしますか?セキュリティはどうですか?フレームワークを構築している場合、これが必要になる場合があります。ただし、一般的なビジネスロジックの場合はget_empsget_depts機能を分離しておく方がよい
Chris Saxon

1

可能性の例としては、後ろにpl / sqlがあるため、行を表すオブジェクトを定義し、それらのオブジェクトのpl / sqlテーブルを定義できます。

create type T_MY_TABLE as table of t_my_object;

で終わる

OPEN p_recordset FOR select * from table( v_my_table );

したがって、データベーステーブルでmongoを構築するのではなく、多くの場合、密集した、および/または不可解な直接クエリを作成するのではなく、内部テーブルを作成して、pl / sqlの全能力でデータを設定できます。そして、結果セットを収集するクライアントは賢明ではありません。また、内部テーブルの定義を変更する方が、データベーステーブルを変更するよりも、管理視点から簡単です。

また、Jasperなどのレポートジェネレーターを使用する場合は、SQLをレポートからデータベースにプッシュし、プロシージャを呼び出してレコードセットを取得し、レポート側をフォーマットに集中させることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.