循环语句主要用于反复执行一段操作,有以下几种形式:
基本 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 的语句结构如下:
[ label ] LOOP
statements
END LOOP [ label ];
使用 LOOP 循环语句,statements 语句会循环执行。为了避免死循环,LOOP 和 END LOOP 之间的语句中,至少要有一个语句包含 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 (0.03 sec)
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 (0.03 sec)
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 (0.03 sec)
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 (0.03 sec)
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 会从 lower_bound 递减至 upper_bound。
obclient> BEGIN
-> FOR i IN 1..5 LOOP
-> DBMS_OUTPUT.PUT_LINE (i);
-> END LOOP;
-> END;
-> /
Query OK, 0 rows affected (0.03 sec)
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 (0.03 sec)
5
4
3
2
1
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.02 sec)
0
1
2