3.4 結果セットのサポート

各種リレーショナル・データベースでは、ストアド・プロシージャで結果セット(1つ以上の行セット)を戻すことができます。

従来、データベースのストアド・プロシージャの動作は、高水準プログラミング言語のプロシージャと同じでした。引数の数は一定で、INOUTまたはIN OUT型を使用できました。プロシージャにn引数が指定されている場合は、結果として最大n個の値が戻されます。ただし、ストアド・プロシージャでSELECT * FROM empなどの問合せを実行して結果を戻す必要がある場合があります。emp表の列数は固定ですが、プロシージャの作成時には行数を指示する手段がありません。このため、このような問合せの結果を戻す従来のストアド・プロシージャを作成できませんでした。その結果、複数のリレーショナル・データベース・ベンダーがストアド・プロシージャから結果セットを戻す機能を追加していますが、戻す方法はリレーショナル・データベースごとに異なっています。

Oracleには、REF CURSORというデータ型が用意されています。ストアド・プロシージャでは、他のすべてのOracleデータ型と同様に、このデータ型をINまたはOUT引数として使用できます。Oracle Databaseでは、ストアド・プロシージャにはREF CURSOR型の出力引数が必要です。次に、SQL文のカーソルをオープンし、その出力パラメータのそのカーソルにハンドルを置きます。これにより、コール元は他のカーソルの場合と同じ方法でREF CURSORから取得できます。

Oracle Databaseは、結果セットを戻す以外に多くの処理を行うことができます。REF CURSORデータ型をPL/SQLルーチンに入力引数として渡し、クライアント・プログラムとPL/SQLルーチン間、または複数のPL/SQLルーチン間でやり取りできます。

トピック:

3.4.1 Oracle以外のシステムでの結果セットのサポート

Oracle以外の複数のシステムで、ストアド・プロシージャにより結果セットを戻すことができますが、その方法は異なります。

通常、Oracle以外のデータベースでの結果セットのサポートは次の2つのモデルのいずれかに基づいています。

  • モデル1: 結果セットのサポート

    ユーザーは、ストアド・プロシージャの作成時に、そのストアド・プロシージャが戻すことのできる結果セットの最大数を明示的に指定できます。実行時には、ストアド・プロシージャは0(ゼロ)から指定された最大数の範囲内で結果セットをオープンできます。ストアド・プロシージャの実行後に、クライアント・プログラムは埋込みSQLディレクティブを使用するか、クライアントのライブラリ・ファンクションをコールして、これらの結果セットへのハンドルを取得できます。その後、クライアント・プログラムは、通常のカーソルと同様に結果セットから取得できます。

  • モデル2: 結果セットのサポート

    このモデルでは、ストアド・プロシージャから戻される結果セット数の制限は指定されていません。モデル1とOracle Databaseにはどちらも制限があります。Oracle Databaseでは、ストアド・プロシージャから戻すことができる結果セットの数はREF CURSOR OUT引数の数以下です。モデル1では、ストアド・プロシージャ言語のディレクティブを使用して上限が指定されます。モデル2がOracle Databaseおよびモデル1と異なるもう1つの点は、これらでは結果セットに対するハンドルが戻されないことです。かわりに、これらはストアド・プロシージャから戻された結果セット全体を送信します。Oracle DatabaseではハンドルはREF CURSOR OUT引数です。モデル1では、これはストアド・プロシージャの実行後に別に取得されます。Oracle Databaseとモデル1の両方で、ハンドルが取得された後で、ハンドルに対するフェッチを実行して結果セットのデータが取得されます。複数のカーソルが開いており、任意の順序でフェッチすることができます。ただし、モデル2のケースでは、すべてのデータがすでに送信されています。ストアド・プロシージャによって決定された順序で結果セットが届き、プロシージャの出力引数が最後に届きます。最初の結果セット全体を取得してから2番目の結果セット全体を取得し、すべての結果セットを取得するまで続ける必要があります。最後に、ストアド・プロシージャのOUT引数が取得されます。

