知识点:简单循环,WHILE 循环,数值型 FOR 循环,CONTINUE 语句以及嵌套循环等。PL/SQL 有四种类型的循环:简单循环、WHILE 循环、FOR 循环以 及游标 FOR 循环。本章会讨论前三种循环,并学习 Oracle 11g 中所引入的 CONTINUE 和 CONTINUE  WHEN 语句,以及循环的嵌套使用。 

1、loop循环的使用

1.1    简单循环loop的使用

       简单循环,就像其名称一样,是一种最基本的循环。 简单循环语句结构:

loop
    Statement 1;--循环语句
    Statement 2;
    ……
    Statement n;
end loop;

语法中:

        loop 是保留字,标识简单循环的开始。Statement_1 到 Statement_n 是循环体内容,也就是需要反复执行的语句。这些语句由一个或者多个结构语句组成。end loop 是表示循环结构结束的保留字。

       循环结构运行时,循环体内语句执行完一遍后,程序将再次执行循环体结构最开始的语句,并将无限制地执行,因为没有语句指定何时循环会终止。因此,简单循环称为无穷循环,因为无法退出这个循环。正确构造的循环需要退出条件,退出条件决定循环在何种情况下终止。退出条件有两种形式:EXIT 和 EXIT WHEN。接下来我们来了解这两种形式。

示例练习1:使用简单loop循环,输出语句

declare
    v_num1 int := 0 ; --声明一个变量,设置初始值是0
begin  
    loop
        v_num1 := v_num1 + 1; 
        dbms_output.put_line( '这是第' || v_num1 || '遍,输出');
    end loop;    
end;

输出结果演示:

postgre 循环执行SQL pl sql for循环_loop循环的使用

结果说明:在使用简单loop输出时,提示错误:“ORA-20000: ORU-10027: buffer overflow, limit of 10000 bytes”,

错误出现的原因:因为在sqlplus下,如果set serveroutput on此时就会用dbms_output将相关的信息打印到屏幕上,如果sqlplus登录环境没有设置buffer的大小,默认情况下是10000,将打印打开也同时赋予10000的buffer,如果输出超过这个值,则会报以上错误!

解决办法:设置更大的buffer值,最大支持1000000!或者在begin后面加上DBMS_OUTPUT.ENABLE(buffer_size => null); ,表示输出buffer不受限制(慎用此方法,容易造成系统崩溃)。。 

1.2    在loop循环中加入exit

       exit 表示退出。在 LOOP 循环中可以添加 if 语句,当 if 语句判断为 true 时,使用 exit (退出)。

示例练习2:使用 exit 控制简单loop循环,输出5遍“大家好,才是真的好”

输出结果:

postgre 循环执行SQL pl sql for循环_oracle中的循环_02

实现代码:

declare
    v_num1 int := 0 ; --声明一个变量,设置初始值是0
begin  
    loop
      v_num1 := v_num1 + 1; 
      if v_num1 > 5 then 
         exit;
      end if;
      dbms_output.put_line( '这是第' || v_num1 || '遍:大家好,才是真的好!');
    end loop;    
end;

 

1.3    带有 exit  when 条件的loop循环

       exit when 语句是 exit 语句的升级版。只有当 exit when 语句条件的计算结果为 true 时,才会终止循环。然后,执行权会转到 end loop  语句之后的第一条可执行语句。

示例练习3:使用 exit  when控制简单loop循环,输出5遍“大家好,才是真的好”

实现代码:

declare
    v_num1 int := 0 ; --声明一个变量,设置初始值是0
begin  
    loop
        v_num1 := v_num1 + 1; 
        exit when v_num1 > 5;
        dbms_output.put_line( '这是第' || v_num1 || '遍:大家好,才是真的好!');
    end loop;    
end;

示例思考:示例2和示例3的两个代码之间有什么区别?注意分析语法结构。

 

1.4    带有 continue 条件的loop循环

       CONTINUE 语句会导致循环终止当前迭代,需要借助于 IF 语句来计算 CONTINUE 条件。当 if 条件为 TRUE 时,开始执行continue,开始执行该循环的下一次迭代。

示例练习4:使用 continue控制loop,输出5遍“大家好,才是真的好”(第3遍不输出)

实现代码:

declare
    v_num1 int := 0 ; --声明一个变量,设置初始值是0
begin  
    loop
      v_num1 := v_num1 + 1; 
      if v_num1 = 3 then 
         continue;
      end if;
      exit when v_num1 > 5 ;
      dbms_output.put_line( '这是第' || v_num1 || '遍:大家好,才是真的好!');
    end loop;    
end;

输出结果:

postgre 循环执行SQL pl sql for循环_oracle中的循环_03

 

1.5    带有 continue  when 条件的loop循环

       与 EXIT WHEN 语句一样,使 CONTINUE 语句不与 IF 语句组合使用,而是独立构成一个完整的语意体。只有当 CONTINUE WHEN 条件为 TRUE 时,CONTINUE WHEN 语句会终止当前循环迭代,并开始循环的下一次迭代,也就是执行循环体中第一条可执行语句。

示例练习5:使用 continue when控制loop,输出5遍“大家好,才是真的好”(第3遍不输出)

实现代码:

declare
    v_num1 int := 0 ; --声明一个变量,设置初始值是0
