プライマリ・コンテンツに移動

Oracle® Data Provider for .NET開発者ガイド ODAC 12.2c リリース1 (12.2.0.1) for Microsoft Windows E88311-03 |
| 目次 | 索引

前 | 次 |

# PL/SQL REF CURSORおよびOracleRefCursor

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

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

- OracleRefCursorオブジェクトの取得

- REF CURSORデータ型の取得

- REF CURSORからのOracleDataReaderへの移入

- REF CURSORからのDataSetへの移入

- REF CURSORからのOracleRefCursorへの移入

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

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

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

## OracleRefCursorオブジェクトの取得

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

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

## REF CURSORデータ型の取得

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

## REF CURSORからのOracleDataReaderへの移入

`REF` `CURSOR`データ型は、`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`データ型はパラメータがバインドされている順序に従います。

## REF CURSORからのDataSetへの移入

`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`は移入されません。

## REF CURSORからのOracleRefCursorへの移入

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の更新

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

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

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

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

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

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

関連項目:

詳細は、Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照

## ストアド・プロシージャへの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());
      }
    }