CASE语句与CASE表达式

      case语句与case表达式是plsql流程控制的重要组成部分,尽管其使用方法较为简单,但容易混淆。本文将描述case语句与case表达式并给出演示以便于更好理解两者的异同及使用时的注意事项。

一、简单case语句

-->语法

CASE SELECTOR
WHEN EXPRESSION 1 THEN STATEMENT 1;
WHEN EXPRESSION 2 THEN STATEMENT 2;
...
WHEN EXPRESSION N THEN STATEMENT N;
ELSE STATEMENT N+1;
END CASE;

--简单的case语句是指SELECTOR中得到的值或结果与EXPRESSION n中的值或结果相匹配,一旦找到匹配,则对应的语句被执行。直到找到为止。
--如果对应的EXPRESSION n 中没有匹配,则此时ELSE上阵,执行其后对应的语句。
--ELSE为可选项。如省略且when条件中未找到任何匹配项,则收到case_not_found异常。

-->演示简单case语句
sys@ORCL> DECLARE
  2     v_num    NUMBER := &in_num;
  3     v_flag   NUMBER;
  4  BEGIN
  5     v_flag := MOD (v_num, 2);
  6
  7     CASE v_flag
  8        WHEN 0
  9        THEN
 10           DBMS_OUTPUT.put_line (v_num || ' is even number');
 11        WHEN 1
 12        THEN
 13           DBMS_OUTPUT.put_line (v_num || ' is odd number');
 14        ELSE
 15           NULL;
 16     END CASE;
 17  END;
 18  /
Enter value for in_num: 5
5 is odd number

PL/SQL procedure successfully completed.

二、搜索式case语句

-->语法

CASE
WHEN SEARCH CONDITION 1 THEN STATEMENT 1;
WHEN SEARCH CONDITION 2 THEN STATEMENT 2;
...
WHEN SEARCH CONDITION N THEN STATEMENT N;
ELSE STATEMENT N+1;
END CASE;

--搜索式case语句与简单case语句长相不一样。首先是case 之后没有接selector,其次是when之后的SEARCH CONDITION n得到的结果为布尔型,
--当搜索到第一个为TRUE的STATEMENT的结果会被返回。若果所有的when之后的SEARCH CONDITION没有为TRUE的,则else之后的STATEMENT
--的结果会被返回。如果此时省略了else子句,等同于简单case语句,同样会收到case_not_found异常。谁叫他俩一母同胞呢?

-->下面演示搜索式case
scott@ORCL> DECLARE
  2     v_num   NUMBER := &in_num;
  3  BEGIN
  4     CASE
  5        WHEN v_num > 0
  6        THEN
  7           DBMS_OUTPUT.put_line (v_num || ' is a positive number ');
  8        WHEN v_num < 0
  9        THEN
 10           DBMS_OUTPUT.put_line (v_num || ' is a negative number ');
 11        ELSE
 12           DBMS_OUTPUT.put_line (v_num || ' is zero ');
 13     END CASE;
 14  END;
 15  /
Enter value for in_num: -3
-3 is a negative number

-->如下例所示所有的when之后的没有一个为true,且省略了else子句,那么迎接你的是CASE not found
scott@ORCL> DECLARE
  2     v_num   NUMBER := &in_num;
  3  BEGIN
  4     CASE
  5        WHEN v_num > 0
  6        THEN
  7           DBMS_OUTPUT.put_line (v_num || ' is a positive number ');
  8        WHEN v_num < 0
  9        THEN
 10           DBMS_OUTPUT.put_line (v_num || ' is a negative number ');
 11     END CASE;
 12  END;
 13  /
Enter value for in_num: 0
DECLARE
*
ERROR at line 1:
ORA-06592: CASE not found while executing CASE statement
ORA-06512: at line 4

/**************************************************/
/* Author: Robinson Cheng                         */
/* Blog:   http://blog.csdn.net/robinson_0612     */
/* MSN:    robinson_0612@hotmail.com              */
/* QQ:     645746311                              */
/**************************************************/ 

三、简单case语句与搜索式case语句的异同

--相同点:两者都用于根据不同的条件,来执行与之对应的语句或完成特定的任务,甚至某些情况下可以互换替换。
--不同点:
	--简单case语句提供一个selector选择器,且EXPRESSION的数据类型一定与selector的数据类型匹配,否则报错。
	--搜索case语句没有selector选择器,且when子句之后得到的结果一定是一个布尔型值(NULL,TRUR,FALSE)