3.4.2 異機種間サービスでの結果セットのサポート

結果セットのサポートは、Oracle以外のデータベースではそれぞれ異なっています。これらすべてをOracleのREF CURSORモデルにマップする必要があります。

Oracle以外のシステム間では動作が異なるため、異機種間サービスでの結果セットのサポートは、接続先となるOracle以外のシステムに応じて2つの方法のいずれかになります。

異機種間サービスでの結果セットのサポートについては、次の注意事項があります。

  • 結果セットのサポートは異機種間サービスの汎用コードに含まれますが、この機能をゲートウェイで動作させるには、ドライバもこれを実装する必要があります。すべてのドライバが結果セットのサポートを実装しているわけではありません。ゲートウェイがサポートされることを確認する必要があります。

  • 異機種間サービスでは、ストアド・プロシージャからのREF CURSOR OUT引数がサポートされます。INおよびIN OUT引数はサポートされません。

  • REF CURSOR OUT引数は、すべて匿名参照カーソルです。異機種間サービスで戻されるREF CURSORには型がありません。

トピック:

3.4.2.1 結果セット: カーソル・モード

Oracle以外のシステムのストアド・プロシージャから戻される各結果セットは、OracleドライバによりREF CURSOR型のOUT引数にマップされます。

クライアント・プログラムは、REF CURSOR型の複数のOUT引数を持つストアド・プロシージャを検知します。ストアド・プロシージャの実行後に、クライアント・プログラムはOracleストアド・プロシージャにより戻されるREF CURSORの場合と同じ方法で、そのREF CURSORからフェッチできます。3.4.1.1項で説明したように、異機種間サービスはゲートウェイへの接続時にカーソル・モードになります。

3.4.2.2 結果セット: 逐次モード

特定のストアド・プロシージャが戻すことのできる結果セットには最大数があります。戻される結果セットの数は、ストアド・プロシージャのREF CURSOR OUT引数の数以下です。戻される結果セットの数は、この上限より少なくてもかまいませんが、上限を超えることはできません。

3.4.1.2項で説明したシステムの場合、戻すことのできる結果セットの最大数はありません。モデル1(3.4.1.1項)の場合は、プロシージャが戻すことのできる結果セットの最大数、およびドライバが異機種間サービスに戻すことのできる結果セットの最大数は、REF CURSOR OUT引数の数により、ストアド・プロシージャに指定されています。ストアド・プロシージャの実行時に、戻される結果セットが最大数より少なければ、その他のREF CURSOR OUT引数はNULLに設定されます。

モデル2のデータベース・サーバーのもう1つの問題は、データベースによって送信された順序で結果セットを取得する必要があることです。このため、異機種間サービスがこれらのデータベースに接続するときにカーソル・モードで実行できません。これらのストアド・プロシージャによって戻される結果セットにアクセスするには、異機種間サービスを逐次モードにする必要があります。

逐次モードでは、ドライバから戻されるプロシージャ記述に次の情報が含まれます。

  • リモート・ストアド・プロシージャのすべての入力引数

  • 出力引数はなし

  • REF CURSOR型のOUT引数1つ(ストアド・プロシージャから戻される最初の結果セットに対応)

クライアントは、このREF CURSORからフェッチし、仮想パッケージ・ファンクションDBMS_HS_RESULT_SET.GET_NEXT_RESULT_SETをコールして、次の結果セットに対応するREF CURSORをフェッチします。すべての結果セットが取得されるまでこのファンクション・コールが繰り返されます。最後に戻される結果セットは、リモート・ストアド・プロシージャのOUT引数となります。

逐次モードの主な制限事項は、次のとおりです。

  • リモート・ストアド・プロシージャから戻された結果セットは、送信された順に取得される必要があります。

  • ストアド・プロシージャが実行されると、以前に実行されたストアド・プロシージャから戻された結果セットがすべて(データが取得されたかどうかに関係なく)クローズされます。

    関連項目:

    ゲートウェイを介した結果セットのサポート方法の詳細は、ご使用のゲートウェイ固有のマニュアルを参照してください。