Oracle23ai新特性FOR LOOP循环控制结构增强
在Oracle数据库中,FOR LOOP
是一种常用的循环控制结构,它允许你重复执行一系列语句固定次数或直到满足特定条件为止。然而,标准的Oracle PL/SQL中的FOR LOOP
主要用于遍历集合(如数组或游标的结果集),而不是像在一些其他编程语言中那样用于基于条件的循环。
参考官方文档地址
https://docs.oracle.com/en/database/oracle/oracle-database/23/lnpls/plsql-control-statements.html#GUID-0E130F2D-9635-4C0B-9D63-16C3D9FBE7D2
Oracle PL/SQL中的FOR LOOP
主要用于以下几种情况:
-
基于数值范围的遍历:你可以使用
FOR LOOP
遍历一个从起始值到结束值的数值序列。 -
遍历游标:
FOR LOOP
可以自动从游标中检索行,并允许你在循环体内部访问这些行。
1:基于数值范围的遍历
DECLARE i NUMBER;
BEGINFOR i IN 1..5 LOOPDBMS_OUTPUT.PUT_LINE('i的值为: ' || i);END LOOP;
END;
/
sqlplus执行结果如下
SYS@orcl> set serveroutput on
SYS@orcl> DECLARE i NUMBER;2 BEGIN3 FOR i IN 1..5 LOOP4 DBMS_OUTPUT.PUT_LINE('i的值为: ' || i);5 END LOOP;6 END;7 /
i的值为: 1
i的值为: 2
i的值为: 3
i的值为: 4
i的值为: 5PL/SQL procedure successfully completed.
这个例子中,FOR LOOP
会遍历从1到5的整数,并在控制台上打印每个数值。
2:反向循环语句范围迭代控制
The FOR LOOP statement in this example prints the numbers from 5 to 1. The loop variable i is implicitly declared as a PLS_INTEGER (the default for counting and indexing loops).
BEGINFOR i IN REVERSE 1..5 LOOPDBMS_OUTPUT.PUT_LINE ('i的值为: ' ||i);END LOOP;
END;
/
Result:
i的值为: 5
i的值为: 4
i的值为: 3
i的值为: 2
i的值为: 1
3:实现带步长的循环
3.1:Oracle23ai新特性FOR i IN … BY … LOOP
This example shows a loop variable n declared explicitly as a NUMBER(5,1). The increment for the counter is 0.5.
这个例子中,展示一个显式声明为NUMBER(5,1)的循环变量n。计数器的步长增量为0.5。
BEGINFOR n NUMBER(5,1) IN 1.0 .. 5.0 BY 0.5 LOOPDBMS_OUTPUT.PUT_LINE('n的值为: ' ||n);END LOOP;
END;
/
Result:
SYS@FREE> BEGIN2 FOR n NUMBER(5,1) IN 1.0 .. 5.0 BY 0.5 LOOP3 DBMS_OUTPUT.PUT_LINE('n的值为: ' ||n);4 END LOOP;5 END;6 /
n的值为: 1
n的值为: 1.5
n的值为: 2
n的值为: 2.5
n的值为: 3
n的值为: 3.5
n的值为: 4
n的值为: 4.5
n的值为: 5PL/SQL procedure successfully completed.
Oracle19c及之前的版本,以上语句执行不了,报错如下
SYS@orcl> BEGIN2 FOR n NUMBER(5,1) IN 1.0 .. 3.0 BY 0.5 LOOP3 DBMS_OUTPUT.PUT_LINE(n);4 END LOOP;5 END;6 /FOR n NUMBER(5,1) IN 1.0 .. 3.0 BY 0.5 LOOP*
ERROR at line 2:
ORA-06550: line 2, column 10:
PLS-00103: Encountered the symbol "NUMBER" when expecting one of the following:
in
The symbol "in" was substituted for "NUMBER" to continue.
ORA-06550: line 2, column 22:
PLS-00103: Encountered the symbol "IN" when expecting one of the following:
. ( * % & - + / at loop mod remainder rem ..
<an exponent (**)> || multiset
3.2:Oracle19c及之前的版本可以采用如下两种方法即可
3.2.1:使用LOOP … EXIT WHEN … END LOOP
SYS@FREE> DECLARE i NUMBER(5,1) := 1.0; 2 BEGIN 3 LOOP 4 DBMS_OUTPUT.PUT_LINE('i的值为: ' || i); 5 i := i + 0.5; -- 设置步长为0.5 6 EXIT WHEN i > 5.0; -- 当i大于5.0时退出循环 7 END LOOP; 8 END; 9 /
i的值为: 1
i的值为: 1.5
i的值为: 2
i的值为: 2.5
i的值为: 3
i的值为: 3.5
i的值为: 4
i的值为: 4.5
i的值为: 5PL/SQL procedure successfully completed.
3.2.2:使用WHILE LOOP
SYS@orcl> DECLARE i NUMBER(5,1) := 1.0; 2 BEGIN 3 WHILE i <= 5.0 LOOP 4 DBMS_OUTPUT.PUT_LINE('i的值为: ' || i); 5 i := i + 0.5; -- 设置步长为0.5 6 END LOOP; 7 END; 8 /
i的值为: 1
i的值为: 1.5
i的值为: 2
i的值为: 2.5
i的值为: 3
i的值为: 3.5
i的值为: 4
i的值为: 4.5
i的值为: 5PL/SQL procedure successfully completed.
3.3:STEP Clause in FOR LOOP Statement
In this example, the FOR LOOP effectively increments the index by five
这个例子中,展示循环变量n。计数器的步长增量为5。
BEGINFOR i IN 5..15 BY 5 LOOPDBMS_OUTPUT.PUT_LINE (i);END LOOP;
END;
执行并返回结果
SYS@FREE> BEGIN2 FOR i IN 5..15 BY 5 LOOP3 DBMS_OUTPUT.PUT_LINE (i);4 END LOOP;5 END;6 /
5
10
15PL/SQL procedure successfully completed.
3.3:使用LOOP … EXIT WHEN … END LOOP实现带步长的循环
下面是一个使用LOOP … EXIT WHEN … END LOOP结构来实现从1遍历到10,步长为2的示例:
DECLARE i NUMBER := 1;
BEGIN LOOP DBMS_OUTPUT.PUT_LINE('i的值为: ' || i); i := i + 2; -- 设置步长为2 EXIT WHEN i > 10; -- 当i大于10时退出循环 END LOOP;
END;
/i的值为: 1
i的值为: 3
i的值为: 5
i的值为: 7
i的值为: 9
3.4:使用WHILE LOOP实现带步长的循环
同样,你也可以使用WHILE LOOP来实现相同的功能:
DECLARE i NUMBER := 1;
BEGIN WHILE i <= 10 LOOP DBMS_OUTPUT.PUT_LINE('i的值为: ' || i); i := i + 2; -- 设置步长为2 END LOOP;
END;
/i的值为: 1
i的值为: 3
i的值为: 5
i的值为: 7
i的值为: 9
4:遍历游标
假设你有一个名为employees
的表,包含员工的ID和姓名等信息,你可以使用FOR LOOP
遍历这个表的游标。
DECLARECURSOR emp_cur ISSELECT employee_id, first_name, last_name FROM employees;emp_rec emp_cur%ROWTYPE;
BEGINFOR emp_rec IN emp_cur LOOPDBMS_OUTPUT.PUT_LINE('Employee ID: ' || emp_rec.employee_id || ', Name: ' || emp_rec.first_name || ' ' || emp_rec.last_name);END LOOP;
END;
/Employee ID: 100, Name: Steven King
Employee ID: 101, Name: Neena Kochhar
Employee ID: 102, Name: Lex De Haan
Employee ID: 103, Name: Alexander Hunold
Employee ID: 104, Name: Bruce Ernst
Employee ID: 105, Name: David Austin
Employee ID: 106, Name: Valli Pataballa
。。。
PL/SQL procedure successfully completed.
在这个例子中,FOR LOOP
自动从游标emp_cur
中检索每一行,并将每一行的数据存储在emp_rec
中,然后你可以在循环体内访问这些数据。
5:注意
- 在使用
DBMS_OUTPUT.PUT_LINE
之前,你可能需要在SQL*Plus或SQLcl中设置SERVEROUTPUT ON
来确保输出被显示。 - Oracle PL/SQL的
FOR LOOP
不直接支持像其他编程语言中那样的条件退出(如break
语句),但它通过其结构本身限制了循环的范围,因此通常不需要这种功能。 - 对于更复杂的循环条件,你可能需要使用
WHILE LOOP
或LOOP...EXIT WHEN...END LOOP
结构。