--下面的例子是一个简单case与搜索case之间互换的例子,同时该方式也实现了行到列的转行。
scott@ORCL> select sum(case when deptno=20 then sal end) as sal_sum_20,   -->搜索式case表达式 @20150713更正
  2  sum(case when deptno=30 then sal end) as sal_sum_30
  3  from emp where comm>300;

SAL_SUM_20 SAL_SUM_30
---------- ----------
     13075       8300

scott@ORCL> select sum(case deptno when 20 then sal end) as sal_sum_20,  -->简单式case表达式  @20150713更正
  2  sum(case deptno when 30 then sal end) as sal_sum_30
  3  from emp where comm>300;

SAL_SUM_20 SAL_SUM_30
---------- ----------
     13075       8300

--使用搜索式case方式,当selector选择器的数据类型不是为布尔型时,收到类型不匹配的提示,如下示例:
scott@ORCL> DECLARE
  2     v_num    NUMBER := &sv_num;
  3     v_flag   NUMBER;
  4  BEGIN
      THEN
  5     CASE v_flag
  6        WHEN MOD (v_num, 2) = 0
  7        THEN
  8           DBMS_OUTPUT.PUT_LINE (v_num || ' is even number');
  9        ELSE
 10           DBMS_OUTPUT.PUT_LINE (v_num || ' is odd number');
 11     END CASE;
 12  END;
 13  /
Enter value for sv_num: 7
   CASE v_flag
        *
ERROR at line 5:
ORA-06550: line 5, column 9:
PLS-00615: type mismatch found at 'V_FLAG' between CASE operand and WHEN operands
ORA-06550: line 5, column 4:
PL/SQL: Statement ignored

四、case表达式

--Case表达式与Case语句,如何理解呢?我们不妨来望文生义,便于记忆。分析如下:
--Case表达式,那么when 之后接的一定是表达式或一个特定值。
--Case语句,那么when之后接的特定一个语句,或函数,或计算表达式。既然是语句则一定带有分号。
--最后一点区别是case以end结束,而case语句则是以case end结束。

scott@ORCL> DECLARE
  2     v_num      NUMBER := &in_num;
  3     v_flag     NUMBER;
  4     v_result   VARCHAR2 (20);
  5     BEGIN
  6     v_flag := MOD (v_num, 2);
  7
  8     v_result :=
  9        CASE v_flag
 10           WHEN 0 THEN TO_CHAR (v_num) || ' is even number'
 11           WHEN 1 THEN TO_CHAR (v_num) || ' is odd number'
 12        END;
 13     DBMS_OUTPUT.put_line (v_result);
 14  END;
 15  /
Enter value for in_num: 3
3 is odd number

PL/SQL procedure successfully completed.

-->下面的写法也较为常用
scott@ORCL> SELECT ename,
  2         CASE deptno
  3            WHEN 20 THEN 'Developement'
  4            WHEN 30 THEN 'Sales'
  5            ELSE 'Clerk'
  6         END
  7            AS deptname
  FROM scott.emp;
  8
ENAME      DEPTNAME
---------- ------------
john       Clerk
Henry      Developement
ALLEN      Sales
WARD       Sales
..........

五、case嵌套

--case的嵌套就是case语句和表达式中嵌套case语句与表达式,理解了case的用法,case嵌套并不难。注意case与case end/end的匹配问题
--下面是一个使用case表达式演示的case嵌套示例。
--更新表emp中的comm列,首要case是根据部门来判断,其下又嵌套了一个case,根据comm值的不同来确定新的comm值。
UPDATE scott.emp
   SET comm =
          CASE deptno
             WHEN 20 THEN CASE
                             WHEN comm IS NULL THEN 500
                             WHEN comm < 200 THEN 300
                             ELSE 100
                          END
             WHEN 30 THEN CASE
                             WHEN comm IS NULL THEN 700
                             WHEN comm < 200 THEN 500
                             ELSE 200
                          END
             ELSE 1000
          END;

六、更多参考          

启用用户进程跟踪

父游标、子游标及共享游标

绑定变量及其优缺点

dbms_xplan之display_cursor函数的使用

dbms_xplan之display函数的使用

