CASE语句与CASE表达式_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2259 | 回复: 0   主题: CASE语句与CASE表达式        下一篇 
leixianp
注册用户
等级:新兵
经验:57
发帖:64
精华:0
注册:2011-7-26
状态:离线
发送短消息息给leixianp 加好友    发送短消息息给leixianp 发消息
发表于: IP:您无权察看 2015-7-22 10:06:40 | [全部帖] [楼主帖] 楼主

case语句与case表达式是plsql流程控制的重要组成部分,尽管其使用方法较为简单,但容易混淆。

一、简单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;

ENDCASE;

--简单的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     ENDCASE;

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;

ENDCASE;

--搜索式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     ENDCASE;

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     ENDCASE;

12  END;

13  /

Enter value for in_num: 0

DECLARE

*

ERROR at line 1:

ORA-06592: CASEnot found while executing CASE statement

ORA-06512: at line 4

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

--相同点:两者都用于根据不同的条件,来执行与之对应的语句或完成特定的任务,甚至某些情况下可以互换替换。

--不同点: 

--简单case语句提供一个selector选择器,且EXPRESSION的数据类型一定与selector的数据类型匹配,否则报错。

--搜索case语句没有selector选择器,且when子句之后得到的结果一定是一个布尔型值(NULL,TRUR,FALSE)

--下面的例子是一个简单case与搜索case之间互换的例子,同时该方式也实现了行到列的转行。

scott@ORCL> selectsum(casewhen deptno=20 then sal endas sal_sum_20,   

-->搜索式case表达式 @20150713更正

2  sum(casewhen 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> selectsum(case deptno when 20 then sal endas 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     ENDCASE;

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'betweenCASE operand andWHEN 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 THENCASE

WHEN comm ISNULLTHEN 500

WHEN comm < 200 THEN 300

ELSE 100

END

WHEN 30 THENCASE

WHEN comm ISNULLTHEN 700

WHEN comm < 200 THEN 500

ELSE 200

END

ELSE 1000

END;

--转自 北京联动北方科技有限公司




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论