ループ文は、特定の操作を繰り返し実行するために主に使用されます。
適用対象
この内容は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 ];
condition の値が TRUE である限り、ループは condition の値が 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