[连载]Oracle 12cR2 PL/SQL语言参考 - 04 控制语句

588 阅读6分钟

概述

PL/SQL有如下这几类控制语句:

  • 条件选择语句
    基于不同的值来选择执行不同的语句,条件选择语句是IF和CASE
  • 循环语句
    基于不同的值来执行相同的语句,循环语句是LOOP, FOR LOOP和WHILE LOOP这三种
    EXIT语句可以退出循环,CONTINUE语句可以退出当前循环而进入下一次循环,这两个
    语句都有一个可选的WHEN子句,在这里你可以给出一个条件
  • 顺序控制语句
    GOTO语句直接跳转至一个指明的语句或NULL(什么也不做)

4.1 条件选择语句

IF语句基于一个条件,来选择执行或跳过一系列语句,IF语句有如下的形式:

    IF THEN
    IF THEN ELSE
    IF THEN ELSIF

CASE语句从一系列条件中做选择,并执行对应的语句,它有如下两种形式:

  • 简单
    计算一个表达式,将其结果与几个值进行比较
  • 搜索
    计算多个条件,并选中第一个结果为true的条件所对应的语句执行

4.1.1 IF THEN语句

IF THEN语句的语法格式如下

IF 条件 THEN
    一系列语句
END IF;

如果条件的计算结果为TRUE,则执行语句,否则什么都不做
IF语句是可以嵌套的

4.1.2 IF THEN ELSE语句

IF THEN ELSE语句的语法格式如下

IF 条件 THEN
    一系列语句  -- 条件计算结果为TRUE时执行
ELSE
    一系列语句  -- 条件计算结果为FALSE时执行
END IF;

4.1.3 IF THEN ELSIF语句

IF THEN ELSIF语句的语法格式如下

IF 条件1 THEN
    一系列语句
ELSIF 条件2 THEN
    一系列语句
[ ELSIF 条件3 THEN
    一系列语句
] ...
[ ELSE
    一系列语句]
END IF;

4.1.4 简单CASE语句

简单CASE语句的语法格式如下

CASE selector
WHEN selector_value_1 THEN 语句系列_1
WHEN selector_value_2 THEN 语句系列_2
WHEN selector_value_3 THEN 语句系列_3
...
WHEN selector_value_n THEN 语句系列_n
[ ELSE
    语句系列]
END CASE;

selector是一个表达式(通常是一个变量),每个selector_value可以是字面量或表达式
selector的计算结果与哪个selector_value相等,就执行对应的语句系列,如果没有匹配到,
就执行ELSE对应的语句系列(如果有),如果没有ELSE部分就抛出一个预定义异常CASE_NOT_FOUND

4.1.5 搜索CASE语句

搜索CASE语句的语法格式如下

CASE
WHEN condition_1 THEN 语句系列_1
WHEN condition_2 THEN 语句系列_2
WHEN condition_3 THEN 语句系列_3
...
WHEN condition_n THEN 语句系列_n
[ ELSE
    语句系列]
END CASE;

搜索CASE语句会运行第一个碰到的condition为真所对应的语句系列,剩余的condition将不会
再计算.如果没有condition为真,那就执行ELSE对应的语句(如果有),如果没有ELSE部分就抛出
一个预定义异常CASE_NOT_FOUND

4.2 循环语句

循环语句有如下几种:

  • 基本LOOP
  • FOR LOOP
  • 游标FOR LOOP
  • WHILE LOOP 完全退出循环的语句是: EXIT 和 EXIT WHEN
    退出当前循环并进入下一次循环的语句是: CONTINUE 和 CONTINUE WHEN
    LOOP语句可以打上标签,LOOP语句可以嵌套,在嵌套的LOOP语句中使用标签是推荐的,
    因为可以提高可读性,要确保LOOP语句的开头和结尾都匹配同一个标签(编译器并不做检查)

4.2.1 基本LOOP语句

基本LOOP语句的语法格式如下

[标签] LOOP
    语句系列
END LOOP [标签];

为防止无限循环,必须有一个语句或抛出异常来退出循环

4.2.2 EXIT语句

EXIT语句无条件的退出当前循环或标签指定的外层循环
样例程序如下

DECLARE
    x NUMBER := 0;
