Oracle WHERE子句多条件CASE语句报ORA-00905缺失关键字问题
问题根因
- 语法逻辑错误:Oracle的
CASE是返回具体值的表达式,不支持在THEN/ELSE分支直接返回布尔判断条件,你当前的写法相当于让CASE返回一组WHERE过滤规则,不符合SQL语法要求,这是触发ORA-00905的核心原因。 - 细节语法问题:ELSE分支的括号没有闭合,且
to_char(sysdate,'Day')返回的字符串默认带尾部空格填充(固定长度9位),直接和'Sunday'判等会匹配失败。 - 冗余逻辑:两个分支里的月份、年份判断完全可以合并,不需要重复写。
最优解决方案(推荐,可走索引)
不需要用CASE,直接用OR逻辑拼接判断条件即可,写法更简洁性能更好:
FROM lea_nf1.lea_agreement_dtl c WHERE -- 共用的年月过滤 to_char(C.DISBURSALDATE , 'mm') = to_char(sysdate-1, 'mm') AND to_char(C.DISBURSALDATE , 'yyyy') = to_char(sysdate-1, 'yyyy') AND ( -- 周日则取近3天(到昨天为止) (trim(to_char(sysdate,'Day')) = 'Sunday' AND C.DISBURSALDATE between trunc(sysdate-3) and trunc(sysdate-1)) -- 非周日只取昨天 OR (trim(to_char(sysdate,'Day')) != 'Sunday' AND trunc(C.DISBURSALDATE) = trunc(sysdate-1)) ) ORDER BY C.DISBURSALDATE desc
强制使用CASE的修正写法
如果业务场景必须要使用CASE实现,需要把判断逻辑改成CASE返回值和字段匹配的形式:
FROM lea_nf1.lea_agreement_dtl c WHERE to_char(C.DISBURSALDATE , 'mm') = to_char(sysdate-1, 'mm') AND to_char(C.DISBURSALDATE , 'yyyy') = to_char(sysdate-1, 'yyyy') AND C.DISBURSALDATE <= trunc(sysdate-1) AND C.DISBURSALDATE >= CASE trim(to_char(sysdate,'Day')) WHEN 'Sunday' THEN trunc(sysdate-3) ELSE trunc(sysdate-1) END ORDER BY C.DISBURSALDATE desc
内容的提问来源于stack exchange,提问作者Sulzehq
相关产品推荐
相关产品推荐

