循环语句

简单LOOP语句

语法图

图 1 loop::=
循环语句 - 图1

示例

  1. CREATE OR REPLACE PROCEDURE proc_loop(i in integer, count out integer)
  2. AS
  3. BEGIN
  4. count:=0;
  5. LOOP
  6. IF count > i THEN
  7. raise info 'count is %. ', count;
  8. EXIT;
  9. ELSE
  10. count:=count+1;
  11. END IF;
  12. END LOOP;
  13. END;
  14. /
  15. CALL proc_loop(10,5);

循环语句 - 图2 须知:

该循环必须要结合EXIT使用,否则将陷入死循环。

WHILE_LOOP语句

语法图

图 2 while_loop::=
循环语句 - 图3

只要条件表达式为真,WHILE语句就会不停的在一系列语句上进行循环,在每次进入循环体的时候进行条件判断。

示例

  1. CREATE TABLE integertable(c1 integer) ;
  2. CREATE OR REPLACE PROCEDURE proc_while_loop(maxval in integer)
  3. AS
  4. DECLARE
  5. i int :=1;
  6. BEGIN
  7. WHILE i < maxval LOOP
  8. INSERT INTO integertable VALUES(i);
  9. i:=i+1;
  10. END LOOP;
  11. END;
  12. /
  13. --调用函数
  14. CALL proc_while_loop(10);
  15. --删除存储过程和表
  16. DROP PROCEDURE proc_while_loop;
  17. DROP TABLE integertable;

FOR_LOOP(integer变量)语句

语法图

图 3 for_loop::=
循环语句 - 图4

循环语句 - 图5 说明:

  • 变量name会自动定义为integer类型并且只在此循环里存在。变量name介于lower_bound和upper_bound之间。
  • 当使用REVERSE关键字时,lower_bound必须大于等于upper_bound,否则循环体不会被执行。

FOR_LOOP查询语句

语法图

图 4 for_loop_query::=
循环语句 - 图6

循环语句 - 图7 说明:

变量target会自动定义,类型和query的查询结果的类型一致,并且只在此循环中有效。target的取值就是query的查询结果。

FORALL批量查询语句

语法图

图 5 forall::=
循环语句 - 图8

循环语句 - 图9 说明:

  • 变量index会自动定义为integer类型并且只在此循环里存在。index的取值介于low_bound和upper_bound之间。
  • 如果声明了SAVE EXCEPTIONS,则会将循环体DML执行过程中每次遇到的异常保存在SQL&BULK_EXCEPTIONS中,并在执行结束后统一抛出一个异常,循环过程中没有异常的执行的结果在当前子事务内不会回滚。

示例

  1. CREATE TABLE hdfs_t1 (
  2. title NUMBER(6),
  3. did VARCHAR2(20),
  4. data_period VARCHAR2(25),
  5. kind VARCHAR2(25),
  6. interval VARCHAR2(20),
  7. time DATE,
  8. isModified VARCHAR2(10)
  9. );
  10. INSERT INTO hdfs_t1 VALUES( 8, 'Donald', 'OConnell', 'DOCONNEL', '650.507.9833', to_date('21-06-1999', 'dd-mm-yyyy'), 'SH_CLERK' );
  11. CREATE OR REPLACE PROCEDURE proc_forall()
  12. AS
  13. BEGIN
  14. FORALL i IN 100..120
  15. update hdfs_t1 set title = title + 100*i;
  16. END;
  17. /
  18. --调用函数
  19. CALL proc_forall();
  20. --查询存储过程调用结果
  21. SELECT * FROM hdfs_t1 WHERE title BETWEEN 100 AND 120;
  22. --删除存储过程和表
  23. DROP PROCEDURE proc_forall;
  24. DROP TABLE hdfs_t1;

LABEL_LOOP语句

语法格式

  1. [label_begin:] LOOP
  2. statements
  3. END LOOP [label_end]

循环语句 - 图10说明:

在简单loop语句的基础上增加了label标签的用法,标签规则如下:

  • label_begin可以单独出现(不加label_end),但是使用label_end,就必须有与之相同的label_begin。
  • 标签可以被continue或exit语句引用,特别的是,在数据库模式为’B’时,也可用iterate或leave语句。

循环语句 - 图11 须知:

该循环只在数据库兼容模式为’B’时使用,其他模式下报错。必须要结合EXIT使用(’B‘模式下可使用’LEAVE‘,与EXIT效果相同;’B‘模式下可使用’ITERATE’,与CONTINUE效果相同),否则将陷入死循环。

示例

  1. CREATE OR REPLACE PROCEDURE label_loop(i in integer, count out integer)
  2. AS
  3. BEGIN
  4. count:=0;
  5. label:
  6. LOOP
  7. IF count > i THEN
  8. raise info 'count is %. ', count;
  9. LEAVE;
  10. ELSE
  11. count:=count+1;
  12. END IF;
  13. END LOOP label;
  14. END;
  15. /
  16. CALL proc_loop(10,5);

WHILE_DO语句

语法格式

  1. [label_begin:] WHILE condition DO
  2. statements
  3. END WHILE [label_end]

循环语句 - 图12 说明:

只要条件表达式为真,WHILE语句就会不停的在一系列语句上进行循环,在每次进入循环体的时候进行条件判断。

标签规则如下:

  • label_begin可以单独出现(不加label_end),但是使用label_end,就必须有与之相同的label_begin。
  • 标签可以被continue或exit语句引用,特别的是,在数据库模式为’B’时,也可用iterate或leave语句。

循环语句 - 图13 须知: 该循环只在数据库兼容模式为’B’时使用,其他模式下报错。

示例

  1. create or replace procedure while_test()
  2. as
  3. declare _i integer = 0;
  4. BEGIN
  5. the_while:
  6. while _i < 10 do
  7. _i := _i + 1;
  8. continue the_while when _i % 2 = 0;
  9. raise notice '%', _i;
  10. end while the_while;
  11. end;
  12. /
  13. select while_test();

REPEAT语句

语法格式

  1. [label_begin:] REPEAT
  2. statements
  3. UNTIL condition
  4. END REPEAT [label_end]

循环语句 - 图14 说明:

只要条件表达式为真,WHILE语句就会停止在一系列语句上进行循环,在每次进入循环体的时候进行条件判断。

标签规则如下:

  • label_begin可以单独出现(不加label_end),但是使用label_end,就必须有与之相同的label_begin。
  • 标签可以被continue或exit语句引用,特别的是,在数据库模式为’B’时,也可用iterate或leave语句。

循环语句 - 图15 须知: 该循环只在数据库兼容模式为’B’时使用,其他模式下报错。

示例

  1. CREATE or replace PROCEDURE dorepeat(p1 INT)
  2. as
  3. declare
  4. i int =0;
  5. BEGIN
  6. label:
  7. repeat
  8. i = i + 1;
  9. until i >p1 end repeat label;
  10. raise notice '%',i;
  11. end;
  12. /