通过 LOOP、EXIT、CONTINUE、WHILE 和 FOR 语句,您可以安排 SPL 程序重复一系列命令。

LOOP

LOOP
    statements
END LOOP;

LOOP 定义一个无条件循环,该循环将无限期地重复执行,直到被 EXIT 或 RETURN 语句终止。

EXIT

EXIT [ WHEN expression ];

终止最里面的循环,并接着执行 END LOOP 后面的语句。

如果 WHEN 存在,则仅当指定条件为 true 时才执行循环退出;否则控制权会传递给 EXIT 后面的语句。

EXIT 可用于提前退出所有类型的循环;它不限于与无条件循环一起使用。

下面是一个简单的循环示例,该循环执行十次迭代,然后使用 EXIT 语句终止。

DECLARE
    v_counter       NUMBER(2);
BEGIN
    v_counter := 1;
    LOOP
        EXIT WHEN v_counter > 10;
        DBMS_OUTPUT.PUT_LINE('Iteration # ' || v_counter);
        v_counter := v_counter + 1;
    END LOOP;
END;

下面是此程序的输出。

Iteration # 1
Iteration # 2
Iteration # 3
Iteration # 4
Iteration # 5
Iteration # 6
Iteration # 7
Iteration # 8
Iteration # 9
Iteration # 10

CONTINUE

CONTINUE 语句提供一种在跳过中间语句时继续循环的下一迭代的方式。

当遇到 CONTINUE 语句时,将开始最里面循环的下一迭代,这会跳过 CONTINUE 语句后面的所有语句,直到循环结束。也就是说,控制权将传回循环控制表达式(如果有),并将对循环体重新进行求值。

如果使用 WHEN 子句,则仅当 WHEN 子句中指定表达式的求值结果为 true 时才开始循环的下一迭代。否则,控制权将传给 CONTINUE 语句后面的下一个语句。

CONTINUE 语句不能在循环外部使用。

下面是上一示例的变体,它使用 CONTINUE 语句跳过奇数的显示。

DECLARE
    v_counter       NUMBER(2);
BEGIN
    v_counter := 0;
    LOOP
        v_counter := v_counter + 1;
        EXIT WHEN v_counter > 10;
        CONTINUE WHEN MOD(v_counter,2) = 1;
        DBMS_OUTPUT.PUT_LINE('Iteration # ' || v_counter);
    END LOOP;
END;

下面是上述程序的输出。

Iteration # 2
Iteration # 4
Iteration # 6
Iteration # 8
Iteration # 10

WHILE

WHILE expression LOOP
    statements
END LOOP;

WHILE 语句重复一系列语句,只要条件表达式的求值结果为 TRUE。就在每次进入循环体之前检查条件。

以下示例包含与上一示例相同的逻辑,但 WHILE 语句用于取代 EXIT 语句来确定何时退出循环。

说明 用于确定何时退出循环的条件表达式必须进行修改。EXIT 语句在其条件表达式为 true 时终止循环。WHILE 语句在其条件表达式为 false 时终止(或从不开始循环)。
DECLARE
    v_counter       NUMBER(2);
BEGIN
    v_counter := 1;
    WHILE v_counter <= 10 LOOP
        DBMS_OUTPUT.PUT_LINE('Iteration # ' || v_counter);
        v_counter := v_counter + 1;
    END LOOP;
END;

以下示例生成的结果与前一示例相同。

Iteration # 1
Iteration # 2
Iteration # 3
Iteration # 4
Iteration # 5
Iteration # 6
Iteration # 7
Iteration # 8
Iteration # 9
Iteration # 10

FOR(整型变量)

FOR name IN [REVERSE] expression .. expression LOOP
    statements
END LOOP;

此形式的 FOR 创建一个对一系列整数值执行迭代的循环。变量 name 自动定义为 INTEGER 类型并仅在循环内存在。给出循环范围的两个表达式在进入循环时进行一次求值。迭代步长为 +1,name 的值从 .. 左侧的 expression 开始,在 name 超过 .. 右侧的 expression 值后终止。因而,这两个表达式担任以下角色:start-value .. end-value。

可选的 REVERSE 子句指定循环应按反向顺序迭代。首次通过循环时,name 设置为最右侧 expression 表达式的值;当 name 小于最左侧 expression 时循环终止时。

以下示例通过使用从 1 到 10 执行迭代的 FOR 循环,更进一步简化了 WHILE 循环示例。

BEGIN
    FOR i IN 1 .. 10 LOOP
        DBMS_OUTPUT.PUT_LINE('Iteration # ' || i);
    END LOOP;
END;

下面是使用 FOR 语句的输出。

Iteration # 1
Iteration # 2
Iteration # 3
Iteration # 4
Iteration # 5
Iteration # 6
Iteration # 7
Iteration # 8
Iteration # 9
Iteration # 10

如果开始值大于结束值,则根本不会执行循环体。如以下示例所示,不会引发错误。

BEGIN
    FOR i IN 10 .. 1 LOOP
        DBMS_OUTPUT.PUT_LINE('Iteration # ' || i);
    END LOOP;
END;

由于从未执行循环体,因此此示例没有输出。

说明 SPL 还支持 CURSOR FOR 循环。