Oracle数据库之PL/SQL流程控制语句
在任何计算机编程语言(如C,Java,C#等)都有各种流程控制语句,同样,在PL/SQL中也存在这样的流程控制结构。
几种常见的流程控制结构:
一、条件结构
1. 简单IF结构
-- 简单IF结构 IF <布尔表达式> THEN 满足条件时执行的语句 END IF;
2. IF-ELSE结构
-- IF-ELSE结构 IF <布尔表达式> THEN 满足条件时执行的语句 ELSE 不满足条件时执行的语句 END IF;
3. 多重IF
-- 多重IF IF <布尔表达式1> THEN 满足条件1时执行的语句 ELSIF <布尔表达式2> THEN 满足条件2时执行的语句 ELSIF <布尔表达式3> THEN 满足条件3时执行的语句 ELSE 满足条件1、2、3均不满足时执行的语句 END IF;
注意:ELSIF
不能写成ELSEIF
示例:
DECLARE emp_id employee.id%TYPE := &empid; emp_salary employee.salary%TYPE; info VARCHAR2(50); BEGIN SELECT salary INTO emp_salary FROM employee WHERE id = emp_id; /* 根据薪资情况判断 */ IF emp_salary < 1500 THEN info := '太少了,不加就辞职!'; ELSIF emp_salary <3000 THEN info := '还将就,先干着吧!'; ELSE info := '目前还比较满意,以后再看!'; END IF; DBMS_OUTPUT.PUT_LINE(info); EXCEPTION WHEN no_data_found THEN DBMS_OUTPUT.PUT_LINE('没有数据~!'); WHEN others THEN DBMS_OUTPUT.PUT_LINE(sqlcode || '---' || sqlerrm); END;
4. CASE
语法一:
CASE 条件表达式 WHEN 条件表达式结果1 THEN 语句1 WHEN 条件表达式结果2 THEN 语句2 ...... WHEN 条件表达式结果n THEN 语句n [ELSE 条件表达式结果] END CASE;
示例:
DECLARE grade CHAR(1); BEGIN grade := '&g'; CASE grade WHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent'); WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good'); WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE('Good'); WHEN 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair'); WHEN 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor'); ELSE DBMS_OUTPUT.PUT_LINE('No such grade'); END CASE; END;
语法二:
CASE WHEN 条件表达式1 THEN 语句1 WHEN 条件表达式2 THEN 语句2 ...... WHEN 条件表达式n THEN 语句n [ELSE 语句] END CASE;
示例:
DECLARE grade CHAR(1); BEGIN grade := '&g'; CASE WHEN grade = 'A' THEN DBMS_OUTPUT.PUT_LINE('Excellent'); WHEN grade = 'B' THEN DBMS_OUTPUT.PUT_LINE('Very Good'); WHEN grade = 'C' THEN DBMS_OUTPUT.PUT_LINE('Good'); WHEN grade = 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair'); WHEN grade = 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor'); ELSE DBMS_OUTPUT.PUT_LINE('No such grade'); END CASE; END;
二、循环结构
1. 简单循环
语法:
LOOP 循环体语句; [EXIT WHEN <条件语句>] END LOOP;
示例1:
DECLARE x NUMBER(2) := 0; BEGIN LOOP x := x + 1; DBMS_OUTPUT.PUT_LINE('x的当前值为:'||x); EXIT WHEN x = 10; END LOOP; END;
示例2:
DECLARE x NUMBER := 0; BEGIN LOOP DBMS_OUTPUT.PUT_LINE ('循环中: x = ' || TO_CHAR(x)); x := x + 1; IF x > 3 THEN EXIT; END IF; END LOOP; DBMS_OUTPUT.PUT_LINE(' 循环结束: x = ' || TO_CHAR(x)); END;
2. WHILE循环
语法:
WHILE <布尔表达式> LOOP 循环体语句; END LOOP;
示例1:
DECLARE done BOOLEAN := FALSE; BEGIN WHILE done LOOP DBMS_OUTPUT.PUT_LINE ('Oh, no! It's wrong!'); done := TRUE; END LOOP; WHILE NOT done LOOP DBMS_OUTPUT.PUT_LINE ('Hello, world!'); done := TRUE; END LOOP; END;
3. FOR循环
语法:
[<<标签>>] FOR 循环计数器 IN [ REVERSE ] 下限 .. 上限 LOOP 循环体语句; END LOOP [<<标签>>];
说明:
使用关键字REVERSE,循环变量自动减1。跟在IN REVERSE后面的数字应是从小到大的顺序,而且必须是整数,不能是变量或表达式。
示例1:
BEGIN DBMS_OUTPUT.PUT_LINE ('下限 < 上限:'); FOR i IN 1..3 LOOP DBMS_OUTPUT.PUT_LINE (i); END LOOP; DBMS_OUTPUT.PUT_LINE ('下限 = 上限:'); FOR i IN 2..2 LOOP DBMS_OUTPUT.PUT_LINE (i); END LOOP; DBMS_OUTPUT.PUT_LINE ('下限 > 上限:'); FOR i IN 3..1 LOOP DBMS_OUTPUT.PUT_LINE (i); END LOOP; END;
输出结果:
下限 < 上限: 1 2 3 下限 = 上限: 2 下限 > 上限:
示例2:
BEGIN DBMS_OUTPUT.PUT_LINE ('反转 -- 下限 < 上限:'); FOR i IN REVERSE 1..3 LOOP DBMS_OUTPUT.PUT_LINE (i); END LOOP; DBMS_OUTPUT.PUT_LINE ('反转 -- 下限 = 上限:'); FOR i IN REVERSE 2..2 LOOP DBMS_OUTPUT.PUT_LINE (i); END LOOP; DBMS_OUTPUT.PUT_LINE ('反转 -- 下限 > 上限:'); FOR i IN REVERSE 3..1 LOOP DBMS_OUTPUT.PUT_LINE (i); END LOOP; END;
运行结果:
反转 -- 下限 < 上限: 3 2 1 反转 -- 下限 = 上限: 2 反转 -- 下限 > 上限:
循环结构中,均可以在适当的时候构建条件使用EXIT退出循环结构。
三、顺序结构
1. GOTO
GOTO语句用于跳转到指定<<标号>>去执行语句,是无条件跳转到指定的标号去的意思。
注意:标号是用<< >>括起来的标识符。
语法:
GOTO label;
GOTO语句缺点是会增加程序的复杂性,降低可读性,所以Oracle建议不要使用。
示例:
DECLARE p VARCHAR2(30); n PLS_INTEGER := 37; BEGIN FOR j in 2..ROUND(SQRT(n)) LOOP IF n MOD j = 0 THEN p := ' 不是素数'; GOTO print_now; END IF; END LOOP; p := ' 是素数'; <<print_now>> DBMS_OUTPUT.PUT_LINE(TO_CHAR(n) || p); END;
2. NULL
空语句,执行没有任何实际效果,可以使某些语句变得有意义,提高程序的可读性,保证其他语句结构的完整性和正确性,通常用于占位置。
示例1:
DECLARE valid BOOLEAN := TRUE; BEGIN GOTO update_row; IF valid THEN <<update_row>> NULL; END IF; END;
示例2:
DECLARE v_job_id VARCHAR2(10); v_emp_id NUMBER(6) := 110; BEGIN SELECT job_id INTO v_job_id FROM employees WHERE employee_id = v_emp_id; IF v_job_id = 'SA_REP' THEN UPDATE employees SET commission_pct = commission_pct * 1.2; ELSE NULL; END IF; END;