OPEN

OPEN ステートメントは、カーソルをオープンして、カーソルの結果表から行を取り出せるようにします。

呼び出し

このステートメントは、アプリケーション・プログラムに組み込んで使用します。それ以外の使用法はありません。 これは実行可能ステートメントですが、動的に準備することはできません。Java™ では指定できません。

権限

ステートメントでグローバル変数を参照する場合は、ステートメントの権限 ID が保持する特権に、少なくとも次のいずれか 1 つが含まれなければなりません。

  • ステートメント内で識別されるグローバル変数に対して、
    • そのグローバル変数に対する READ 特権
    • そのグローバル変数を含むライブラリーに対する *EXECUTE システム権限
  • データベース管理者権限

カーソルの使用に必要な権限については、DECLARE CURSORを参照してください。

構文

構文図を読む構文図をスキップする
>>-OPEN--cursor-name-------------------------------------------->

>--+-------------------------------------------------------+---><
   |        .-,--------.                                   |   
   |        V          |                                   |   
   +-USING----variable-+-----------------------------------+   
   |                       .-LOCAL--.                      |   
   +-USING SQL DESCRIPTOR--+--------+--SQL-descriptor-name-+   
   |                       '-GLOBAL-'                      |   
   '-USING DESCRIPTOR--descriptor-name---------------------'   

説明

cursor-name
オープンするカーソルを識別します。この cursor-name は、宣言されているカーソルを識別しなければなりません。カーソルの宣言については、DECLARE CURSOR ステートメントの Notes の項を参照してください。このカーソルは、OPEN ステートメントを実行するときには、クローズ状態になければなりません。

カーソルに関連付けられる SELECT ステートメントは、以下のいずれかです。

  • DECLARE CURSOR ステートメントで指定した選択ステートメント、または
  • DECLARE CURSOR ステートメントで指定したステートメント名 によって識別される準備済み選択ステートメント。このステートメントが正しく準備されていない場合や、選択ステートメント でない場合は、カーソルを正常にオープンすることはできません。

カーソルの対象となる結果表は、SELECT ステートメントを評価することによって得られます。 SELECT ステートメントを評価するときには、SELECT ステートメントに特殊レジスターが指定されていれば、 その特殊レジスターの現行値が使用され、OPEN ステートメントの USING 文節または SELECT ステートメントに変数が指定されていれば、その変数の現行値が使用されます。 結果表の行は、OPEN ステートメントの実行時に取得され、一時表に保持される場合と、 後続の FETCH ステートメントの実行時に取得される場合があります。 どちらの場合も、カーソルはオープン状態になり、結果表の最初の行の前に位置付けられます。 ただし、表が空であれば、実際のカーソルの位置は「最終行の後」になります。

USING
この後に変数のリストを指定します。準備済みステートメントのパラメーター・マーカー (疑問符) は、 ここに指定した変数の値によって置き換えられます。パラメーター・マーカーの説明については、PREPAREを参照してください。
  • DECLARE CURSOR ステートメントでパラメーター・マーカーを組み込んだ statement-name を指定していた場合は、USING を使用する必要があります。準備済みステートメントにパラメーター・マーカーが入っていない場合は、USING は無視されます。
  • DECLARE CURSOR ステートメントで select-statement を指定していた場合は、USING を使用して変数値をオーバーライドできます。詳細については、変数値のオーバーライドを参照してください。
DECLARE CURSOR ステートメントでパラメーター・マーカーの入った 準備済みステートメントを指定している場合は、USING を使用する必要があります。 準備済みステートメントにパラメーター・マーカーが入っていない場合は、USING は無視されます。
variable,…
ホスト構造体または変数を指定します。指定するホスト構造体または変数は それらの宣言の規則に従ってプログラムで宣言されていなければなりません。 ホスト構造体に対する参照は、その個々の変数に対する参照に置き換えられます。 変数の数は、準備済みステートメントのパラメーター・マーカーの数と同じでなければなりません。n 番目の変数は、 準備済みステートメントの n 番目のパラメーター・マーカーに対応します。

