ヘッダーをスキップ
Oracle® Data Provider for .NET開発者ガイド
11g リリース2 (11.2.0.4)
B66456-02
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

PL/SQL REF CURSORおよびOracleRefCursor

REF CURSORは、Oracle PL/SQL言語でのデータ型です。Oracle Database内のカーソルまたは結果セットを表します。OracleRefCursorオブジェクトは、REF CURSOR型に対応するODP.NETタイプです。

この項では、REF CURSORデータ型およびOracleRefCursorオブジェクトを使用する際の次の点について説明します。

OracleRefCursorオブジェクトの取得

OracleRefCursorオブジェクトにはコンストラクタがありません。PL/SQLストアド・プロシージャ、ストアド・ファンクションまたは無名ブロックからパラメータ値として取得できるのみです。

OracleRefCursorオブジェクトは接続されたオブジェクトです。OracleRefCursorオブジェクトを戻すコマンドの実行に使用される接続が、コマンドの存続期間にわたり必要になります。OracleRefCursorオブジェクトに関連付けられている接続がクローズされると、OracleRefCursorオブジェクトは使用できなくなります。

REF CURSORデータ型の取得

REF CURSORデータ型は、OracleDataReaderDataSetまたはOracleRefCursorオブジェクトとして取得できます。REF CURSORデータ型をOracleRefCursorオブジェクトとして取得する場合は、OracleDataReaderオブジェクトの作成またはDataSetへの移入に使用できます。REF CURSORデータ型にアクセスするときは、常にOracleDbType.RefCursorパラメータとしてバインドする必要があります。

REF CURSORからのOracleDataReaderへの移入

REFCURSORデータ型は、OracleCommandオブジェクトのExecuteReaderメソッドを呼び出すことでOracleDataReaderとして取得できます。OracleDbTypeプロパティが設定された出力パラメータは、OracleDbType.RefCursorにバインドされます。タイプOracleDbType.RefCursorの出力パラメータは、ExecuteReaderメソッドが起動された後は移入されません。

複数の出力REF CURSORパラメータがある場合、次のREF CURSORデータ型にアクセスするにはOracleDataReaderオブジェクトのNextResultメソッドを使用します。OracleDataReaderNextResultメソッドは、REF CURSORに対して順次アクセスを提供します。一時点でアクセスできるREF CURSORデータ型は1つのみです。

対応するREF CURSORデータ型に対してOracleDataReaderオブジェクトが作成される順序は、パラメータがバインドされている順序に依存します。PL/SQLストアド・プロシージャがREF CURSORデータ型を戻した場合は、これが最初のOracleDataReaderオブジェクトになり、出力されるすべてのREF CURSORデータ型はパラメータがバインドされている順序に従います。

REF CURSORからのDataSetへの移入

FillメソッドによりDataSetに正しく移入するには、OracleDataAdapterSelectCommandプロパティをタイプOracleDbType.RefCursorの出力パラメータにバインドする必要があります。Fillメソッドが正常に実行されると、REF CURSORデータ型を表すDataTableDataSetに移入されます。

コマンドの実行で複数のREF CURSORデータ型が戻されると、DataSetには複数のDataTableオブジェクトが移入されます。

Oracle Data Provider for .NETリリース11.1.0.6.20では、DataTableに移入されるREF CURSORを識別するため、拡張プロパティのREFCursorNameDataTableに導入されています。

このプロパティは、DataSetに複数のREF CURSOR(その中の1つ以上がNULL)が移入されている場合に特に便利です。たとえば、3つのREF CURSORを戻すストアド・プロシージャを実行してDataSetが移入され、2番目のREF CURSORNULLである場合、1番目のDataTableに対するREFCursorNameプロパティ値はREFCursorで、2番目のDataTableに対する値はREFCursor2です。NULL REF CURSORに対してDataTableは移入されません。

REF CURSORからのOracleRefCursorへの移入

1つ以上のREF CURSORデータ型を戻すコマンドに対してExecuteNonQueryが起動されると、OracleDbType.RefCursorとしてバインドされている各OracleCommandパラメータはOracleRefCursorオブジェクトへの参照を取得します。

OracleRefCursorオブジェクトからOracleDataReaderオブジェクトを作成するには、OracleRefCursorオブジェクトからGetDataReaderメソッドを起動します。後続のGetDataReaderメソッドへのコールでは、同一のOracleDataReaderオブジェクトへの参照が戻されます。

DataSetOracleRefCursorオブジェクトを移入するには、OracleRefCursorオブジェクトを取るOracleDataAdapterクラスのFillメソッドをアプリケーションで起動できます。OracleDataReaderオブジェクトと同じく、OracleRefCursorオブジェクトも順方向専用です。したがって、OracleRefCursorオブジェクトから行が読み取られると、問合せから再度移入されないかぎり、同じ行は取得できません。

コマンドの実行で複数のREF CURSORデータ型がOracleRefCursorオブジェクトとして戻される場合、アプリケーションではOracleDataReaderオブジェクトを作成するか、特定のOracleRefCursorオブジェクトをDataSetに移入するかを選択できます。OracleRefCursorオブジェクトから作成されるOracleDataReaderオブジェクトまたはDataSetオブジェクトはすべて同時にアクティブになり、任意の順序でアクセスできます。

REF CURSORから取得したDataSetの更新

REF CURSOR型は更新不可能です。ただし、DataSetから取り出したデータは更新できます。このため、OracleDataAdapterクラスには、REF CURSORデータの更新をすべてデータベースにフラッシュするカスタムSQL文が必要になります。

REF CURSORの更新のためのSQLの生成にOracleCommandBuilderオブジェクトを使用することはできません。

REF CURSORに対するExecuteScalarメソッドの動作

次のいずれかの場合、ExecuteScalarメソッドは、REF CURSORの最初の行の最初の列の値を戻します。

  • ストアド・ファンクション実行の戻り値

  • ストアド・プロシージャ実行の最初のバインド・パラメータ


関連項目:

詳細は、Oracle Databaseアプリケーション開発者ガイド-ラージ・オブジェクトを参照

ストアド・プロシージャへのREFカーソルの引渡し

アプリケーションは、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());
  }
}