执行计划中各字段各模块描述

使用 EXPLAIN PLAN 获取SQL语句执行计划

启用 AUTOTRACE 功能

函数使得索引列失效

Oracle 绑定变量窥探



时间: 2024-08-03 14:44:47

CASE语句与CASE表达式的相关文章

mysql 存储过程case语句语法与实例教程

接着我们要讲的是关于mysql教程 存储过程case语句语法与实例教程哦,首页我们来看看case语句的简单说明,再以实例说明case的具体用法. case语句. case语句比起if要复杂了一些,它可以构造更复杂的条件. Case condtion           WHEN whenvalue THEN statlist         [when value then statmentlist]          [else statmentlist] end case or: case

图片-switch语句中各个case语句与default的次序不影响执行结果吗?

问题描述 switch语句中各个case语句与default的次序不影响执行结果吗? 解决方案 解决方案二: switch...case... 语句switch case 语句基础知识之switch case语句 解决方案三: http://zhidao.baidu.com/link?url=wmBFivbZ3tyO_HPJvx3coYKWoVtAhIXR8cfkaEU-Zea5u8nkB2Um5pwvPExjMCrihmtMY0N8dQ1si17IkSHW2K 解决方案四: 你的外层switc

MySQL中的if和case语句使用总结

 Mysql的if既可以作为表达式用,也可在存储过程中作为流程控制语句使用,如下是做为表达式使用: IF表达式 代码如下: IF(expr1,expr2,expr3) 如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),则 IF()的返回值为expr2; 否则返回值则为 expr3.IF() 的返回值为数字值或字符串值,具体情况视其所在语境而定. 代码如下: select *,if(sva=1,"男","女&qu

vba语句select case End Select

  一.Select Case语法及参数介绍 Select Case testexpression [Case expressionlist-n [statements-n]] ... [Case Else [elsestatements]] End Select Select Case 语句的语法具有以下几个部分: testexpression 必要参数.任何数值表达式或字符串表达式. expressionlist-n 如果有 Case 出现,则为必要参数.其形式为 expression,ex

MySQL中的if和case语句使用总结_Mysql

Mysql的if既可以作为表达式用,也可在存储过程中作为流程控制语句使用,如下是做为表达式使用: IF表达式 复制代码 代码如下: IF(expr1,expr2,expr3) 如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),则 IF()的返回值为expr2; 否则返回值则为 expr3.IF() 的返回值为数字值或字符串值,具体情况视其所在语境而定. 复制代码 代码如下: select *,if(sva=1,"男",&

VBS教程:VBScript 语句-Select Case 语句_vbs

Select Case 语句根据表达式的值执行几组语句之一. Select Case testexpression[Case expressionlist-n[statements-n]] . . .[Case Else expressionlist-n[elsestatements-n]]End Select 参数testexpression 任意数值或字符串表达式. expressionlist-n 如 Case 出现则必选项.一个或多个表达式的分界列表. statements-n 当 te

《Puppet实战手册》——2.10 使用选择器和case语句

2.10 使用选择器和case语句 虽然可以用if来编写任何条件语句,但Puppet还是提供提供了一些其他的形式来帮助用户更容易地编写表达条件语句:选择器(selecteor)和case语句. 操作步骤下面是一些关于选择器和case语句的例子. 1. 把下面的代码加入到配置清单中: $systemtype = $::operatingsystem ? { 'Ubuntu' => 'debianlike', 'Debian' => 'debianlike', 'RedHat' => 're

java中switch case语句的使用方法

switch语法  代码如下 复制代码 switch(表达式) { case 常量表达式1:语句1; .... case 常量表达式2:语句2; default:语句; } default就是如果没有符合的case就执行它,default并不是必须的. case后的语句可以不用大括号. switch语句的判断条件可以接受int,byte,char,short,不能接受其他类型. 一旦case匹配,就会顺序执行后面的程序代码,而不管后面的case是否匹配,直到遇见break,利用这一特性可以让好几

深入解析Swift中switch语句对case的数据类型匹配的支持_Swift

Swift可以对switch中不同数据类型的值作匹配判断: var things = Any[]() things.append(0) things.append(0.0) things.append(42) things.append(3.14159) things.append("hello") things.append((3.0, 5.0)) things.append(Movie(name:"Ghostbusters", director:"Iv