現在の接続がローカル接続である (DRDA® 接続ではない) 場合のみ、グローバル変数が使用できます。

USING SQL DESCRIPTOR SQL-descriptor-name
SQL 記述子を識別します。
LOCAL
記述子の名前の有効範囲はプログラム呼び出しのローカルであることを指定します。
GLOBAL
記述子の名前の有効範囲は SQL セッション全体であることを指定します。
SQL-descriptor-name
SQL 記述子の名前を指定します。名前は、指定の有効範囲を持つ既存の記述子を識別するものでなければなりません。

SQL 記述子内の情報の説明については、SET DESCRIPTORを参照してください。

USING DESCRIPTOR descriptor-name
SQLDA を識別します。この SQLDA には、入力変数の有効な記述が入っていなければなりません。

OPEN ステートメントを処理する前に、ユーザーは SQLDA の以下のフィールドをセットしておく必要があります。(REXX の場合は、規則が異なります。 詳しくは、組み込み SQL プログラミングを参照してください。)

  • SQLN (SQLDA に用意する SQLVAR のオカレンスの数を示します。)
  • SQLDABC (SQLDA 用に割り振る記憶域のバイト数を示します。)
  • SQLD (ステートメントを処理するときに、SQLDA で使用する変数の個数を指示します。)
  • SQLVAR の各オカレンス (変数の属性を指示します。)

SQLDA の記憶域は、SQLVAR のオカレンスをすべて収容するのに十分な大きさで割り振らなければなりません。 LOB または特殊タイプが結果の中に存在する場合、各パラメーター・マーカ ーごとに追加の SQLVAR 項目が必要です。 SQLVAR の説明、SQLVAR オカレンスの回数を判別する方法など、SQLDA について詳しくは、SQLDA (SQL 記述子域)を参照してください。

SQLD には、ゼロ以上で SQLN 以下の値をセットしなければなりません。 この値は、準備済みステートメント内のパラメーター・マーカーの個数と同じでなければなりません。 SQLDA によって n 番目に記述される変数は、準備済みステートメントの n 番目のパラメーター・マーカーに対応します。

RPG/400® はポインターを設定する機能を用意しておらず、SQLDA はポインターを使用して、 適切な変数を見つけるため、ユーザーは、RPG/400 アプリケーションの外側でポインターを設定しなければならないことに注意する必要があります。

クローズ状態のカーソル: 以下の時点では、 プログラム内のすべてのカーソルはクローズ状態にあります。

  • プログラムが呼び出されたとき。
    • CLOSQLCSR(*ENDPGM) が指定されている場合、プログラムが呼び出されるたびに、すべてのカーソルがクローズ状態になります。
    • CLOSQLCSR(*ENDSQL) が指定されている場合、1 つの SQL プログラムが呼び出しスタックに残っている間は、プログラムが初めて呼び出されるときに限って、すべてのカーソルがクローズ状態になります。
    • CLOSQLCSR(*ENDJOB) が指定されている場合は、ジョブが活動状態である限りは、 プログラムが初めて呼び出された時に限って、すべてのカーソルがクローズ状態になります。
    • CLOSQLCSR(*ENDMOD) が指定されている場合、モジュールが開始されるたびに、すべてのカーソルがクローズ状態になります。
    • CLOSQLCSR(*ENDACTGRP) が指定されている場合は、 プログラム内のモジュールが活動化グループ内で最初に開始された時に限って、すべてのカーソルがクローズ状態になります。
  • プログラムは、HOLD オプションの指定がない COMMIT ステートメントを実行して、新規の作業単位を開始します。 HOLD オプションを指定して宣言されたカーソルは、HOLD オプションの指定がない COMMIT ステートメントではクローズされません。 COMMIT HOLD ステートメントは、HOLD オプションで宣言されているかどうかに関わらず、カーソルをクローズしません。
  • プログラムは、HOLD オプションの指定がない ROLLBACK ステートメントを実行して、新規の作業単位を開始します。 ROLLBACK HOLD ステートメントは、HOLD オプションで宣言されているかどうかに関わらず、カーソルをクローズしません。
  • CONNECT (タイプ 1) ステートメントが実行されたとき。

