oracle where子句用case的时候

时间:2017-10-24 19:15:45

标签: sql oracle case

我正在努力避免使用动态sql。我需要检查参数中的值,并根据它来应用正确的子句。

例如:

select * from table
WHERE 1 =
CASE
    WHEN channel = 1 AND REGEXP_LIKE(LOGIN, '[[:digit:]]') THEN 1--only numbers
    WHEN channel = 2 AND LOGIN LIKE 'MI|%' THEN 1
    WHEN channel = 3 AND LOGIN NOT LIKE 'MI|%' AND NOT REGEXP_LIKE(LOGIN, '^\d+(\.\d+)?$', '') THEN 1 --except what is being filtered on case 1 and 2
    ELSE 0
END    

来自LOGIN栏的DATA样本:

VIC.A67923
2013836
257551
GAB.A53272
MI|1234
MI|5345

单独运行过滤器,它们工作正常,但测试为参数指定了正确的值,它返回了错误的数据。

e.g。当传递1时,它应该只返回那些有数字的数据,但它返回的数据也包含数据。

2 个答案:

答案 0 :(得分:3)

您没有锚定并重复数字检查。将其锚定到字符串的开头和结尾。并且所有案例都返回1,因此最终无效

SELECT *
  FROM tablea
 WHERE 1 = CASE WHEN channel = 1 AND REGEXP_LIKE (login, '^[[:digit:]]*$')
               THEN 1                                                                                      --only numbers
               WHEN channel = 2 AND login LIKE 'MI|%'
               THEN 1
               WHEN channel = 3 AND login NOT LIKE 'MI|%' AND NOT REGEXP_LIKE (login, '^\d+(\.\d+)?$', '')
               THEN 1                                                     --except what is being filtered on case 1 and 2
               ELSE 1
           END

答案 1 :(得分:1)

将您的案例更改为

CASE
    WHEN channel = 1 AND REGEXP_LIKE(LOGIN, '[[:digit:]]') 
        THEN 1--only numbers
    WHEN channel = 2 AND LOGIN LIKE 'MI|%' 
        THEN 2
    WHEN channel = 3 AND LOGIN NOT LIKE 'MI|%' AND NOT REGEXP_LIKE(LOGIN, '^\d+(\.\d+)?$', '') 
        THEN 3 --except what is being filtered on case 1 and 2
    ELSE 4
END

或者,如果channel是输入参数:

WHERE channel =
    CASE
        WHEN REGEXP_LIKE(LOGIN, '[[:digit:]]') 
            THEN 1--only numbers
        WHEN LOGIN LIKE 'MI|%' 
            THEN 2
        WHEN LOGIN NOT LIKE 'MI|%' AND NOT REGEXP_LIKE(LOGIN, '^\d+(\.\d+)?$', '') 
            THEN 3 --except what is being filtered on case 1 and 2
        ELSE 4
    END