知识点:简单循环,WHILE 循环,数值型 FOR 循环,CONTINUE 语句以及嵌套循环等。PL/SQL 有四种类型的循环:简单循环、WHILE 循环、FOR 循环以 及游标 FOR 循环。本章会讨论前三种循环,并学习 Oracle 11g 中所引入的 CONTINUE 和 CONTINUE WHEN 语句,以及循环的嵌套使用。
简单循环,就像其名称一样,是一种最基本的循环。 简单循环语句结构:
loop
Statement 1;--循环语句
Statement 2;
……
Statement n;
end loop;
语法中:
loop 是保留字,标识简单循环的开始。Statement_1 到 Statement_n 是循环体内容,也就是需要反复执行的语句。这些语句由一个或者多个结构语句组成。end loop 是表示循环结构结束的保留字。
循环结构运行时,循环体内语句执行完一遍后,程序将再次执行循环体结构最开始的语句,并将无限制地执行,因为没有语句指定何时循环会终止。因此,简单循环称为无穷循环,因为无法退出这个循环。正确构造的循环需要退出条件,退出条件决定循环在何种情况下终止。退出条件有两种形式:EXIT 和 EXIT WHEN。接下来我们来了解这两种形式。
declare
v_num1 int := 0 ; --声明一个变量,设置初始值是0
begin
loop
v_num1 := v_num1 + 1;
dbms_output.put_line( '这是第' || v_num1 || '遍,输出');
end loop;
end;
输出结果演示:
结果说明:在使用简单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不受限制(慎用此方法,容易造成系统崩溃)。。
exit 表示退出。在 LOOP 循环中可以添加 if 语句,当 if 语句判断为 true 时,使用 exit (退出)。
输出结果:
实现代码:
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;
exit when 语句是 exit 语句的升级版。只有当 exit when 语句条件的计算结果为 true 时,才会终止循环。然后,执行权会转到 end loop 语句之后的第一条可执行语句。
实现代码:
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的两个代码之间有什么区别?注意分析语法结构。
CONTINUE 语句会导致循环终止当前迭代,需要借助于 IF 语句来计算 CONTINUE 条件。当 if 条件为 TRUE 时,开始执行continue,开始执行该循环的下一次迭代。
实现代码:
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;
输出结果:
与 EXIT WHEN 语句一样,使 CONTINUE 语句不与 IF 语句组合使用,而是独立构成一个完整的语意体。只有当 CONTINUE WHEN 条件为 TRUE 时,CONTINUE WHEN 语句会终止当前循环迭代,并开始循环的下一次迭代,也就是执行循环体中第一条可执行语句。
实现代码:
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 只有处于循环中才有效,当位于循环之外将会出现语法错误。
实现代码:
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来实现此案例。
WHILE 循环结构语法:
while condition loop
Statement 1;
Statement 2;
……
Statement n;
end loop;
语法说明:
如果测试条件的计算结果是 TRUE,则会执行循环体内容,执行完后,执行权会被转到while 循环的顶部,进行判断测试条件。如果测试条件的计算结果为 FALSE,则循环会终止, 执行权转到本循环后面的第一条可执行语句。
实现代码:
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
数值型 FOR 循环之所以被称为数值型,原因在于它需要一个整数作为自己的终止值。 其结构语法:
FOR loop_counter IN [REVERSE] lower_limit .. upper_limit LOOP
Statement 1;
Statement 2;
……
Statement n;
END LOOP;
语法说明:
实现代码:
代码说明:i 即循环计数器,不需要定义类型,默认为整数类型。IN 关键字表示循环计数器 i 从下限值增长到上限值。
输出结果:
将代码改动:如果使用 in reverse
declare
begin
for i in reverse 1 .. 5 loop
dbms_output.put_line( i );
end loop;
end;
代码说明:如果使用 IN REVERSE 则正好相反,循环计数器 i 则从上限值减小到下限值。
输出结果:
说明:下限值必须小于上限值,也就是说,下限值必须在上限值前面,例如 1..5。任何时候都不能反过来书写。否则,得不到结果。
我们已经学习过了三种类型的循环:简单循环、WHILE 循环以及数值型 FOR 循环。其中任何一种循环都可以嵌套在其他循环体中。例如,简单循环可以嵌套在 WHILE 循环中,也可以反过来。
实现代码:
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;
输出结果:
案例延伸:使用嵌套循环,输出九九乘法表、输出等腰三角形……
=========这里是结束分割线======