CASE 语句在指定的搜索条件为 true 时执行一组单个或多个语句。CASE 语句本身是独立的语句,而前面讲述的 CASE 表达式必须作为表达式的一部分出现。
CASE 语句有两种格式:一种称为搜索 CASE,另一种使用选择器。
选择器 CASE 语句
选择器 CASE 语句尝试将一个称为选择器的表达式与一个或多个 WHEN 子句中指定的表达式进行匹配。当找到匹配项时,将执行对应的一个或多个语句。
CASE selector-expression
WHEN match-expression THEN
statements
[ WHEN match-expression THEN
statements
[ WHEN match-expression THEN
statements ] ...]
[ ELSE
statements ]
END CASE;
selector-expression 返回一个与每个 match-expression 类型兼容的值。match-expression 将按它出现在 CASE 语句中的顺序进行求值。statements 是一个或多个 SPL 语句,每个语句以分号结尾。当 selector-expression 的值等于第一个 match-expression 时,将执行对应 THEN 子句中的语句,并且控制权在 END CASE 关键字后面继续执行。如果没有匹配项,则执行 ELSE 后面的语句。如果没有匹配项并且没有 ELSE 子句,则将引发异常。
以下示例使用选择器 CASE 语句根据部门编号,将部门名称和地点分配给一个变量。
DECLARE
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
v_deptno emp.deptno%TYPE;
v_dname dept.dname%TYPE;
v_loc dept.loc%TYPE;
CURSOR emp_cursor IS SELECT empno, ename, deptno FROM emp;
BEGIN
OPEN emp_cursor;
DBMS_OUTPUT.PUT_LINE('EMPNO ENAME DEPTNO DNAME '
|| ' LOC');
DBMS_OUTPUT.PUT_LINE('----- ------- ------ ----------'
|| ' ---------');
LOOP
FETCH emp_cursor INTO v_empno, v_ename, v_deptno;
EXIT WHEN emp_cursor%NOTFOUND;
CASE v_deptno
WHEN 10 THEN v_dname := 'Accounting';
v_loc := 'New York';
WHEN 20 THEN v_dname := 'Research';
v_loc := 'Dallas';
WHEN 30 THEN v_dname := 'Sales';
v_loc := 'Chicago';
WHEN 40 THEN v_dname := 'Operations';
v_loc := 'Boston';
ELSE v_dname := 'unknown';
v_loc := '';
END CASE;
DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || RPAD(v_ename, 10) ||
' ' || v_deptno || ' ' || RPAD(v_dname, 14) || ' ' ||
v_loc);
END LOOP;
CLOSE emp_cursor;
END;
下面是此程序的输出。
EMPNO ENAME DEPTNO DNAME LOC
----- ------- ------ ---------- ---------
7369 SMITH 20 Research Dallas
7499 ALLEN 30 Sales Chicago
7521 WARD 30 Sales Chicago
7566 JONES 20 Research Dallas
7654 MARTIN 30 Sales Chicago
7698 BLAKE 30 Sales Chicago
7782 CLARK 10 Accounting New York
7788 SCOTT 20 Research Dallas
7839 KING 10 Accounting New York
7844 TURNER 30 Sales Chicago
7876 ADAMS 20 Research Dallas
7900 JAMES 30 Sales Chicago
7902 FORD 20 Research Dallas
7934 MILLER 10 Accounting New York
搜索 CASE 语句
搜索 CASE 语句使用一个或多个布尔表达式确定要执行的语句的结果集。
CASE WHEN boolean-expression THEN
statements
[ WHEN boolean-expression THEN
statements
[ WHEN boolean-expression THEN
statements ] ...]
[ ELSE
statements ]
END CASE;
boolean-expression 按它在 CASE 语句中出现的顺序进行求值。当遇到求值结果等于 TRUE 的第一个 boolean-expression 时,将执行对应 THEN 子句中的语句,并且控制权在 END CASE 关键字后面继续执行。如果没有求值结果为 TRUE 的 boolean-expression,则将执行 ELSE 后面的语句。如果没有求值结果为 TRUE 的 boolean-expression 并且没有 ELSE 子句,则将引发异常。
以下示例使用搜索 CASE 语句根据部门编号,将部门名称和地点分配给一个变量。
DECLARE
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
v_deptno emp.deptno%TYPE;
v_dname dept.dname%TYPE;
v_loc dept.loc%TYPE;
CURSOR emp_cursor IS SELECT empno, ename, deptno FROM emp;
BEGIN
OPEN emp_cursor;
DBMS_OUTPUT.PUT_LINE('EMPNO ENAME DEPTNO DNAME '
|| ' LOC');
DBMS_OUTPUT.PUT_LINE('----- ------- ------ ----------'
|| ' ---------');
LOOP
FETCH emp_cursor INTO v_empno, v_ename, v_deptno;
EXIT WHEN emp_cursor%NOTFOUND;
CASE
WHEN v_deptno = 10 THEN v_dname := 'Accounting';
v_loc := 'New York';
WHEN v_deptno = 20 THEN v_dname := 'Research';
v_loc := 'Dallas';
WHEN v_deptno = 30 THEN v_dname := 'Sales';
v_loc := 'Chicago';
WHEN v_deptno = 40 THEN v_dname := 'Operations';
v_loc := 'Boston';
ELSE v_dname := 'unknown';
v_loc := '';
END CASE;
DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || RPAD(v_ename, 10) ||
' ' || v_deptno || ' ' || RPAD(v_dname, 14) || ' ' ||
v_loc);
END LOOP;
CLOSE emp_cursor;
END;
下面是此程序的输出。
EMPNO ENAME DEPTNO DNAME LOC
----- ------- ------ ---------- ---------
7369 SMITH 20 Research Dallas
7499 ALLEN 30 Sales Chicago
7521 WARD 30 Sales Chicago
7566 JONES 20 Research Dallas
7654 MARTIN 30 Sales Chicago
7698 BLAKE 30 Sales Chicago
7782 CLARK 10 Accounting New York
7788 SCOTT 20 Research Dallas
7839 KING 10 Accounting New York
7844 TURNER 30 Sales Chicago
7876 ADAMS 20 Research Dallas
7900 JAMES 30 Sales Chicago
7902 FORD 20 Research Dallas
7934 MILLER 10 Accounting New York