ループ文は、特定の操作を繰り返し実行するために主に使用されます。
適用対象
この内容は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 の構文は以下のとおりです:
[ 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