目录
一、简单循环
1.1LOOP 循环语法:
1.2LOOP 循环示例
二、for循环
2.1for循环语法:
2.2for循环示例
三、while循环
3.1while循环语法
3.2while循环示例
四、GOTO 循环
4.1GOTO 循环语法
4.2GOTO 循环示例
在 Oracle 数据库中,提供了多种循环类型用于实现不同的业务逻辑需求。我们可以使用 PL/SQL 中的循环语句来实现反复执行一段代码块的目的。PL/SQL 是一种过程化语言,提供了完善的控制流结构,支持多种循环形式。下面介绍一些常用的循环语句及其语法和示例。
一、简单循环
之所以会被叫做简单循环:因为它仅是以LOOP关键字开始,以END LOOP语句结束。要靠循环体内的EXIT、EXIT WHEN或者RETURN来退出循环(或者有异常抛出)。这种循环为LOOP 循环,是一种无限循环,它会反复执行一个语句块,直到遇到 BREAK 语句为止。LOOP 循环在程序中也通常用于等待某个条件变为真时再退出循环,或者在处理数据集合时用来查找某个特定的记录。
1.1LOOP 循环语法:
LOOP 循环的语法如下:
LOOP
-- statements to be executed
EXIT [WHEN condition];
END LOOP;
--简单理解为:
loop
要执行的语句; ┐
exit when 退出条件; ├循环体
[要执行的语句;] ┘
end loop;
EXIT
是一个可选关键字,可以用来指定跳出循环的条件;condition
是一个布尔表达式,当其值为 TRUE 时会导致循环退出。
1.2LOOP 循环示例
下面就是使用 LOOP 循环的一些示例
示例1.循环打印1-10,代码如下:
declare
v1 number:=0;
begin
loop
v1:=v1+1;
dbms_output.put_line(v1);
exit when v1=10;
end loop;
end;
输出结果如下:
示例2.循环打印1-10的和,代码如下:
declare
v1 number:=1;--自增
v2 number:=0;--求和
begin
loop
v2:=v2+v1;
dbms_output.put_line(v2);
exit when v1=10;
v1:=v1+1;
end loop;
end;
输出结果如下:
示例3.只打印1-10的和,代码如下:
declare
v1 number:=1;--自增
v2 number:=0;--求和
begin
loop
v2:=v2+v1;
exit when v1=10;
v1:=v1+1;
end loop;
dbms_output.put_line(v2);
end;
输出如下:
示例4. 不换行打印1-10,代码如下:
declare
v1 number:=0;
begin
loop
v1:=v1+1;
dbms_output.put(v1||',');
exit when v1=10;
end loop;
dbms_output.put_line('');
end;
输出结果如下:
示例5.循环打印1+2+3+4...+10=55这个式子,代码如下:
declare
v1 number:=1;--自增
v2 number:=0;--求和
begin
loop
v2:=v2+v1; --求和
dbms_output.put(v1||'+');
v1:=v1+1;--自增
exit when v1=10;--退出
end loop;
dbms_output.put_line(v1||'='||(v2+v1));
end;
输出结果如下:
示例6.读取一张表中所有员工记录,代码如下:
DECLARE
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
v_job emp.job%TYPE;
v_mgr emp.mgr%TYPE;
v_hiredate emp.hiredate%TYPE;
v_sal emp.sal%TYPE;
v_comm emp.comm%TYPE;
v_deptno emp.deptno%TYPE;
CURSOR c_emp IS SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno
FROM emp;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO v_empno, v_ename, v_job, v_mgr, v_hiredate, v_sal, v_comm, v_deptno;
EXIT WHEN c_emp%NOTFOUND;
-- 在这里可以对每个员工记录进行处理,例如打印或者插入到另一个表中等操作
DBMS_OUTPUT.PUT_LINE('empno=' || v_empno || ', ename=' || v_ename || ', job=' || v_job || ', mgr=' || v_mgr || ', hiredate=' || v_hiredate || ', sal=' || v_sal || ', comm=' || v_comm || ', deptno=' || v_deptno);
END LOOP;
CLOSE c_emp;
END;
上述代码我创建了一个名为 c_emp 的游标,该游标从 emp 表中选择所有员工记录。要知道游标是会遍历表所有行,然后我使用 LOOP 循环和 FETCH 语句来逐行读取游标中的数据,并将其存储到变量中。在每次循环迭代时,我可以对每个员工记录进行处理,例如打印或者插入到另一个表中等操作。最后,我再通过 CLOSE 语句关闭了游标。这里需要注意,使用游标时需要进行显式地打开和关闭操作。下图是输出结果:
示例7.打印九九乘法表,代码如下:
第一种格式对齐代码如下:
begin
Dbms_Output.put_line('九九乘法表');
for i in 1..9 loop
for j in 1..i loop
dbms_output.put(j||'*'||i||'='|| lpad(i*j,2,0)||' ');
end loop;
dbms_output.put_line('');
end loop;
end;
输出结果如下:
第二种代码如下:
declare
i int:=1;
j int:=1;
begin
loop
loop
Dbms_Output.put(i||'*'||j||'='||i*j);
dbms_output.put(' ');
j:=j+1;
exit when j>i;
end loop;
dbms_output.put_line('');
i:=i+1;
j:=1;
exit when i>9;
end loop;
end;
输出结果如下:
二、for循环
FOR 循环是一种最常见的循环形式,在固定范围内反复执行某些操作,在程序中通常用于遍历一个数据集合或执行指定次数的操作。
2.1for循环语法:
FOR loop_counter IN [REVERSE] low_value..high_value LOOP
-- statements to be executed
END LOOP;
--简单理解v:
for 变量 in [reverse]小值..大值 loop --(两值之间要有两个点,不能多不能少)
要执行的语句;
[exit when 中途退出的条件;]
end loop;
·加上reverse是从大值循环到小值
其中,loop_counter
为循环计数器,它可以是任何用户定义的变量或标识符;low_value
和 high_value
表示循环计数器的起始值和终止值;REVERSE
为可选关键字,表示倒序循环。
2.2for循环示例
示例1.循环打印1-10,代码如下:
begin
for i in 1..10 loop
dbms_output.put_line(i);
end loop;
end;
输出结果如下:
示例2.循环打印1+2+3+4...+10=55这个式子,代码如下:
declare
v2 int:=0;
begin
for a in 1..9 loop
v2:=v2+a;
dbms_output.put(a||'+');
end loop;
dbms_output.put_line('10='||(v2+10));
end;
输出结果如下:
示例3.打印直角三角形,如下图所示,
代码如下:
begin
for i in 1..5 loop--控制层数
for j in 1..i loop--控制每一层的星数
dbms_output.put('* ');
end loop;
dbms_output.put_line('');
end loop;
end;
输出结果和上图一致。
示例4.打印九九乘法表,代码如下:
begin
for i in 1..9 loop
for j in 1..i loop
dbms_output.put(j||'×'||i||'='||j*i||' ');
end loop;
dbms_output.put_line('');
end loop;
end;
输出结果如下:
三、while循环
WHILE 循环是一种基于条件表达式的循环结构,只要条件表达式的结果为 TRUE,则会一直执行循环内的语句,直到条件变为 FALSE 才停止循环。也就是说它会根据指定条件重复执行某一段代码,直到条件不成立为止。
3.1while循环语法
其基本语法如下:
WHILE condition LOOP
-- statements to be executed
END LOOP;
--简单理解v:
while 条件 --进入循环的条件
loop
要执行的语句;
[exit when 退出条件;]--中途退出的条件
end loop;
其中,condition
是一个布尔表达式,当其值为 TRUE 时会执行循环内的语句。
3.2while循环示例
示例1.循环打印1-10,代码如下:
declare
v1 int:=1;
begin
while v1<=10 loop
dbms_output.put_line(v1);
--exit when v1=5;
v1:=v1+1;
end loop;
end;
输出结果如下:
示例2.循环打印1+2+3+4...+10=55这个式子,代码如下:
declare
v1 int:=1;
v2 int:=0;
begin
while v1<10 loop
v2:=v2+v1;
dbms_output.put(v1||'+');
v1:=v1+1;
end loop;
dbms_output.put_line('10='||(v2+v1));
end;
输出结果如下:
示例3.打印九九乘法表,代码如下:
declare
i int:=1;
j int:=1;
begin
while i<=9 loop j:=1;
while j<=i loop
Dbms_Output.put(i||'*'||j||'='||i*j);
dbms_output.put(' ');
j:=j+1;
end loop;
dbms_output.new_line;
i:=i+1;
end loop;
end;
输出结果如下:
四、GOTO 循环
GOTO 循环是一种标签控制形式,是一种无条件转移语句,用于跳转到程序中的指定标签位置。在指定标签前置了符号“:”后,通过 GOTO+标签名 的方式实现循环。
4.1GOTO 循环语法
其基本语法如下:
<<label>>
WHILE condition LOOP
statement;
[EXIT | EXIT WHEN condition];
-- 跳转至标签位置
GOTO label;
END LOOP;
其中 label 是循环名称,condition 和 statement 同 WHILE 循环的定义。如果要退出循环,可以使用 BREAK 语句或者在 loop 开始位置放置 EXIT 语句。
4.2GOTO 循环示例
示例1.循环打印1到10,代码如下:
DECLARE
i NUMBER := 1;
BEGIN
<<my_loop>> -- 声明标记名称my_loop
IF i <= 10 THEN
DBMS_OUTPUT.PUT_LINE(i);
i := i + 1;
GOTO my_loop; -- 跳转到标记名称为my_loop的位置
END IF;
END;
输出结果如下:
示例2.打印九九乘法表,代码如下:
DECLARE
i NUMBER := 1;
j NUMBER := 1;
BEGIN
<<my_loop1>> -- 标记名称为 my_loop1
IF i <= 9 THEN
<<my_loop2>> -- 标记名称为 my_loop2
IF j <= i THEN
DBMS_OUTPUT.PUT(i || '*' || j || '=' || i*j || ' ');
j := j + 1;
GOTO my_loop2; -- 转移到标记名称为 my_loop2 的位置
ELSE
DBMS_OUTPUT.NEW_LINE; -- 换行
j := 1;
i := i + 1;
GOTO my_loop1; -- 转移到标记名称为 my_loop1 的位置
END IF;
END IF;
END;
日常情况使用goto循环的情况会比较少,我解释下上面的代码:在上述代码中,首先初始化变量 i
和 j
并声明两个标记名称 my_loop1
和 my_loop2
。然后,在第一层循环中,检查 i
的值是否小于等于 9。如果是,则进入第二层循环,检查 j
的值是否小于等于 i
。如果是,则使用 DBMS_OUTPUT.PUT_LINE 函数输出乘法表的一项,并将变量 j
加 1。接着使用 GOTO 语句跳转到第二层循环的最开始位置(即标记名称为 my_loop2
的地方),继续执行乘法表循环。如果 j
的值大于 i
,则输出一个空行,并将变量 j
重置为 1,将 i
加 1。然后使用 GOTO 语句跳转到第一层循环的最开始位置(即标记名称为 my_loop1
的地方),继续执行乘法表循环。
最后输出结果如下:
注意:
GOTO 循环是基于 PL/SQL 语言的特性,在 Oracle 数据库的多个版本中都支持。
具体地说,GOTO 循环是在 Oracle Database 11g Release 2 和之后版本中引入的新特性。 如果使用的是 Oracle 数据库较老的版本,可能不支持该特性。
虽然使用 GOTO 可以实现类似于循环的功能,但是它也可能会影响代码的可读性和维护性,代码设计时应优先考虑使用更好的循环结构方式(如WHILE循环、FOR循环等)来实现控制流程。同时,为了提高代码执行效率,应当尽量避免在PL/SQL中过度使用 GOTO 语句。
在PL/SQL中,GO和CONTINUE语句可以使用类似的方式来实现迭代。通常情况下,使用带有明确退出条件的循环比使用GOTO更容易理解和调试。