BEGIN
    LOOP
        DBMS_OUTPUT.PUT_LINE('Inside loop: x = ' || TO_CHAR(x));
        x := x + 1;
        IF x > 3 THEN
            EXIT;
        END IF;
    END LOOP;
    -- EXIT执行后,程序会执行到这里
    DBMS_OUTPUT.PUT_LINE('After loop: x = ' || TO_CHAR(x));
END;
/

4.2.3 EXIT WHEN语句

EXIT WHEN语句的语法格式如下

EXIT WHEN 条件表达式;

当条件表达式为TRUE时就退出当前循环或指定标签的外层循环
上一个EXIT语句的样例程序可以改写为

DECLARE
    x NUMBER := 0;
BEGIN
    LOOP
        DBMS_OUTPUT.PUT_LINE('Inside loop: x = ' || TO_CHAR(x));
        x := x + 1;
        EXIT WHEN x > 3
    END LOOP;
    -- EXIT执行后,程序会执行到这里
    DBMS_OUTPUT.PUT_LINE('After loop: x = ' || TO_CHAR(x));
END;
/

下面是一个嵌套循环的样例程序

DECLARE
    s PLS_INTEGER := 0;
    i PLS_INTEGER := 0;
    j PLS_INTEGER;
BEGIN
    <<outer_loop>>
    LOOP
        i := i + 1;
        j := 0;
        <<inner_loop>
        LOOP
            j := j + 1;
            s := s + i * j;
            EXIT inner_loop WHEN (j > 5);
            EXIT outer_loop WHEN ((i * j) > 15);
        END LOOP inner_loop;
    END LOOP outer_loop;
    DBMS_OUTPUT.PUT_LINE('The sum of products equals: ' || TO_CHAR(s));
END;
/

有些语言拥有LOOP UNTIL或REPEAT UNTIL语句,它们的测试条件在尾部而不是在开头
所以循环体内的语句至少会执行一次,要想模拟这种语句,可以使用

LOOP
    语句系列
    EXIT WHEN 条件;
END LOOP;

4.2.4 CONTINUE语句

CONTINUE语句无条件退出当前循环或指定标签的外层循环,并进入下一次循环

4.2.5 CONTINUE WHEN语句

CONTINUE WHEN语句的语法格式如下

CONTINUE WHEN 条件表达式;

当条件表达式为TRUE时就退出当前循环或指定标签的外层循环,并进入下一次循环

4.2.6 FOR LOOP语句

当循环索引在指定的值范围内时FOR LOOP循环执行一系列语句,语法格式如下

[标签] FOR 索引 IN [REVERSE] 低值..高值 LOOP
    一系列语句
END LOOP [标签];

在不使用REVERSE时,索引的值从低值开始,每次循环后加1,直到等于高值后,循环结束
如果低值比高值大,那么循环永远不会执行
在使用REVERSE时,索引的值从高值开始,每次循环后减1,直到等于低值后,循环结束
如果低值比高值大,那么循环永远不会执行
在FOR LOOP循环中可以使用EXIT, EXIT WHEN, CONTINUE和CONTINUE WHEN语句来提前退出循环

FOR LOOP循环索引
循环索引这个变量隐式的被声明为PLS_INTEGER类型局部变量,循环内部的语句可以访问索引
的值,但是不能改变它,而循环外部的语句无法访问这个索引变量,循环结束后索引变量就被
销毁了,所以有时索引也被称为循环计数器

低值边界与高值边界
FOR LOOP循环中的低值和高值可以是数字字面量,数字类型变量或表达式(计算结果是数字)
如果不是数字,PL/SQL会抛出异常VALUE_ERROR

4.2.7 WHILE LOOP语句

WHILE LOOP循环语句的语法格式如下

[标签] WHILE 条件 LOOP
    语句系列
END LOOP [标签];

如果条件的计算结果是TRUE,那么循环就一直执行

4.3 顺序控制语句

顺序控制语句GOTO和NULL对于PL/SQL程序并不是必要的

4.3.1 GOTO语句

不推荐使用,所以略

4.3.2 NULL语句

表示什么都不做,在设计函数或子程序时,可以使用NULL语句来代替暂未设计好的代码实现