カーソルを使用した行のリトリーブ
Db2 カーソルと呼ばれる仕組みがあります。 カーソルを使用することは、印刷されたテキストの特定の行を指が示しているのに似ています。
Db2 では、アプリケーションプログラムがカーソルを使用して、テーブルから取得した行の集合の中から1つまたは複数の行を指し示します。 また、カーソルを使用して、ストアード・プロシージャーが戻した結果セットから行をリトリーブできます。 アプリケーション・プログラムは、カーソルを使用して表から行を取り出すことができます。
SQL ステートメントの検索条件を満足する 1 セットの行のリトリーブと処理を行うことができます。 プログラムを使用して行を選択する場合、そのプログラムは 1 つ以上の行を一度に処理できます。
SELECT ステートメントは、DECLARE CURSOR ステートメント内にある必要があり、INTO 文節を含むことはできません。 DECLARE CURSOR ステートメントは、このカーソルの SELECT ステートメントを使ってリトリーブする行のセットを指定して、カーソルを定義し、名前を指定します。 この行のセットは結果表と呼ばれます。
DECLARE CURSOR ステートメントの実行後、以下のようにして、カーソルの結果表を処理します。
- カーソルをオープンして初めて、どの行もリトリーブできます。
Db2 に、結果テーブルの最初の行の処理準備ができたことを伝えるには、OPENステートメントを発行するようにプログラムを設定します。 Db2 次に、DECLARE CURSOR文内のSELECT文を使用して、行の集合を特定します。 そのSELECT文でホスト変数を使用する場合、 Db2 は変数の現在の値を使用して行を選択します。
- FETCH ステートメントを使用して、1 つ以上の行をリトリーブします。
FETCH ステートメントの最も単純な形式を使用すると、結果表の単一行をリトリーブします。これを行うには、行位置設定 カーソルを使用します。 どの時点であっても、行位置設定カーソルは多くとも単一の行を結果表からホスト変数にリトリーブします。 FETCH ステートメントを使用して結果表の複数の行をリトリーブできます。これを行うには、行セットの処理を可能にするカーソルを使用します。 行セット とは 1 セットの行であり、複数行フェッチを使ってこれをリトリーブします。
プログラムで行位置指定のFETCH文を発行すると、 Db2 はカーソルを使用して結果テーブルの行を指し、現在の行とします。 Db2 次に、FETCH文のINTO節で指定したプログラムホスト変数に、現在の行の内容を移動します。 FETCH ステートメントによりカーソルが移動します。 ホスト変数配列を使用し、単一の FETCH ステートメントで複数行のデータを戻すことができます。
- データの終わり条件が発生時にカーソルをクローズします。
結果表の行の処理を完了し、再度そのカーソルを使用したい場合は、CLOSE ステートメントを出してカーソルをクローズします。
プログラムには複数のカーソルを保有することができます。 各カーソルには、以下の要件があります。
- DECLARE CURSOR ステートメントで、カーソルを定義する
- OPEN と CLOSE ステートメントで、カーソルのオープンとクローズを行う
- FETCH ステートメントで、カーソルの結果表から行をリトリーブする
DECLARE CURSOR ステートメントでホスト変数を参照する前に、そのホスト変数を宣言する必要があります。 カーソルを使ってアクセスする 1 セットの行を定義および指定するには、DECLARE CURSOR ステートメントを出します。 DECLARE CURSOR ステートメントは、カーソルに名前を付け、 SELECT ステートメントを指定します。 この SELECT ステートメントは、結果表の中に存在する各行に対して基準を定義します。
カーソルを使用して、表の 1 つ以上の行のフェッチ、更新、または削除を行えますが、カーソルを使用して表に行を挿入することはできません。
例
プログラムで部門 D11 の社員に関するデータを調べ、EMP 表にそのデータを保持するものと仮定します。 以下の例には、そのための SQL ステートメントを記載してあります。この SQL ステートメントは COBOL プログラムの中に組み込まれて、カーソルを定義および使用しています。 以下の例では、プログラムはカーソルを使用して、EMP 表から 1 セットの行を処理します。
- 例: カーソルの定義
- 以下のステートメントでは、THISEMP という名のカーソルを定義します。
EXEC SQL DECLARE THISEMP CURSOR FOR SELECT EMPNO, LASTNAME, DEPT, JOB FROM EMP WHERE DEPT = 'D11' FOR UPDATE OF JOB END-EXEC. - 例: カーソルのオープン
- 以下のステートメントでカーソルをオープンします。
EXEC SQL OPEN THISEMP END-EXEC. - 例: カーソルを使用して行をリトリーブ
- 以下のステートメントではカーソル (THISEMP) を使用して行をリトリーブします。
EXEC SQL FETCH THISEMP INTO :EMP-NUM, :NAME2, :DEPT, :JOB-NAME END-EXEC. - 例カーソルを使用して現在行の更新
- 以下のステートメントでは、カーソル (THISEMP) を使用して部門 D11 にいる特定の社員に対する JOB 値を更新します。
EXEC SQL UPDATE EMP SET JOB = :NEW-JOB WHERE CURRENT OF THISEMP END-EXEC. - カーソルのクローズ例
- 以下のステートメントでカーソルをクローズします。
EXEC SQL CLOSE THISEMP END-EXEC.
カーソルの詳細
このカーソルが順方向スクロールの場合、各フェッチではカーソルを次の順番にある行、または行のセットにカーソルを位置付けます。 両方向スクロール・カーソル は前方向と逆方向にスクロール可能であり、先頭に、最後に、または相対オフセット位置に位置変更することができます。 アプリケーションは SQL ステートメントの強力なセットを使用して、ランダムな順序でカーソルを使ってデータをフェッチできます。 両方向スクロール・カーソルが特に有用なのは、画面ベースのアプリケーションの場合です。 結果表内のデータを静的な状態のままにすることを指定できます。 例えば、 会計アプリケーションではデータを定数のままの状態にしたい可能性があります。一方では、航空座席予約システム・アプリケーションでは、最新のフライト状況情報を表示する必要があります。
また、挿入、更新、または削除の発生時に基礎となるデータにおける変更に対して、両方向スクロール・カーソルがどの程度感知するか指定するオプションを、DECLARE CURSOR ステートメントで定義することもできます。
- センシティブ・カーソル とは、結果表の生成後にデータベースに対して行われた変更を感知するカーソルです。 例えば、アプリケーションが位置付け UPDATE と DELETE ステートメントをカーソル指定で実行する場合、これらの変更は結果表の中で認識できます。
- インセンシティブ・カーソル は、結果表の生成後にその結果表の基本行に対して行われた挿入、更新、または削除を感知しないカーソルです。 例えば、行の順序および結果表の各行ごとの値は、アプリケーションがいったんカーソルをオープンした後は変わりません。
カーソルがスクロール可能であることを指定するためには、SCROLL キーワード を指定してカーソルを宣言します。
EXEC SQL DECLARE C1 INSENSITIVE SCROLL CURSOR FOR
SELECT DEPTNO, DEPTNAME, MGRNO
FROM DEPT
ORDER BY DEPTNO
END-EXEC.このカーソルを使用して結果表の 5 番目の行をフェッチするには、以下の例のような FETCH ステートメントを使用します。
EXEC SQL FETCH ABSOLUTE +5 C1 INTO :HVDEPTNO, :DEPTNAME, :MGRNO;Db2 for z/OS® 動的スクロールカーソルと呼ばれる別のタイプのカーソルを提供します。 動的両方向スクロール・カーソルを使用すると、アプリケーションは、ほとんどの現行データにアクセスする間に基本表を直接スクロールできます。