また、次の場合に、カーソルがクローズ状態になることもあります。

  • CLOSE ステートメントが実行されたとき。
  • DISCONNECT ステートメントによって、そのカーソルが関連する接続が切り離されたとき。
  • そのカーソルが関連した接続が解除保留状態にあり、正常な COMMIT が行われたとき。
  • CONNECT (タイプ 1) ステートメントが実行されたとき。

カーソルの結果表から行を検索するには、 カーソルがオープン状態であるときに FETCH ステートメントを実行しなければなりません。 クローズ状態のカーソルをオープン状態に変更する方法は、OPEN ステートメントを実行する以外にはありません。

一時表の影響: カーソルの結果表が読み取り専用でなければ、 その結果表の行は後続の FETCH ステートメントを実行したときに取得されます。 これと同じ方式は、読み取り専用の結果表にも使用されます。 ただし、結果表が読み取り専用である場合は、DB2® for i がこの方式に代えて一時表方式の使用を選択することがあります。 一時表を使用する方式では、OPEN ステートメントの実行時に、結果表全体が一時表に挿入されます。 一時表を使用した場合は、プログラムの結果が以下のいくつかの点で異なります。

  • 通常は、後続の FETCH ステートメントが実行されるまでは発生しないエラーが、 OPEN ステートメントの実行時に発生する可能性がある。
  • カーソルがオープンされている時に INSERT、UPDATE、および DELETE ステートメントを実行すると、 結果表に影響を与えない可能性がある。
  • SELECT ステートメント内にある任意の NEXT VALUE 式は、 OPEN 中に結果表のすべての行に対して評価されます。 そのため、OPEN 状態のときに結果表のすべての行に対してシーケンス値が生成されます。
  • 任意の関数は、OPEN 中に結果表のすべての行に対して評価されます。 そのため、関数内にある SQL データを変更する外部アクションおよび SQL ステートメントは、 OPEN 状態のときに結果表のすべての行に対して実行されます。

逆に、一時表を使用しない場合は、カーソルがオープンされている間に INSERT、UPDATE、および DELETE ステートメントを実行すると、結果表に影響を与える可能性があり、SELECT ステートメント内のすべての NEXT VALUE 式および関数は、各行が取り出される際に評価されます。 このような操作の影響は、常に予測できるとは限りません。 例えば、SELECT * FROM T として定義されている結果表の行にカーソル CUR が位置付けられているときに、 T に対して行を挿入した場合は、その行の順序が定まっていないことから、その挿入が結果表に与える影響は予測できないものになります。 後続の FETCH CUR で、T の新しい行が取り出されることも、取り出されないこともあります。

パラメーター・マーカーの置換: ステートメント内にある 各パラメーター・マーカーは、実際には、カーソルに関連する SELECT ステートメントが評価されるときに、対応する変数の値に置き換えられます。 パラメーター・マーカーの置き換えは、変数の値をソースとし、データベース・マネージャー内部の変数をターゲッ トとする割り当て演算によって処理されます。 タイプ付きパラメーター・マーカーの場合、ターゲット変数の属性は、CAST によって指定されたものになります。タイプ無しパラメーター・マーカーの場合、ターゲット変数の属性は、パラ メーター・マーカーのコンテキストによって決まります。 パラメーター・マーカーに影響を及ぼす規則については、表 1を参照してください。

V が、パラメーター・マーカー P に対応する変数を指すものとします。V の値は、 値を列に割り当てる場合の規則に従って、P のターゲット変数に割り当てられます。したがって、次のことがいえます。

  • V は、ターゲットと互換性のあるものでなければなりません。
  • V が数値ならば、V の整数部の絶対値は、ターゲットの整数部の絶対値の最大を超えてはなりません。
  • V の属性がターゲットの属性と一致しない場合は、ターゲットの属性に合わせて値が変換されます。
  • ターゲットに NULL を入れることができない場合は、V の値は NULL であってはなりません。

