LOOP
文は、一連の文を複数回実行します。 PL/SQLには、次のLOOP文があります。
基本LOOP
WHILE
LOOP
FOR
LOOP
カーソルFOR
LOOP
構文
basic_loop_statement ::=
while_loop_statement ::=
for_loop_statement ::=
cursor_for_loop_statement ::=
キーワードとパラメータの説明
basic_loop_statement
回数の制限なしに実行するループです。 LOOP
キーワードとEND
LOOP
キーワードで一連の文を囲みます。 ループが繰り返されるたびに一連の文が実行され、制御がループの先頭に戻ります。 EXIT
、GOTO
またはRAISE
文は、ループの外に分岐します。 例外が呼び出された場合もループは終了します。
boolean_expression
この式の値がTRUE
の場合にのみ、LOOP
の後の文が実行されます。
cursor_for_loop_statement
SQL問合せを発行し、結果セットの行をループします。 この手法を使用すると、問合せの処理が、他のプログラミング言語でテキスト行を読み取る場合と同様に簡単になります。
カーソルFOR
ループは、ループ索引を%ROWTYPE
属性のレコードとして暗黙的に宣言し、カーソルをオープンして、結果セットから行の値をフェッチしてレコード内のフィールドに入れる一連の作業を繰り返し、すべての行を処理した後にカーソルをクローズします。
cursor_name
現行の有効範囲の中で、事前に宣言されている明示カーソルを識別します。 カーソルFOR
ループに入ると、cursor_name
は、OPEN
文または外側のカーソルFOR
ループによって、すでにオープンされたカーソルを参照できません。
cursor_parameter_name
カーソルの仮パラメータとして宣言された変数を識別します。 cursor_parameter_declaration
の構文は、「明示カーソル」を参照してください。 カーソルのパラメータは、問合せの中で定数が使用できる場所であれば、どこででも使用できます。 カーソルの仮パラメータはIN
パラメータにしてください。
for_loop_statement
数値のFOR_LOOP
ループは、指定された整数の範囲内でループを繰り返し実行します。 反復の範囲は、キーワードFOR
とLOOP
に囲まれた反復スキームの一部です。
反復の範囲はFOR
ループに入った段階で評価され、それ以降は評価されません。 ループ本体は、lower_bound
..upper_bound
によって定義された範囲の整数1つにつき1回実行されます。 1回の反復が終わると、ループ索引に増分が加えられます。
index_name
ループ索引に名前を付ける未宣言の識別子です(ループ・カウンタと呼ばれる場合もあります)。 有効範囲はループ自体になるため、ループの外側では索引を参照できません。
index_name
の暗黙的な宣言は、ループの外側での宣言をオーバーライドします。 同じ名前の別の変数を参照するには、ラベルを使用します。 詳細は、例4-22「ループ・カウンタと同じ名前のグローバル変数の参照」を参照してください。
ループの内側では、索引は定数のように扱われるため、式の中で使用できます。ただし、値は代入できません。
label_name
オプションとしてループに付けるラベル名で、未宣言の識別子です。label_name
を使用する場合は、二重の山カッコで囲み、ループの先頭に置く必要があります。 必要に応じて、label_name
を山カッコで囲まずにループの最後に置くこともできます。
label_name
をEXIT
文の中で使用すると、label_name
によってラベル付けされているループを終了できます。 カレント・ループのみでなく、外側のループも終了できます。
外側のFOR
ループと、その内側のネストされたFOR
ループの索引が同じ名前である場合、ネストされたループから外側のループの索引を参照できません。ただし、外側のループがlabel_name
でラベル付けされている場合は、ドット表記法を使用すれば参照できます。 詳細は、例4-23「内部カウンタと同じ名前の外部カウンタの参照」を参照してください。
lower_bound .. upper_bound
数値を戻す式です。 それ以外の場合、PL/SQLは事前定義の例外VALUE_ERROR
を呼び出します。 式は、最初にループに入ったときにのみ評価されます。 下限は1である必要はありません。次の例に示すように、負の整数にすることができます。
FOR i IN -5..10
ループ・カウンタの増分値(または減分値)は1である必要があります。
内部的に、PL/SQLはPLS_INTEGER
一時変数に境界の値を代入します。さらに、必要に応じてその値を最も近い整数に四捨五入します。 PLS_INTEGER
の大きさの範囲は、32ビットで表すと、-2147483648から2147483647です。 範囲外の数値を評価した場合、PL/SQLが代入をすると、数値オーバーフローのエラーが発生します。 詳細は、「PLS_INTEGERおよびBINARY_INTEGERデータ型」を参照してください。
デフォルトでは、ループ索引にはlower_bound
の値が代入されます。 この値がupper_bound
の値を超えていない場合、ループの中の一連の文が実行され、索引が増分されます。 索引の値がupper_bound
の値を超えていない場合、一連の文がもう一度実行されます。 この処理は、索引の値がupper_bound
の値を超えるまで繰り返されます。 下回った時点で、ループが終了します。
record_name
暗黙的に宣言されたレコードを識別します。 このレコードはcursor_name
またはselect_statement
によって取り出された行と同じ構造を持ちます。
レコードはループの内側のみで定義されています。 ループの外側からこのレコードのフィールドを参照できません。 record_name
の暗黙的な宣言は、ループの外側での宣言をオーバーライドします。 同じ名前のレコードは、ブロック・ラベルを使用して参照を修飾しないかぎり、ループの内側から参照できません。
レコード中のフィールドには、暗黙のうちにフェッチされた行の列値が格納されます。 フィールドの名前とデータ型は、対応する列の名前とデータ型と同じです。 フィールドの値にアクセスするには、次のようにドット表記法を使用します。
record_name.field_name
FOR
ループのカーソルによってフェッチされた選択項目の名前は、単純名にしてください。また、それらが式である場合は、別名を持つ必要があります。 次の例では、選択項目salary+NVL(commission_pct,0)*1000
の別名としてwages
を指定しています。
CURSOR c1 IS SELECT employee_id, salary + NVL(commission_pct,0) * 1000 wages FROM employees ...
デフォルトでは、反復は、範囲の下限から上限に上向きに進みます。 キーワードREVERSE
を使用すると、反復は上限から下限に下向きに進みます。 次に例を示します。
BEGIN FOR i IN REVERSE 1..10 LOOP -- i starts at 10, ends at 1 DBMS_OUTPUT.PUT_LINE(i); -- statements here execute 10 times END LOOP; END; /
ループ索引にはupper_bound
の値が代入されます。 この値がlower_bound
の値を下回っていない場合、ループの中の一連の文が実行され、索引が減分されます。 索引の値がまだlower_bound
の値を下回っていない場合、一連の文がもう一度実行されます。 この処理は、索引の値がlower_bound
の値を下回るまで繰り返されます。 下回った時点で、ループが終了します。
select_statement
使用不可能な内部カーソルに関連付けられた問合せです。 構文はselect_into_statement
の構文と似ていますが、INTO
句は使用できません。 「SELECT INTO文」を参照してください。 PL/SQLは内部カーソルを自動的に宣言し、オープンし、データをフェッチしてクローズします。 select_statement
は独立した文ではないため、暗黙カーソルSQL
は適用されません。
while_loop_statement
WHILE-LOP
文は、ブール式を、キーワードLOOP
とEND
LOOP
で囲まれた一連の文に関連付けます。 ループを反復する前に条件が評価されます。 式がTRUE
を戻す場合、一連の文が実行されてから、ループの先頭で制御が再開します。 式がFALSE
またはNULL
を戻す場合、ループは実行されず、制御は次の文に渡されます。
使用上の注意
EXIT
WHEN
文を使用すると、任意のループを途中で終了できます。 WHEN
句の中のブール式がTRUE
を戻す場合、ループはただちに終了します。
カーソルFOR
ループを終了すると、EXIT
文またはGOTO
文を使用してループを途中で終了した場合でも、カーソルは自動的にクローズされます。 ループの内側で例外が呼び出された場合も、カーソルは自動的にクローズされます。
関連トピック