begin  
    loop
      v_num1 := v_num1 + 1;       
      continue when v_num1 = 3;      
      exit when v_num1 > 5 ;
      dbms_output.put_line( '这是第' || v_num1 || '遍:大家好,才是真的好!');
    end loop;    
end;

示例思考:示例4和示例5的两个代码之间有什么区别?注意分析语法结构。

注意:EXIT、EXIT WHEN、CONTINUE 和 CONTINUE WHEN 只有处于循环中才有效,当位于循环之外将会出现语法错误。

 

示例练习6:使用 loop 循环,输出100以内的偶数合

实现代码:

declare
    v_num int := 0 ; --声明一个变量v_num,作为循环变量
    v_sum int := 0;  --声明一个变量v_sum,用来存储求和的结果
begin  
    loop
      v_num := v_num + 1;       
      continue when mod(v_num ,2) != 0;  --mod(m,n)函数,返回m除以n的余数,如果n是0,返回m
      v_sum := v_sum + v_num ;      
      exit when v_num > 99 ;
    end loop;    
      dbms_output.put_line( '100以内的偶数合是:' || v_sum);
end;

代码分析:使用mod(m,n)函数来判断奇偶数,mod(m,n)函数返回m除以n的余数,如果n是0,返回m。

输出结果:100以内的偶数合是:2550

示例延伸:案例6中使用的是exit when 和continue when实现的,试着使用exit、continue来实现此案例。

 

2、while循环的使用

WHILE 循环结构语法:

while condition loop
    Statement 1;
    Statement 2;
    ……
    Statement n;
end loop;

语法说明:

  • 保留字 WHILE 标识循环结构的开始。
  • condition 是本循环的测试条件,结果为 TRUE 或者FALSE。测试结果决定是否执行本循环。
  • Statement 语句 1〜n 是重复执行的语句,
  • END LOOP 是标识循环结构结束的保留字。

        如果测试条件的计算结果是 TRUE,则会执行循环体内容,执行完后,执行权会被转到while 循环的顶部,进行判断测试条件。如果测试条件的计算结果为 FALSE,则循环会终止, 执行权转到本循环后面的第一条可执行语句。

示例练习7:使用 while 循环,输出100以内的整数合

实现代码:

declare
    v_num int := 0 ; --声明一个变量v_num,作为循环变量
    v_sum int := 0; --声明一个变量v_sum,用来存储求和的结果
begin  
    while v_num < 100 loop
      v_num := v_num + 1;       
      v_sum := v_sum + v_num ;      
    end loop;    
      dbms_output.put_line( '100以内的整数合是:' || v_sum);
end;

输出结果:100以内的整数合是:5050

 

3、数值型for循环的使用

       数值型 FOR 循环之所以被称为数值型,原因在于它需要一个整数作为自己的终止值。 其结构语法:

FOR loop_counter IN [REVERSE] lower_limit .. upper_limit  LOOP
    Statement 1;
    Statement 2;
    ……
    Statement n;
END LOOP;

语法说明:

  • 保留字 FOR 标识 FOR 循环结构的开始。
  • 双点号(..)是范围操作符。注意:lower_limit 和 upper_limit 必须是两个整数数字或结果为整数的表达式。当计数器的值小于下限值lower_limit 或者当计数器的值大于上限值 upper_limit,程序将终止 FOR循环。
  • END LOOP 是标识 循环结构结束的保留字。
  • 变量 loop_counter 称为循环计数器,是隐含定义的索引变量。没有必要在 PL/SQL 语句块的声明部分定义循环计数器。这个变量是循环结构定义的。默认情况下计数器的值会循环递增,当在循环中使用 reverse 关键字时,计数器的值会随循环递减。

示例练习8:使用 for 循环,输出1到5

实现代码:

postgre 循环执行SQL pl sql for循环_postgre 循环执行SQL_04

代码说明:i 即循环计数器,不需要定义类型,默认为整数类型。IN 关键字表示循环计数器 i 从下限值增长到上限值。

输出结果:

postgre 循环执行SQL pl sql for循环_循环结构_05

将代码改动:如果使用 in reverse

declare

begin  
    for i in reverse 1 .. 5   loop
      dbms_output.put_line(  i );    
    end loop;   
end;

代码说明:如果使用 IN REVERSE 则正好相反,循环计数器 i 则从上限值减小到下限值。

输出结果:

postgre 循环执行SQL pl sql for循环_循环结构_06

说明:下限值必须小于上限值,也就是说,下限值必须在上限值前面,例如 1..5。任何时候都不能反过来书写。否则,得不到结果。

 

4、嵌套循环

       我们已经学习过了三种类型的循环:简单循环、WHILE 循环以及数值型 FOR 循环。其中任何一种循环都可以嵌套在其他循环体中。例如,简单循环可以嵌套在 WHILE 循环中,也可以反过来。

示例练习9:使用 嵌套 循环,输出由*组成的3行5列的矩形

实现代码:

declare

begin  
    --这里是外层循环开始,外层循环控制行数
    for i in  1 .. 3 loop
      --这里是内层循环开始,内层循环控制列数  
      for j in 1 .. 5 loop
          dbms_output.put( '*' );--在内层循环里用loop循环输出每一列的内容    
      end loop; --内层循环结束
      dbms_output.put_line( '' );
    end loop;
      
end;

输出结果:

postgre 循环执行SQL pl sql for循环_循环结构_07

案例延伸:使用嵌套循环,输出九九乘法表、输出等腰三角形……