DECLARE CURSOR
DECLARE CURSOR ステートメントは、カーソルを定義します。
呼び出し
このステートメントは、アプリケーション・プログラムに組み込んで使用します。それ以外の使用法はありません。 このステートメントは、実行可能ステートメントではありません。 Java™で指定してはなりません。
許可
このステートメントを使用するための権限は不要です。 ただし、カーソルに関して OPEN または FETCH を使用するには、ステートメントの権限 ID によって保持される特権に、少なくとも次の 1 つが含まれていなければなりません。
- 該当のカーソルの SELECT ステートメントで識別される各表またはビューに対して、
- 表やビューに対する SELECT 特権、および
- 表またはビューが含まれるスキーマに対する USAGE 特権
- データベース管理者権限
カーソルの SELECT ステートメントは、次のいずれかです。
- ステートメント名 によって識別される準備済み選択ステートメント。
- 指定された 選択ステートメント。
statement-name を指定した場合:
- ステートメントの権限 ID は、 プログラムが作成されたときに CRTSQLxxx コマンドに USRPRF(*OWNER) および DYNUSRPRF(*OWNER) が 指定された場合を除いて、実行時の権限 ID です。 詳しくは、 許可 ID と許可名を参照してください。
- CRTSQLxxx コマンドで DLYPRP(*YES) が指定されていない場合には、選択ステートメント を準備するときに権限検査が行われます。
- DLYPRP (*YES) パラメーターを使用してコンパイルされているプログラムについては、カーソルをオープンするときに権限検査が行われます。
選択ステートメント を指定した場合は、
- SQL 命名を指定した USRPRF(*OWNER) または USRPRF(*NAMING) が、CRTSQLxxx コマンドで指定された場合は、ステートメントの権限 ID は、その SQL プログラムまたはパッケージの所有者です。
- システム命名を指定した USRPRF(*USER) または USRPRF(*NAMING) が、CRTSQLxxx コマンドで指定された場合は、ステートメントの権限 ID は、実行時権限 ID です。
- REXX では、ステートメントの許可 ID は実行時の許可 ID です。
- カーソルがオープンされるときには、権限検査が実行されます。
SQL 特権に対応するシステム権限については、 表またはビューに対する特権を検査する際の対応するシステム権限を参照してください。
構文
説明
- カーソル名
- カーソルの名前を指定します。 ソース・プログラムで宣言されている、他のカーソルと同じ名前を指定してはなりません。
- ASENSITIVE、SENSITIVE、または INSENSITIVE
- カーソルが変更に対して反応を決めない、反応する、または反応しないことを指定します。 statement-name を指定した場合、デフォルトはこのステートメントの対応する準備属性になります。 それ以外の場合は、ASENSITIVE がデフォルトです。
- ASENSITIVE
- カーソルは選択ステートメント の最適化の内容に応じて SENSITIVE または INSENSITIVE として動作できることを指定します。
- SENSITIVE
- カーソルがオープンになった後にデータベースに加えられた変更が結果表で可視になることを指定します。 カーソルには、その結果表の基礎となる行に対してカーソルのオープン後に行われた更新または削除については、ある程度の感度があります。 カーソルは、同じカーソルを使用して位置付けられた更新または削除を常に認識します。 さらに、カーソルには、このカーソルの外部で行われた変更に対する感度があります。 データベース・マネージャーが変更をカーソルに対して可視状態にできない場合は、エラーが戻されます。 データベース・マネージャーが変更をカーソルに対して可視状態にできないのは、カーソルが暗黙的に読み取り専用になっている場合です。 ( カーソルの結果表を参照してください。) SENSITIVE を指定する場合は、SELECT ステートメントにデータ変更表参照 を入れられません。
- INSENSITIVE
- これを指定するとカーソルは、そのオープン後は、この活動化グループや他の活動化グループで実行する挿入、更新、または削除を検知しなくなります。 INSENSITIVE が指定されると、カーソルは読み取り専用となり、カーソルのオープン時に一時結果が作成されます。 また、 SELECT ステートメントに UPDATE 文節を含めることはできません。
- NO SCROLL または SCROLL
- カーソルがスクロール可能かどうかを指定します。 statement-name を指定した場合、デフォルトはこのステートメントの対応する準備属性になります。 それ以外の場合は、NO SCROLL がデフォルトです。
- NO SCROLL
- カーソルがスクロール可能でないことを指定します。
- SCROLL
- カーソルがスクロール可能であることを指定します。
- WITHOUT HOLD または WITH HOLD
- コミット操作の結果として、カーソルがクローズされるのを防止するかどうかを指定します。 statement-name を指定した場合、デフォルトはこのステートメントの対応する準備属性になります。 それ以外の場合は、WITHOUT HOLD がデフォルトです。
- WITHOUT HOLD
- コミット操作の結果としてカーソルをクローズすることを回避しません。
- WITH HOLD
- コミット操作の結果として、カーソルがクローズされるのを防止します。 WITH HOLD 文節を使用して宣言されたカーソルがコミット時点で暗黙にクローズするのは、そのカーソルに関連する接続がコミット操作中に終了する場合だけです。
WITH HOLD の指定がある場合、コミット操作はその時点の作業単位における変更をすべてコミットし、そのカーソル一を維持する上で必要なロック以外のすべてのロックを解放します。 その後、位置指定 UPDATE または DELETE ステートメントを実行できるようにするために FETCH ステートメントが必要になります。
カーソルはすべて、CONNECT (タイプ 1) またはロールバック操作によって暗黙にクローズされます。 ある接続に関連するカーソルはすべて、その接続の切り離しによって暗黙にクローズされます。 カーソルは、WITH HOLD が指定されていない場合、または、そのカーソルに関連した接続が解除保留状態にある場合にも、コミット操作によって暗黙にクローズされます。
カーソルがコミット操作の前にクローズされた場合、その効果は、そのカーソルが WITH HOLD オプションを指定せずに宣言されたのと同一です。
- WITHOUT RETURN または WITH RETURN
- カーソルの結果表をプロシージャーの結果セットとして使用することを指定します。 statement-name を指定した場合、デフォルトはこのステートメントの対応する準備属性になります。 それ以外の場合は、WITHOUT RETURN がデフォルトです。
- WITHOUT RETURN
- カーソルの結果表がプロシージャーの結果セットとして使用されることを意図していないことを指定します。
- WITH RETURN
- カーソルの結果表をプロシージャーの結果セットとして使用することを指定します。 プロシージャーのソース・コードに DECLARE CURSOR ステートメントが含まれていなければ、この文節は無視されます。SQL プロシージャーの場合に結果セットが返されるのは、プロシージャー定義の DYNAMIC RESULT SETS 文節で結果セットの最大数としてゼロ以外の値を指定した場合に限られます。
- WITH RETURN 文節を使用して定義したカーソルがプロシージャーの終了時にオープンしたままになっていれば、それらのカーソルによってプロシージャーの結果セットが定義されます。 プロシージャーの作成時に CLOSQLCSR(*ENDACTGRP) を指定していない限り、他のすべてのオープン・カーソルは、プロシージャーの終了時にクローズします。
- WITH RETURN 文節または WITHOUT RETURN 文節を使用して定義したカーソルがストアード・プロシージャーに存在しない場合は、ストアード・プロシージャーの終了時にオープンしているカーソルが結果セット・カーソルになる可能性があります。
- プロシージャーの結果セットを決定するその他の考慮事項については、 CREATE PROCEDURE (SQL) の DYNAMIC RESULT SETS 節を参照してください。
外部プロシージャーの場合は、以下のようになります。- プロシージャーの作成時に CLOSQLCSR(*ENDACTGRP) を指定していない限り、WITH RETURN 文節を使用して定義したカーソル (または SET RESULT SETS ステートメントで結果セット・カーソルとして指定したカーソル) がプロシージャーの終了時にオープンしていれば、それらのカーソルによってプロシージャーの結果セットが定義される可能性があります。 他のすべてのオープン・カーソルは、オープンしたままの状態で残ります。
- WITH RETURN 文節または WITHOUT RETURN 文節を使用して定義したカーソルがストアード・プロシージャーに存在せず、SET RESULT SETS ステートメントで結果セット・カーソルとして指定したカーソルも存在しない場合は、ストアード・プロシージャーの終了時にオープンしているカーソルが結果セット・カーソルになる可能性があります。
- プロシージャーの結果セットを決定するその他の考慮事項については、 CREATE PROCEDURE (external) の DYNAMIC RESULT SETS 節を参照してください。
スクロール可能ではないカーソルの場合、結果セットには、現行カーソル位置から結果表の最後までのすべての行が含まれます。 スクロール可能なカーソルの場合、結果セットには、結果表のすべての行が含まれます。
- TO CALLER
- カーソルがプロシージャーの呼び出し側に結果セットを戻せることを指定します。 例えば、呼び出し側がクライアント・アプリケーションである場合、 結果セットはそのクライアント・アプリケーションに戻されます。
- TO CLIENT
- カーソルがクライアント・アプリケーションに結果セットを戻せることを指定します。 このカーソルは、中間にネストされたプロシージャーからは見えません。 関数またはトリガーが直接または間接的にプロシージャーを呼び出すと、結果セットはクライアントに返されず、プロシージャーの終了後にカーソルがクローズされます。
複数のモジュールを持つ ILE プログラムから結果セットが戻される場合は、TO CLIENT が必要な場合があります。
- WITHOUT EXTENDED INDICATORS または WITH EXTENDED INDICATORS
- 拡張標識を使用可能にするかどうかを指定します。 statement-name を指定した場合、デフォルトはこのステートメントの対応する準備属性になります。 指定していない場合、デフォルトは収容側のプログラムまたはサービス・プログラムで指定された属性になります。
- WITHOUT EXTENDED INDICATORS
- 拡張標識変数を使用不可にすること、および暗黙または明示的な UPDATE 文節または select-statement の中では更新可能な列のみを使用できることを指定します。
- WITH EXTENDED INDICATORS
- 拡張標識変数を使用可能にすること、および選択ステートメント の暗黙または明示的な UPDATE 文節内では非更新可能な列を使用できることを指定します。
- 選択ステートメント
- カーソルの SELECT ステートメントを指定します。 詳しくは、 選択ステートメント を参照してください。
選択ステートメント には、パラメーター・マーカーを含めることはできませんが (REXX の場合を除く)、変数への参照を含めることはできます。 REXX 以外のホスト言語では、ホスト変数の宣言は、ソース・プログラムの DECLARE CURSOR ステートメントより前になければなりません。 REXX では、変数の代わりにパラメーター・マーカーを使用し、ステートメントを準備する必要があります。
- ステートメント名
- カーソルの SELECT ステートメントは、そのカーソルのオープンの時点で ステートメント名 によって識別される準備済み選択ステートメント です。 このステートメント名 は、ソース・プログラムの他の DECLARE CURSOR ステートメントで指定されているステートメント名 と同じであってはなりません。 準備済みステートメントの説明については、 PREPARE を参照してください。
ノート
DECLARE CURSOR の配置: DECLARE CURSOR ステートメントは、 C および PL/I を除いて、該当するカーソルを明示的に参照するどのステートメントよりも前に置かなければなりません。
カーソルの結果表: オープン状態にあるカーソルは、結果表 と、その結果表の行に対する相対的な位置を指定します。 指示される表は、該当するカーソルの SELECT ステートメントで指定されている結果表です。
以下の条件がすべて満たされている場合は、カーソルは 削除可能 です。
- 外部の全選択で指定されているのが、1 つの基本表または削除可能ビューだけであり、その基本表または削除可能ビューがカタログ表またはカタログ・ビューではなく、ネストされた表の式に含まれているわけでもない。
- 外側の全選択に VALUES 文節が含まれていない。
- 外側の全選択に、GROUP BY 文節または HAVING 文節が含まれていない。
- 外側の全選択の選択リストに集約関数が含まれていない。
- 外側の全選択に UNION 演算子、UNION ALL 演算子、EXCEPT 演算子、または INTERSECT 演算子が含まれていない。
- 外側の全選択の SELECT 文節 に DISTINCT 文節が含まれていない。
- 外部全選択に FOR SYSTEM_TIME 期間指定が含まれない
- 外側の全選択に FROM 文節のデータ変更表参照 が含まれていない。
- select-statement に ORDER BY 文節と UPDATE 文節が含まれておらず、SENSITIVE が DECLARE CURSOR ステートメントに指定されていない。
- 選択ステートメント に FOR READ ONLY 文節が含まれていない。
- 外側の全選択の結果に一時表が使用されていない。
- select-statement に SCROLL キーワードが含まれていないか、または SENSITIVE キーワードか UPDATE 文節も指定されている。
- UPDATE 文節が指定されていない場合に、選択リストに DATALINK 列が含まれていない。
以下のすべての条件が満たされている場合は、カーソルに関連した外側 の全選択の選択リスト内の結果列は更新可能 です。
- カーソルが削除可能。
- 結果列が、表の 1 つの列またはビューの更新可能な列からのみ派生したものである。 すなわち、結果の列は、演算子、スカラー関数、定数、またはそれ自体がそのような式から取り出された列を含む式から取り出される列であってはなりません。
カーソルが読み取り専用 であるのは、削除可能でない場合です。
UPDATE 文節を省略する場合、副選択の SELECT 文節の中の列のうち、更新可能なものだけを変更できます。
- WITH EXTENDED INDICATORS を指定した場合は、全選択の最初の FROM 文節で識別される表またはビューのすべての列。
- それ以外の場合は、全選択の最初の FROM 文節で識別される表またはビューの更新可能な列のみ。
列名のリストを使用して UPDATE が指定された場合、列名のリストに指定された列のみが、このカーソルを識別する後続の位置指定 UPDATE ステートメントの割り当て文節のターゲットとして指定できます。
カーソルの有効範囲: cursor-name の有効範囲は、これが定義されたソース・プログラム、つまりプリコンパイラーに実行依頼されたプログラムです。 したがって、カーソルを参照できるステートメントは、そのカーソル宣言と一緒にプリコンパイルされたステートメントだけです。 例えば、別個にコンパイルされた他のプログラムから呼び出されるプログラムでは、その呼び出し側プログラムでオープンされているカーソルを使用することはできません。
また、カーソル名の有効範囲は、カーソルが収められているプログラムの実行場 所であるスレッドに限定されます。 例えば、同一ジョブ内の 2 つの別個のスレッドで同じプログラムが実行しているとした場合、2 番目のスレッドは、最初のスレッドでオープンされたカーソルを使用することはできません。
CRTSQLxxx コマンドに CLOSQLCSR(*ENDJOB)、CLOSQLCSR(*ENDSQL)、または CLOSQLCSR(*ENDACTGRP) が指定されている場合を除いて、カーソルを参照できるのは、プログラム・スタック内の該当するプログラムの同じインスタンスに限られます。
- CLOSQLCSR(*ENDJOB) が指定されている場合は、プログラム・スタックにある該当するプログラムのどのインスタンスでもカーソルを参照することができます。
- CLOSQLCSR(*ENDSQL) が指定されている場合は、プログラム・スタック上の最後の SQL プログラムが終了するまでは、そのプログラム・スタックにある該当するプログラムのどのインスタンスでもカーソルを参照することができます。
- CLOSQLCSR(*ENDACTGRP) が指定されている場合は、活動化グループが終了するまでは、その活動化グループ内のモジュールのすべてのインスタンスでカーソルを参照することができます。
カーソルの有効範囲は、そのカーソルが宣言されているプログラムですが、そのプログラムから作成された各パッケージは、そのカーソルの別個のインスタンスを含み、実行時に複数のカーソルが存在することがあります。 例えば、CONNECT (タイプ 2) ステートメントを使用して、 次の順序でロケーション X とロケーション Y に接続するプログラムを想定します。
EXEC SQL DECLARE C CURSOR FOR…
EXEC SQL CONNECT TO X;
EXEC SQL OPEN C;
EXEC SQL FETCH C INTO…
EXEC SQL CONNECT TO Y;
EXEC SQL OPEN C;
EXEC SQL FETCH C INTO…2 番目の OPEN C ステートメントは、カーソル C の別個のインスタンスを参照しているので、エラーにはなりません。
SELECT ステートメントは、カーソルがオープンされる時点で評価されます。 同一のカーソルをいったんオープンし、クローズした後で、再びオープンした場合には、結果が異なる可能性があります。 カーソルの SELECT ステートメントに CURRENT DATE、CURRENT TIME、または CURRENT TIMESTAMP が含まれる場合、これらの特殊レジスターへのすべての参照で、FETCH ごとにそれぞれ同じ日時値が取り出されます。 この値は、カーソルがオープンされたときに決まります。 同一の SELECT ステートメントを使用する、複数のカーソルを同時にオープンすることができます。 これらのカーソルはそれぞれ、独立したアクティビティーと見なされます。
シーケンス式の使用: カーソルで NEXT VALUE 式と PREVIOUS VALUE 式を使用する方法については、 カーソルでのシーケンス式の使用を参照してください。
データのブロック化: データの処理効率を高め るために、データベース・マネージャーは読み取り専用カーソル用のデータをブロック化することができます。 カーソルを位置指定 UPDATE または DELETE ステートメントの中で 使用することを予定していない場合は、カーソルを FOR READ ONLY として 宣言してください。
REXX での使用法: REXX プロシージャー内の DECLARE CURSOR ステートメントで変数を使用する場合、DECLARE CURSOR は PREPARE および EXECUTE のオブジェクトでなければなりません。
一時的な結果: 特定の SELECT ステートメント を一時結果表としてインプリメントすることができます。
- 一時的結果表は、下記の場合に作成されます。
- INSENSITIVE が指定された場合。
- ORDER BY 文節と GROUP BY 文節の指定する列が異なる場合、または列の指定の順序が異なる場合。
- ORDER BY 文節と GROUP BY 文節に、ユーザー定義の関数、あるいは、スカラー関数である DLVALUE、DLURLPATH、DLURLPATHONLY、 DLURLSERVER、DLURLSCHEME、または、属性が FILE LINK CONTROL と READ PERMISSION DB のデータ・リンクの場合は DLURLCOMPLETE のいずれかが含まれている場合。
- UNION 文節、EXCEPT 文節、INTERSECT 文節、または DISTINCT 文節が指定されている場合。
- ORDER BY 文節または GROUP BY 文節で指定されている列が、すべて同じ表のものでない場合。
- JOINDFT データ記述仕様 (DDS) キーワードによって定義された論理ファイルが、別のファイルに結合されている場合。
- 複数のデータベース・ファイルのメンバーに基づく論理ファイルが指定されている場合。
- DECLARE CURSOR の選択ステートメントが GROUP BY 文節を使用しているときに、FETCH ステートメントで CURRENT または RELATIVE スクロール・オプションが指定されている場合。
- FETCH FIRST n ROWS ONLY 文節が指定されていない場合。
- 次のような副照会が組み込まれている照会。
- 最外部の照会が内部の副選択に相関値を提供しない場合。
- No IN、 = ANY、 = SOME、または <> すべてのサブクエリは、最も外側のクエリによって参照されます。
- カーソルを通じてデータをフェッチ中にカーソルの基礎表に対して更新操作、削除操作、または挿入操作が行われる。かつ
- カーソルに対するフェッチ操作が、カーソルによって以前にフェッチされた同じ行を戻そうとする。
代替構文: 以下のキーワードは、旧リリースとの互換性を維持するためにサポートされている同義語です。 これらのキーワードは標準キーワードではないので、原則として使用しないようにしてください。
- DYNAMIC SCROLL は SENSITIVE DYNAMIC SCROLL の同義語です。
例
例 1: 表 DEPARTMENT からデータを検索するための照会のカーソルとして、C1 を宣言します。 DECLARE CURSOR ステートメントにこの照会自体が含まれています。
EXEC SQL DECLARE C1 CURSOR FOR
SELECT DEPTNO, DEPTNAME, MGRNO
FROM DEPARTMENT
WHERE ADMRDEPT = 'A00';例 2: 表 DEPARTMENT からデータを検索するための照会のカーソルとして、C1 を宣言します。 検索した更新データによるデータの更新は後で行われ、データは照会が実行されるときはロックされるものとします。 DECLARE CURSOR ステートメントにこの照会自体が含まれています。
EXEC SQL DECLARE C1 CURSOR FOR
SELECT DEPTNO, DEPTNAME, MGRNO
FROM DEPARTMENT
WHERE ADMRDEPT = 'A00'
FOR READ ONLY WITH RS USE AND KEEP EXCLUSIVE LOCKS;例 3: STMT2 という名前のステートメント用のカーソルとして、C2 を宣言します。
EXEC SQL DECLARE C2 CURSOR FOR STMT2;例 4: 表 EMPLOYEE の位置指定更新に使用する照会用のカーソルとして、C3 を宣言します。 更新が完了するたびに、カーソルをクローズせずに更新がコミットされるようにします。
EXEC SQL DECLARE C3 CURSOR WITH HOLD FOR
SELECT *
FROM EMPLOYEE
FOR UPDATE OF WORKDEPT, PHONENO, JOB, EDLEVEL, SALARY;更新する列を明示的に指定する代わりに、列を指定せずに UPDATE 文節を使用することもできます。 この方法で、表の更新可能な列をすべて更新することができます。 このカーソルは更新可能なので、このカーソルを使用して表から行を削除することもできます。
例 5: C プログラムにおいて、カーソル C1 を使用して、指定したプロジェクト (PROJNO) に関する値を、表 EMPPROJACT の最初の 4 列から一度に 1 行ずつ取り出して、 それらの値を EMP (CHAR(6))、 PRJ (CHAR(6))、ACT (SMALLINT)、および TIM (DECIMAL(5,2)) というホスト変数に入れています。 検索するプロジェクトの値は、ホスト変数 SEARCH_PRJ (CHAR(6)) から入手します。 動的に 選択ステートメント を準備して、 プログラムの実行時に検索するプロジェクトを指定できるようにします。
void main ()
{
EXEC SQL BEGIN DECLARE SECTION;
char EMP[7];
char PRJ[7];
char SEARCH_PRJ[7];
short ACT;
double TIM;
char SELECT_STMT[201];
EXEC SQL END DECLARE SECTION;
EXEC SQL INCLUDE SQLCA;
strcpy(SELECT_STMT, "SELECT EMPNO, PROJNO, ACTNO, EMPTIME \
FROM EMPPROJACT \
WHERE PROJNO = ?");
.
.
.
EXEC SQL PREPARE SELECT_PRJ FROM :SELECT_STMT;
EXEC SQL DECLARE C1 CURSOR FOR SELECT_PRJ;
/* Obtain the value for SEARCH_PRJ from the user. */
.
.
.
EXEC SQL OPEN C1 USING :SEARCH_PRJ;
EXEC SQL FETCH C1 INTO :EMP, :PRJ, :ACT, :TIM;
if (strcmp(SQLSTATE, "02000", 5) )
{
data_not_found();
}
else
{
while (strcmp(SQLSTATE, "00", 2) || strcmp(SQLSTATE, "01", 2) )
{
EXEC SQL FETCH C1 INTO :EMP, :PRJ, :ACT, :TIM;
}
}
EXEC SQL CLOSE C1;
.
.
.
} EXEC SQL DECLARE C1 SENSITIVE SCROLL CURSOR FOR
SELECT DEPTNO, DEPTNAME, MGRNO
FROM TDEPT
WHERE ADMRDEPT = 'A00';例 7: 4 つの列から値を取り出し、逐次化可能 (RR) 分離レベルを使用して、 それらの値を変数に割り当てるために、カーソルを宣言します。
EXEC SQL DECLARE CURSOR1 CURSOR FOR
SELECT COL1, COL2, COL3, COL4
FROM TBLNAME WHERE COL1 = :varname
WITH RR;例 8: EMPLOYEE 表が、 生成された列 WEEKLYPAY (年間の給与に基づいて週ごとの支払いを計算する) を追加するように調整されていると想定します。 カーソルを宣言して、挿入される行からシステムが生成した列の値を取り出します。
EXEC SQL DECLARE C2 CURSOR FOR
SELECT E.WEEKLYPAY
FROM FINAL TABLE
(INSERT INTO EMPLOYEE
(EMPNO, FIRSTNME, MIDINIT, LASTNAME, EDLEVEL, SALARY)
VALUES('000420', 'Peter', 'U', 'Bender', 16, 31842)) AS E;