和大多数程序语言一样,PL/SQL也有控制语句执行的结构,主要包括:
1、顺序结构:程序从上往下执行逐条语句,就是顺序结构;
2、分支条件判断:分支条件判断主要是指的IF语句和CASE语句。
3、循环语句:循环结构主要指的是REPEAT、LOOP和DO WHILE语句。
本章节主要讲解条件判断语句的用法。
一、 IF 语句的用法
IF 语句的基本格式为:
IF conditionTHEN
statements;
[ ELSIF conditionTHEN
-- 注意,这里的ELSIF中间没有E,ELSIF可以出现任意次
statements;]
[ ELSE
statements;
]
END IF;
IF 后面的判断条件可以是布尔值,常量或表达式,判断结果为TRUE, FALSE或NULL,其中NULL这种情况是PL/SQL中特有的,其他编程语言并不常见;
如果IF后的条件判断结果为TRUE,就执行THEN后面的语句;如果结果为FALSE和NULL,则不执行THEN后面的结果,而执行ELSE后面的语句。
下面看一个简单的例子:
SQL> edit
DECLARE v_myage number :=31; BEGIN IF v_myage < 11 THEN DBMS_OUTPUT.PUT_LINE(‘ I am a child‘); ELSE DBMS_OUTPUT.PUT_LINE( ‘ I am not achild! ‘); -- 由于IF后的条件判断结果为FALSE,所以会执行这条语句 END IF; END; /
SQL> /
I am not a child! PL/SQL procedure successfullycompleted.
现在为上述例子多添加几条分支进行条件判断:
SQL> edit
BEGIN IF v_myage < 11 THEN DBMS_OUTPUT.PUT_LINE(‘ I am achild ‘); ELSIF v_myage < 20 THEN DBMS_OUTPUT.PUT_LINE( ‘Iam young ‘); ELSIF v_myage < 30 THEN DBMS_OUTPUT.PUT_LINE( ‘Iam in my twenties‘); ELSIF v_myage < 40 THEN DBMS_OUTPUT.PUT_LINE( ‘I am in mythirties‘); -- 由于31大于11,20,30,而小于40,所以执行这条语句 ELSE DBMS_OUTPUT.PUT_LINE( ‘Iam always young ‘); END IF; END; /
SQL> /
I am in my thirties PL/SQL procedure successfullycompleted.
如果IF条件判断的结果为NULL,则不会执行THEN后面的语句。
SQL> edit
DECLARE v_myage NUMBER; BEGIN -- IF v_myage IS NULL --这里的结果时TRUE,因为判断是变量v_myage是否为NULL值,是就为TRUE,不是就为FALSE IF v_myage < 11 THEN -- 如果判断的条件为NULL值,则结果为NULL THEN DBMS_OUTPUT.PUT_LINE(‘ I am a child‘); ELSE DBMS_OUTPUT.PUT_LINE( ‘ I am not achild! ‘); END IF; END; /
SQL> /
I am not a child PL/SQL procedure successfullycompleted.
IF 语句的条件还可以使用AND,OR,NOT等逻辑符进行组合。
IF条件判断语句中需要注意一些细节:
a. IF 和 END IF必须配对出现;
b. END IF中间有空格;
c. ELSIF中间没有E;
d. 在END IF后面有分号“;”
二、 CASE的用法
CASE实际上IF语句的变体,当IF语句有大量类似的ELSIF判断条件时,就可以使用CASE来进行简化。CASE的用法可以分为两种,一种是CASE表达式,另一种是CASE语句。
(1)CASE表达式:
CASE 表达式的基本格式为:
CASE selector
WHENexpression1 THEN result1
WHENexpression2 THEN result2
...
WHENexpressionN THEN resultN
[ELSEresultN+1]
END;
其中selector选择值如果等于expression1的值,就执行result1,如果等于expression2,就执行result2...以此类推,如果没有expression的值能与之匹配的,就执行resultN+1。
CASE表达式可以分为simple CASE和Searched CASE,其中simple CASE是指CASE后面会跟一个选择值,然后将条件表达式的结果和这个选择值进行比较,如下述这个例子:
SQL> edit
SET VERIFY OFF DECLARE v_grade CHAR(1) := UPPER(‘&grade‘); v_appraisal VARCHAR2(20); BEGIN v_appraisal := CASE v_grade WHEN ‘A‘ THEN ‘Excellent‘ WHEN ‘B‘ THEN ‘Very Good‘ WHEN ‘c‘ THEN ‘Good‘ ELSE ‘No such grade‘ END; -- 从CASE到END这一部分是simple CASE,其运行结果作为一个值赋给v_appraisal这个变量。 DBMS_OUTPUT.PUT_LINE (‘Grade: ‘ ||v_grade || ‘ Appraisal ‘ || v_appraisal); END;
SQL> /
Enter value for grade: a Grade: A Appraisal Excellent PL/SQL procedure successfullycompleted.
SQL> /
Enter value for grade: s Grade: S Appraisal No suchgrade PL/SQL procedure successfullycompleted.
Searched CASE 中CASE后面没有选择值selector,而是直接判断关键字WHEN后面表达式的布尔值,如下面这个例子:
SQL> edit
DECLARE v_grade CHAR(1) := UPPER(‘&grade‘); v_appraisal VARCHAR2(20); BEGIN v_appraisal := CASE -- 这里的CASE没有选择值了 WHEN v_grade = ‘A‘ THEN‘Excellent‘ -- 直接在条件判断部分完成布尔值的返回 WHEN v_grade IN (‘B‘,‘C‘) THEN‘Good‘ ELSE ‘No such grade‘ END; DBMS_OUTPUT.PUT_LINE (‘Grade: ‘ ||v_grade || ‘ Appraisal ‘ ||v_appraisal); END; /
SQL>/
Enter value for grade: A Grade: A Appraisal Excellent PL/SQL procedure successfullycompleted.
SQL> /
Enter value for grade: o Grade: O Appraisal No such grade PL/SQL procedure successfullycompleted.
SQL> /
Enter value for grade: b Grade: B Appraisal Good PL/SQL procedure successfullycompleted.
(2)CASE语句
CASE语句就是一条条独立的语句,它不能将运行结果再赋值给其他的变量了。
如下面这个例子:
SQL> edit
DECLARE v_deptid NUMBER; v_deptname VARCHAR2(20); V_emps NUMBER; v_mngid NUMBER:= 108; BEGIN CASE v_mngid WHEN 108 THEN SELECT department_id,department_name INTO v_deptid, v_deptname FROM departments WHERE manager_id = 108; SELECT count(*) INTO v_emps FROM employees WHERE department_id = v_deptid; --CASE语句不再作为一个整体将运行结果赋值给其他变量了 WHEN 200 THEN SELECT department_id,department_name INTO v_deptid, v_deptname FROM departments WHERE manager_id = 200; SELECT count(*) INTO v_emps FROM employees WHERE department_id = v_deptid; ELSE SELECT department_id,department_name INTO v_deptid, v_deptname FROM departments WHERE manager_id = 100; SELECT count(*) INTO v_emps FROM employees WHERE department_id = v_deptid; END CASE; --CASE语句中必须有END CASE,如果是CASE表达式就不需要END CASE。 DBMS_OUTPUT.PUT_LINE(‘You are workingin the ‘ || v_deptname || ‘ department. There are ‘ ||v_emps || ‘employees inthis department‘); END; /
SQL> /
You are working in theFinance department. There are 6 employees in this department PL/SQL procedure successfullycompleted.
CASE语句也分为SimpleCASE语句和Searched CASE语句。他们之间的区别和CASE表达式一样。上述例子属于SimpleCASE的用法,如果要使用Searched CASE语句,可以写成如下形式:
SQL> edit
DECLARE v_deptid NUMBER; v_deptname VARCHAR2(20); V_emps NUMBER; v_mngid NUMBER:= 100; BEGIN CASE WHEN v_mngid = 108 THEN --v_mngid不作为选择值,而是直接在WHEN后面进行判断 SELECT department_id,department_name INTO v_deptid, v_deptname FROM departments WHERE manager_id = 108; SELECT count(*) INTO v_emps FROM employees WHERE department_id = v_deptid; WHEN v_mngid = 200 THEN SELECT department_id,department_name INTO v_deptid, v_deptname FROM departments WHERE manager_id = 200; SELECT count(*) INTO v_emps FROM employees WHERE department_id = v_deptid; ELSE SELECT department_id,department_name INTO v_deptid, v_deptname FROM departments WHERE manager_id = 100; SELECT count(*) INTO v_emps FROM employees WHERE department_id = v_deptid; END CASE; DBMS_OUTPUT.PUT_LINE(‘You are workingin the ‘ || v_deptname || ‘ department. There are ‘ ||v_emps || ‘employees inthis department‘); END; /
SQL> /
You are working in theExecutive department. There are 3 employees in this department PL/SQL procedure successfullycompleted.