ただし、値を列に割り当てる場合の規則とは、以下の点が異なります。

  • V がストリングで、その長さがターゲットの長さ属性より大きければ、V の値は途 中で切り捨てられます (エラーは出されません)。

カーソルの SELECT ステートメントが評価されるときに、P の代わりに使用される値は、P のターゲット変数の値です。 例えば、V が CHAR(6) で、ターゲットが CHAR(8) の場合は、P の代わりに使用される値は、 V の値に 2 つのブランクが埋め込まれた値になります。

USING 文節は、パラメーター・マーカーが入っている準備済み SELECT ステートメントを対象としたものです。 しかし、カーソルに関連する SELECT ステートメントが、DECLARE CURSOR ステートメントの一部として入っているときにも、 USING 文節を使用することができます。この場合、OPEN ステートメントは、SELECT ステートメント内の変数の属性が ターゲット変数の属性と同じであることを除けば、SELECT ステートメント内のそれぞれの変数がパラメーター・マーカーである場合と同じように実行されます。 このため、カーソルに関連する SELECT ステートメントにある変数の値は、 USING 文節内で指定された変数の値に変更されることになります。

変数値のオーバーライド: USING 文節の主な対象になっているのは、パラメーター・マーカーが入っている準備済み SELECT ステートメントです。しかし、カーソルに関連する SELECT ステートメントが、DECLARE CURSOR ステートメントの一部として入っているときにも、 USING 文節を使用することができます。その場合、OPEN ステートメントは、SELECT ステートメント内の変数の属性がターゲット変数の属性と同じであることを除けば、SELECT ステートメント内のそれぞれの変数がパラメーター・マーカーである場合と同じように実行されます。このため、カーソルに関連する SELECT ステートメントにある変数の値は、 USING 文節内で指定された変数の値に変更されることになります。

例 1: COBOL プログラム内に、以下のような処理を行う組み込みステートメントを書き込みます。

  1. カーソル C1 を定義します。このカーソルは、ADMRDEPT 部門「A00」によって管理されている各部門の DEPARTMENT 表からすべての行を取り出すためのカーソルです。
  2. 最初に取り出す行の前に、カーソル C1 を位置付けます。
   EXEC SQL  DECLARE C1 CURSOR FOR
              SELECT DEPTNO, DEPTNAME, MGRNO FROM DEPARTMENT
                 WHERE ADMRDEPT = 'A00'  END-EXEC.

   EXEC SQL  OPEN C1  END-EXEC.

例 2: C プログラムに OPEN ステートメントをコーディングして、 カーソル DYN_CURSOR を、動的に定義される選択ステートメント に関連付けます。 準備 済み選択ステートメント の選択リストには、既に 2 つの項目が定義されて いているものとします。最初の項目のデータ・タイプは整数で、2 番目の項 目のデータ・タイプは VARCHAR(64) です。 (以下の例には、関連するホスト変数の定義、PREPARE ステートメント、および DECLARE CURSOR ステートメントも示しています。)

  EXEC SQL  BEGIN DECLARE SECTION;
     static short hv_int;
     char hv_vchar64[64];
     char stmt1_str[200];
  EXEC SQL  END DECLARE SECTION;

  EXEC SQL  PREPARE STMT1_NAME FROM :stmt1_str;

  EXEC SQL  DECLARE DYN_CURSOR CURSOR FOR STMT1_NAME;

  EXEC SQL  OPEN DYN_CURSOR USING :hv_int, :hv_vchar64;

例 3: 例 2 と同じような OPEN ステートメントをコーディングします。 ただし、この例では、選択ステートメント内の項目の数とデータ・タイプは分かっていません。

  EXEC SQL  BEGIN DECLARE SECTION;
     char stmt1_str[200];
  EXEC SQL  END DECLARE SECTION;
  EXEC SQL  INCLUDE SQLDA;

  EXEC SQL  PREPARE STMT1_NAME FROM :stmt1_str;
  EXEC SQL  DECLARE DYN_CURSOR CURSOR FOR STMT1_NAME;

  EXEC SQL  OPEN DYN_CURSOR USING DESCRIPTOR :sqlda;