当前位置:   article > 正文

Oracle23ai新特性FOR LOOP循环控制结构增强

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主要用于以下几种情况:

  1. 基于数值范围的遍历:你可以使用FOR LOOP遍历一个从起始值到结束值的数值序列。

  2. 遍历游标FOR LOOP可以自动从游标中检索行,并允许你在循环体内部访问这些行。

1:基于数值范围的遍历

DECLARE i NUMBER;
BEGIN
    FOR i IN 1..5 LOOP
        DBMS_OUTPUT.PUT_LINE('i的值为: ' || i);
    END LOOP;
END;
/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

sqlplus执行结果如下

SYS@orcl> set serveroutput on
SYS@orcl> DECLARE i NUMBER;
  2  BEGIN
  3      FOR i IN 1..5 LOOP
  4          DBMS_OUTPUT.PUT_LINE('i的值为: ' || i);
  5      END LOOP;
  6  END;
  7  /
i的值为: 1
i的值为: 2
i的值为: 3
i的值为: 4
i的值为: 5

PL/SQL procedure successfully completed.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这个例子中,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).

BEGIN
   FOR i IN REVERSE 1..5 LOOP
      DBMS_OUTPUT.PUT_LINE ('i的值为: ' ||i);
   END LOOP;
END;
/ 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Result:

i的值为: 5
i的值为: 4
i的值为: 3
i的值为: 2
i的值为: 1
  • 1
  • 2
  • 3
  • 4
  • 5

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。

BEGIN
   FOR n NUMBER(5,1) IN 1.0 .. 5.0 BY 0.5 LOOP
      DBMS_OUTPUT.PUT_LINE('n的值为: ' ||n);
   END LOOP;
END;
/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Result:

SYS@FREE> BEGIN
  2     FOR n NUMBER(5,1) IN 1.0 .. 5.0 BY 0.5 LOOP
  3        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的值为: 5

PL/SQL procedure successfully completed.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

Oracle19c及之前的版本,以上语句执行不了,报错如下

SYS@orcl> BEGIN
  2     FOR n NUMBER(5,1) IN 1.0 .. 3.0 BY 0.5 LOOP
  3        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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

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的值为: 5

PL/SQL procedure successfully completed.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

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的值为: 5

PL/SQL procedure successfully completed.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

3.3:STEP Clause in FOR LOOP Statement

In this example, the FOR LOOP effectively increments the index by five
这个例子中,展示循环变量n。计数器的步长增量为5。

BEGIN
  FOR i IN 5..15 BY 5 LOOP
    DBMS_OUTPUT.PUT_LINE (i);
  END LOOP;
END;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

执行并返回结果

SYS@FREE> BEGIN
  2    FOR i IN 5..15 BY 5 LOOP
  3      DBMS_OUTPUT.PUT_LINE (i);
  4    END LOOP;
  5  END;
  6  /
5
10
15

PL/SQL procedure successfully completed.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

4:遍历游标

假设你有一个名为employees的表,包含员工的ID和姓名等信息,你可以使用FOR LOOP遍历这个表的游标。

DECLARE
    CURSOR emp_cur IS
        SELECT employee_id, first_name, last_name FROM employees;
    emp_rec emp_cur%ROWTYPE;
BEGIN
    FOR emp_rec IN emp_cur LOOP
        DBMS_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.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这个例子中,FOR LOOP自动从游标emp_cur中检索每一行,并将每一行的数据存储在emp_rec中,然后你可以在循环体内访问这些数据。

5:注意

  • 在使用DBMS_OUTPUT.PUT_LINE之前,你可能需要在SQL*Plus或SQLcl中设置SERVEROUTPUT ON来确保输出被显示。
  • Oracle PL/SQL的FOR LOOP不直接支持像其他编程语言中那样的条件退出(如break语句),但它通过其结构本身限制了循环的范围,因此通常不需要这种功能。
  • 对于更复杂的循环条件,你可能需要使用WHILE LOOPLOOP...EXIT WHEN...END LOOP结构。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/1005913
推荐阅读
相关标签
  

闽ICP备14008679号