2015-02-07 49 views
0

而不是做:基于select语句的案例?

select count(*) into l_count from mergetest where a = 1; 

case l_count 
    when 0 then 
    insert into mergetest (a,b) values (1,1); 
    when 1 then 
    update mergetest set b = b + 1 where a = 1; 
    else 
    NULL; 
    end case; 

我想摆脱局部变量l_count的,而是做:

case select count(*) from mergetest where a = 1; 
... 

这可能吗?

回答

1

不,这是不可能的。它与PL/SQL的CASE 控制结构无关,而与PL/SQL一般有关。你也不能在IF语句中使用它。

所以这个代码将无法编译之一:

IF (SELECT COUNT(*) FROM MY_TABLE) > 0 THEN ... 

请注意,您可以使用如果子查询CASE语句是表达一个SELECT中(或类似SQL)语句:

SEELCT 
    p.name, 
    CASE WHEN P.TYPE_ID = 1 THEN 
     (SELECT COUNT(*) FROM child c WHERE c.parent_id = p.id) 
    ELSE 0 
    END cnt 
FROM parent p; 

但是,当然,在一个表达式中,你不能使用诸如INSERT或UPDATE之类的语句。

+0

修复:可以 - >不能 – Roland 2015-02-07 15:22:40

+0

@罗兰:谢谢你指出。已经修复了。 – Codo 2015-02-07 15:25:07

0

现在看来似乎使用PL/SQL

从DOC

的CASE操作数的值,而不是可能的情况下操作数在简单情况下 语句可以比其他任何PL/SQL类型BLOB,BFILE,对象 类型,PL/SQL记录,索引表,varray或嵌套表。

http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/case_statement.htm

但是,您可以使用scalar subquery

select case when dummy = 'X' then (select count(*) from all_users) 
else (select count(*) from dual) 
end cnt from dual 

这可能会解决您的问题。

+0

我得到的错误消息: PLS-00103:出现符号“SELECT”在需要下列之一时: ( - +壳体模新不为空<标识符> <双引号delimited-标识符>绑定变量> 继续avg计数当前存在的最大分钟前的sql stddev – Roland 2015-02-07 15:10:00

+0

不,仍然错误 – Roland 2015-02-07 15:15:47

+0

@Roland看到新的编辑 – 2015-02-07 15:20:56

1

这是可能的,通过使用merge,不case摆脱局部变量:

merge into mergetest 
    using (select 1 a from dual) ins 
    on (mergetest.a = ins.a) 
    when matched then 
    update set mergetest.b = mergetest.b + 1 
     where (select count(1) from mergetest where mergetest.a = ins.a) = 1 
    when not matched then insert (mergetest.a, mergetest.b) 
    values (ins.a, 1) 

线:

 where (select count(1) from mergetest where mergetest.a = ins.a) = 1 

防止更新,如果a表超过一次已经存在。

+0

是的,但代码变得难以理解。你顺便说一句回答我的其他问题: http://stackoverflow.com/questions/28382332/merge-statement-but-update-only-if-exactly-one-row-matches – Roland 2015-02-09 08:31:22