REF CURSORは、Oracle PL/SQL言語でのデータ型です。Oracleデータベース内のカーソルまたは結果セットを表します。OracleRefCursorオブジェクトは、REF CURSOR型に対応するODP.NETタイプです。
この項では、REF CURSORデータ型およびOracleRefCursorオブジェクトを使用する際の次の点について説明します。
OracleRefCursorオブジェクトにはコンストラクタがありません。PL/SQLストアド・プロシージャ、ストアド・ファンクションまたは無名ブロックからパラメータ値として取得できるのみです。
OracleRefCursorオブジェクトは接続されたオブジェクトです。OracleRefCursorオブジェクトを戻すコマンドの実行に使用される接続が、コマンドの存続期間にわたり必要になります。OracleRefCursorオブジェクトに関連付けられている接続がクローズされると、OracleRefCursorオブジェクトは使用できなくなります。
REF CURSORデータ型は、OracleDataReader、DataSetまたはOracleRefCursorオブジェクトとして取得できます。REF CURSORデータ型をOracleRefCursorオブジェクトとして取得する場合は、OracleDataReaderオブジェクトの作成またはDataSetへの移入に使用できます。REF CURSORデータ型にアクセスするときは、常にOracleDbType.RefCursorパラメータとしてバインドする必要があります。
A REFCURSORデータ型は、OracleCommandオブジェクトのExecuteReaderメソッドを呼び出すことでOracleDataReaderとして取得できます。OracleDbTypeプロパティが設定された出力パラメータは、OracleDbType.RefCursorにバインドされます。タイプOracleDbType.RefCursorの出力パラメータは、ExecuteReaderメソッドが起動された後は移入されません。
複数の出力REF CURSORパラメータがある場合、次のREF CURSORデータ型にアクセスするにはOracleDataReaderオブジェクトのNextResultメソッドを使用します。OracleDataReaderのNextResultメソッドは、REF CURSORに対して順次アクセスを提供します。一時点でアクセスできるREF CURSORデータ型は1つのみです。
対応するREF CURSORデータ型に対してOracleDataReaderオブジェクトが作成される順序は、パラメータがバインドされている順序に依存します。PL/SQLストアド・プロシージャがREF CURSORデータ型を戻した場合は、これが最初のOracleDataReaderオブジェクトになり、出力されるすべてのREF CURSORデータ型はパラメータがバインドされている順序に従います。
FillメソッドによりDataSetに正しく移入するには、OracleDataAdapterのSelectCommandプロパティをタイプOracleDbType.RefCursorの出力パラメータにバインドする必要があります。Fillメソッドが正常に実行されると、REF CURSORデータ型を表すDataTableがDataSetに移入されます。
コマンドの実行で複数のREF CURSORデータ型が戻されると、DataSetには複数のDataTableオブジェクトが移入されます。
Oracle Data Provider for .NETリリース11.1.0.6.20では、DataTableに移入されるREF CURSORを識別するため、拡張プロパティのREFCursorNameがDataTableに導入されています。
このプロパティは、DataSetに複数のREF CURSOR(その中の1つ以上がNULL)が移入されている場合に特に便利です。たとえば、3つのREF CURSORを戻すストアド・プロシージャを実行してDataSetが移入され、2番目のREF CURSORがNULLである場合、1番目のDataTableに対するREFCursorNameプロパティ値はREFCursorで、2番目のDataTableに対する値はREFCursor2です。NULL REF CURSORに対してDataTableは移入されません。
1つ以上のREF CURSORデータ型を戻すコマンドに対してExecuteNonQueryが起動されると、OracleDbType.RefCursorとしてバインドされている各OracleCommandパラメータはOracleRefCursorオブジェクトへの参照を取得します。
OracleRefCursorオブジェクトからOracleDataReaderオブジェクトを作成するには、OracleRefCursorオブジェクトからGetDataReaderメソッドを起動します。後続のGetDataReaderメソッドへのコールでは、同一のOracleDataReaderオブジェクトへの参照が戻されます。
DataSetにOracleRefCursorオブジェクトを移入するには、OracleRefCursorオブジェクトを取るOracleDataAdapterクラスのFillメソッドをアプリケーションで起動できます。OracleDataReaderオブジェクトと同じく、OracleRefCursorオブジェクトも順方向専用です。したがって、OracleRefCursorオブジェクトから行が読み取られると、問合せから再度移入されないかぎり、同じ行は取得できません。
コマンドの実行で複数のREF CURSORデータ型がOracleRefCursorオブジェクトとして戻される場合、アプリケーションではOracleDataReaderオブジェクトを作成するか、特定のOracleRefCursorオブジェクトをDataSetに移入するかを選択できます。OracleRefCursorオブジェクトから作成されるOracleDataReaderオブジェクトまたはDataSetオブジェクトはすべて同時にアクティブになり、任意の順序でアクセスできます。
REF CURSOR型は更新不可能です。ただし、DataSetから取り出したデータは更新できます。このため、OracleDataAdapterクラスには、REF CURSORデータの更新をすべてデータベースにフラッシュするカスタムSQL文が必要になります。
REF CURSORの更新のためのSQLの生成にOracleCommandBuilderオブジェクトを使用することはできません。
次のいずれかの場合、ExecuteScalarメソッドは、REF CURSORの最初の行の最初の列の値を戻します。
ストアド・ファンクション実行の戻り値
ストアド・プロシージャ実行の最初のバインド・パラメータ
|
関連項目: 詳細は、Oracle Databaseアプリケーション開発者ガイド-ラージ・オブジェクトを参照 |
アプリケーションは、PL/SQLのストアド・プロシージャまたはファンクションからREF CURSORタイプを取り出して、別のストアド・プロシージャまたはファンクションに渡すことができます。この機能は、ストアド・プロシージャまたはファンクションが.NETアプリケーションにREF CURSORタイプを戻し、アプリケーションがそのロジックに応じて別のストアド・プロシージャまたは処理にこのREF CURSORを渡す場合に便利です。.NETアプリケーション内のREF CURSORタイプからデータを取り出す場合、そのデータを別のストアド・プロシージャに戻すことはできないので注意してください。
次の例では、REF CURSORの引渡しを示しています。
/*
connect scott/tiger@oracle
create table test (col1 number);
insert into test(col1) values (1);
commit;
create or replace package testPkg as type empCur is REF Cursor;
end testPkg;
/
create or replace procedure testSP(param1 IN testPkg.empCur, param2 OUT NUMBER)
as
begin
FETCH param1 into param2;
end;
/
*/
// C#
using System;
using Oracle.DataAccess.Client;
using System.Data;
class InRefCursorParameterSample
{
static void Main()
{
OracleConnection conn = new OracleConnection
("User Id=scott; Password=tiger; Data Source=oracle");
conn.Open(); // Open the connection to the database
// Command text for getting the REF Cursor as OUT parameter
String cmdTxt1 = "begin open :1 for select col1 from test; end;";
// Command text to pass the REF Cursor as IN parameter
String cmdTxt2 = "begin testSP (:1, :2); end;";
// Create the command object for executing cmdTxt1 and cmdTxt2
OracleCommand cmd = new OracleCommand(cmdTxt1, conn);
// Bind the Ref cursor to the PL/SQL stored procedure
OracleParameter outRefPrm = cmd.Parameters.Add("outRefPrm",
OracleDbType.RefCursor, DBNull.Value, ParameterDirection.Output);
cmd.ExecuteNonQuery(); // Execute the anonymous PL/SQL block
// Reset the command object to execute another anonymous PL/SQL block
cmd.Parameters.Clear();
cmd.CommandText = cmdTxt2;
// REF Cursor obtained from previous execution is passed to this
// procedure as IN parameter
OracleParameter inRefPrm = cmd.Parameters.Add("inRefPrm",
OracleDbType.RefCursor, outRefPrm.Value, ParameterDirection.Input);
// Bind another Number parameter to get the REF Cursor column value
OracleParameter outNumPrm = cmd.Parameters.Add("outNumPrm",
OracleDbType.Int32, DBNull.Value, ParameterDirection.Output);
cmd.ExecuteNonQuery(); //Execute the stored procedure
// Display the out parameter value
Console.WriteLine("out parameter is: " + outNumPrm.Value.ToString());
}
}