• 基本 LOOP

  • FOR LOOP

  • 用于游标的 FOR LOOP

  • WHILE LOOP

用于退出整个循环的声明包括:

  • EXIT

  • EXIT WHEN

  • CONTINUE

  • CONTINUE WHEN

EXIT, EXIT WHEN, CONTINUE 和 CONTINUE WHEN 用于退出循环,可以放置在循环中的任何位置。 这是推荐的退出循环的方法。 虽然 GOTO 同样可以退出循环,但要避免使用这种方式。 EXIT 语句会将控制转移到 LOOP 结束处; CONTINUE 语句会退出循环的当前迭代,并将控制转移到下次迭代开始处;EXIT 和 CONTINUE 都可以跟一个可选的 WHEN 子句,其中可以指定一个提交。

如果是多层的嵌套循环,推荐给循环打上标签,这样会增加可读性。

基本的 LOOP 语句会重复执行一序列语句。基本 LOOP 的语句结构如下:

使用 LOOP 循环语句,statements 语句会循环执行。为了避免死循环,LOOP 和 END LOOP 之间的语句中,至少要有一个语句包含 EXIT 语句;否则 LOOP 语句会一直重复永不停止。

EXIT 语句可以带一个可选的 WHEN 子句,表示当条件为 TRUE 的时候,执行 EXIT 语句并将控制跳转到的 END LOOP 语句后。

EXIT 语句

示例如下:

  1. -> cnt NUMBER := 0;
  2. -> BEGIN
  3. -> LOOP
  4. -> DBMS_OUTPUT.PUT_LINE ('INSIDE: ' || TO_CHAR(cnt));
  5. -> cnt := cnt + 1;
  6. -> IF cnt > 5 THEN
  7. -> EXIT;
  8. -> END IF;
  9. -> END LOOP;
  10. -> DBMS_OUTPUT.PUT_LINE('OUTSIDE: ' || TO_CHAR(cnt));
  11. -> END;
  12. -> /
  13. Query OK, 0 rows affected (0.03 sec)
  14. INSIDE: 0
  15. INSIDE: 2
  16. INSIDE: 3
  17. INSIDE: 4
  18. INSIDE: 5
  19. OUTSIDE: 6

当 WHEN 字句的条件为 TRUE 时,EXIT WHEN 语句用于退出当前循环。示例如下:

  1. obclient> DECLARE
  2. -> cnt NUMBER := 0;
  3. -> BEGIN
  4. -> LOOP
  5. -> cnt := cnt + 1;
  6. -> EXIT WHEN cnt >5;
  7. -> END LOOP;
  8. -> DBMS_OUTPUT.PUT_LINE('OUTSIDE: ' || TO_CHAR(cnt));
  9. -> END;
  10. -> /
  11. Query OK, 0 rows affected (0.03 sec)
  12. INSIDE: 0
  13. INSIDE: 1
  14. INSIDE: 2
  15. INSIDE: 3
  16. INSIDE: 4
  17. INSIDE: 5
  18. OUTSIDE: 6

CONTINUE 语句

CONTINUE 语句用来退出本次循环, 即略过从 CONTINUE 开始直到循环结束的代码,从循环头开始继续下一次。

CONTINUE WHEN 语句同样是用于退出本次循环, 但只有在 WHEN 子句为 TRUE 的时候才会执行。

示例如下:

  1. obclient> DECLARE
  2. -> cnt NUMBER := 0;
  3. -> BEGIN
  4. -> LOOP
  5. -> cnt := cnt + 1;
  6. -> DBMS_OUTPUT.PUT_LINE ('INSIDE: ' || TO_CHAR(cnt));
  7. -> EXIT WHEN cnt >5;
  8. -> END LOOP;
  9. -> DBMS_OUTPUT.PUT_LINE('OUTSIDE: ' || TO_CHAR(cnt));
  10. -> /
  11. Query OK, 0 rows affected (0.03 sec)
  12. INSIDE: 4
  13. INSIDE: 5
  14. INSIDE: 6
  15. OUTSIDE: 6

FOR LOOP 语句

FOR LOOP 会针对一个索引值范围,循环执行一段代码。 语法如下:

  1. [ label ] FOR index IN [ REVERSE ] lower_bound..upper_bound LOOP
  2. statements
  3. END LOOP [ label ];

如下例所示,不加 REVERSE 子句时, index 会从 lower_bound 递增至 upper_bound;使用 REVERSE 子句时, index 会从 lower_bound 递减至 upper_bound。

  1. [ label ] WHILE condition LOOP
  2. statements
  3. END LOOP [ label ];

只要检测 contidion 值为 TRUE,循环就会继续,直至 contidion 值为 FALSE 或者 NULL 为止。

  1. obclient> DECLARE
  2. -> cnt NUMBER := 0;
  3. -> BEGIN
  4. -> WHILE cnt < 3 LOOP
  5. -> DBMS_OUTPUT.PUT_LINE (cnt);
  6. -> cnt := cnt + 1;
  7. -> END LOOP;
  8. -> END;
  9. -> /
  10. Query OK, 0 rows affected (0.02 sec)
  11. 0
  12. 2