简体   繁体   中英

Using case inside where clause

I´m trying to create a procedure that has a parameter called m_reaplicacao. This parameter receives the values 'S' for Yes, 'N' for No and 'T' for all records. When the parameter is Yes, I should return the records with value equals to 9. When the parameter is No, I should return the records different of 9. And finally, when the the value is All, I should return all records from the table. With the code bellow, Oracle says: Compilation errors for PROCEDURE MYDB.CONTAS_A_PAGAR_SPS Error: PL/SQL: ORA-00905: missing keyword Line: 84 Text: 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; 

I saw a lot of posts, but I did not solve this one. Can someone help me, please?

Don't use a CASE statement in a WHERE clause when you really want a simple combination of boolean evaluations.

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)
      )

If for some reason you really do want to use a CASE statement, you'd need the CASE to return a value that you check in the WHERE clause. For example

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

This is not generally the clearest way to express this sort of condition, however.

You cannot return expressions in CASE statements, easiest to add additional WHERE criteria sets:

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)
       )

Not sure what you want to happen in the NULL situation.

You can use CASE in select statements, like this:

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; 

Here we're looking for rows where val in ('A','B','Z'). In this example, its another way of writing:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM