在where子句中使用case

时间:2014-06-16 17:45:56

标签: sql oracle plsql

我正在尝试创建一个名为m_reaplicacao的参数的过程。此参数接收值“S”表示“是”,“N”表示“否”,“T”表示所有记录。 当参数为是时,我应该返回值等于9的记录。 当参数为No时,我应该返回不同于9的记录。最后,当值为All时,我应该返回表中的所有记录。 使用下面的代码,Oracle说: PROCEDURE MYDB.CONTAS_A_PAGAR_SPS的编译错误 错误:PL / SQL:ORA-00905:缺少关键字 行:84 文字:ta.id_1a_cbr = 9;

    select * from proposta ta
    where 
          ta.estado = 'RJ'
          and case
               when m_reaplicacao = 'S' then
                    ta.id_1a_cbr = 9;
               when m_reaplicacao = 'N' then
                    ta.id_1a_cbr <> 9
               else null
          end case; 

我看了很多帖子,但我没有解决这个问题。 请有人帮帮我吗?

3 个答案:

答案 0 :(得分:7)

当你真的想要一个简单的布尔评估组合时,不要在CASE子句中使用WHERE语句。

WHERE ta.estado = 'RJ'
  AND (    m_reaplicacao = 'T'
       OR (m_reaplicacao = 'S' AND ta.id_1a_cbr = 9)
       OR (m_reaplicacao = 'N' AND ta.id_1a_cbr <> 9)
      )

如果由于某种原因您确实想要使用CASE语句,则需要CASE返回您在WHERE子句中检查的值。例如

WHERE ta.estado = 'RJ'
  AND (CASE WHEN m_reaplicacao = 'S' AND ta.id_1a_cbr = 9 
            THEN 1
            WHEN m_reaplicacao = 'N' AND ta.id_1a_cbr <> 9 
            THEN 1
            WHEN m_reaplicacao = 'T'
            THEN 1
            ELSE 2
        END) = 1

然而,这通常不是表达这种情况的最明确的方式。

答案 1 :(得分:1)

您无法在CASE语句中返回表达式,最容易添加其他WHERE条件集:

select * 
from proposta ta
where ta.estado = 'RJ'
  and (
         (m_reaplicacao = 'S' AND ta.id_1a_cbr = 9)
      OR (m_reaplicacao = 'N' AND ta.id_1a_cbr <> 9)
       )

不确定您希望在NULL情况下发生什么。

答案 2 :(得分:0)

您可以在select语句中使用CASE,如下所示:

with d as (
  select 'A' as val from dual
  union
  select 'B' as val from dual
  union
  select 'C' as val from dual
)
select *
from d
where 
    case 
        when val = 'A' then 1
        when val = 'B' then 1
        when val = 'Z' then 1
    end = 1; 

这里我们正在寻找val in('A','B','Z')的行。在这个例子中,它是另一种写作方式:

select ... where val in ('A','B','Z');