ループ文は、一連の操作を繰り返し実行するために主に使用されます。
適用対象
この内容はOceanBaseデータベースEnterprise Editionにのみ適用されます。OceanBaseデータベースCommunity EditionはMySQLモードのみを提供します。
LOOP 文には、以下の4種類の形式があります:
基本
LOOPFOR LOOPカーソル用
FOR LOOPWHILE LOOP
ループ全体からの終了を宣言するには、以下の2種類の形式があります:
EXITEXIT WHEN
現在のループからの終了を宣言するには、以下の2種類の形式があります:
CONTINUECONTINUE WHEN
EXIT、EXIT WHEN、CONTINUE、および CONTINUE WHEN はループの終了に使用され、ループ内の任意の場所に配置できます。これらはループを終了するための推奨される方法であり、GOTO ステートメントを使用してループを終了する方法は避けてください。EXIT ステートメントは制御を LOOP の終了点に移します。CONTINUE ステートメントはループの現在の反復を終了し、次の反復の開始点に制御を移します。EXIT と CONTINUE はどちらもオプションの WHEN 句を伴うことができ、そこで終了条件を指定できます。
複数層のネストされたループの場合、ループにラベルを付けることを推奨します。これにより、可読性が向上します。
基本 LOOP
基本的な LOOP 文は、一連のステートメントを繰り返し実行します。基本的な LOOP の構文は以下のとおりです:
[ label ] LOOP
statements
END LOOP [ label ];
LOOP ループステートメントを使用すると、statements ステートメントが繰り返し実行されます。無限ループを避けるために、LOOP と END LOOP の間のステートメントのうち、少なくとも1つは EXIT ステートメントを含む必要があります。そうでない場合、LOOP ステートメントは永遠に繰り返され、停止しません。
EXIT ステートメントにはオプションの WHEN 句を付けることができ、条件が TRUE の場合に EXIT ステートメントを実行し、制御を END LOOP ステートメント以降にジャンプさせることを示します。
EXIT ステートメント
EXIT ステートメントは、現在のループを無条件で終了させることを示します。
例:
obclient> DECLARE
cnt NUMBER := 0;
BEGIN
LOOP
DBMS_OUTPUT.PUT_LINE ('INSIDE: ' || TO_CHAR(cnt));
cnt := cnt + 1;
IF cnt > 5 THEN
EXIT;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('OUTSIDE: ' || TO_CHAR(cnt));
END;
/
Query OK, 0 rows affected
INSIDE: 0
INSIDE: 1
INSIDE: 2
INSIDE: 3
INSIDE: 4
INSIDE: 5
OUTSIDE: 6
EXIT WHEN ステートメント
WHEN 句の条件が TRUE の場合、EXIT WHEN ステートメントは現在のループを終了させるために使用されます。
例:
obclient> DECLARE
cnt NUMBER := 0;
BEGIN
LOOP
DBMS_OUTPUT.PUT_LINE ('INSIDE: ' || TO_CHAR(cnt));
cnt := cnt + 1;
EXIT WHEN cnt >5;
END LOOP;
DBMS_OUTPUT.PUT_LINE('OUTSIDE: ' || TO_CHAR(cnt));
END;
/
Query OK, 0 rows affected
INSIDE: 0
INSIDE: 1
INSIDE: 2
INSIDE: 3
INSIDE: 4
INSIDE: 5
OUTSIDE: 6
CONTINUE ステートメント
CONTINUE ステートメントは、現在のループを終了させるために使用され、CONTINUE からループ終了までのコードをスキップし、ループの先頭から次のループを続行します。
obclient> DECLARE
cnt NUMBER := 0;
BEGIN
LOOP
cnt := cnt + 1;
IF cnt < 4 THEN
CONTINUE;
END IF;
DBMS_OUTPUT.PUT_LINE ('INSIDE: ' || TO_CHAR(cnt));
EXIT WHEN cnt >5;
END LOOP;
DBMS_OUTPUT.PUT_LINE('OUTSIDE: ' || TO_CHAR(cnt));
END;
/
Query OK, 0 rows affected
INSIDE: 4
INSIDE: 5
INSIDE: 6
OUTSIDE: 6
CONTINUE WHEN ステートメント
CONTINUE WHEN ステートメントも現在のループを終了させるために使用されますが、WHEN 句が TRUE の場合にのみ実行されます。
例:
obclient>DECLARE
cnt NUMBER := 0;
BEGIN
LOOP
cnt := cnt + 1;
CONTINUE WHEN cnt < 4;
DBMS_OUTPUT.PUT_LINE ('INSIDE: ' || TO_CHAR(cnt));
EXIT WHEN cnt >5;
END LOOP;
DBMS_OUTPUT.PUT_LINE('OUTSIDE: ' || TO_CHAR(cnt));
END;
/
Query OK, 0 rows affected
INSIDE: 4
INSIDE: 5
INSIDE: 6
OUTSIDE: 6
FOR LOOP ステートメント
FOR LOOP は、インデックス値の範囲に対して、一連のコードを繰り返し実行します。構文は以下のとおりです:
[ label ] FOR index IN [ REVERSE ] lower_bound..upper_bound LOOP
statements
END LOOP [ label ];
以下の例のように、REVERSE 句を指定しない場合、index は lower_bound から upper_bound へと増加します。REVERSE 句を使用すると、index は upper_bound から lower_bound へと減少します。
obclient> BEGIN
FOR i IN 1..5 LOOP
DBMS_OUTPUT.PUT_LINE (i);
END LOOP;
END;
/
Query OK, 0 rows affected
1
2
3
4
5
obclient>BEGIN
FOR i IN REVERSE 1..5 LOOP
DBMS_OUTPUT.PUT_LINE (i);
END LOOP;
END;
/
Query OK, 0 rows affected
5
4
3
2
1
FOR LOOP ステートメントのインデックスは、暗黙的にループローカルの PLS_INTEGER 型変数として宣言されます。ループ内のステートメントはインデックスの値を読み取ることができますが、変更することはできません。ループ外のステートメントはインデックスを参照することができません。FOR LOOP ステートメントの実行後、インデックスは未定義の状態です。ループインデックスは、ループカウンターと呼ばれることもあります。
FOR LOOP ステートメントの上下限は、数値テキスト、数値変数、または数値式にすることができます。境界に数値がない場合、PLは事前定義された例外 VALUE_ERROR を発生させます。
WHILE LOOP ステートメント
WHILE LOOP は、別のループ制御の形式であり、条件の結果が TRUE の場合に一連のステートメントを繰り返し実行します。条件の結果が FALSE になると、ループは終了します。構文は以下のとおりです:
[ label ] WHILE condition LOOP
statements
END LOOP [ label ];
contidion の値が TRUE である限り、ループは contidion の値が FALSE または NULL になるまで続行されます。
obclient> DECLARE
cnt NUMBER := 0;
BEGIN
WHILE cnt < 3 LOOP
DBMS_OUTPUT.PUT_LINE (cnt);
cnt := cnt + 1;
END LOOP;
END;
/
Query OK, 0 rows affected
0
1
2