WHERE子句中使用CASE WHEN报错ORA-00905: 缺失关键字
问题解决:ORA-00905错误及SQL修正
错误原因分析
- 函数兼容性问题:你使用了SQL Server专属的日期函数(
GETDATE()、MONTH()、DATEADD、DATEDIFF),但Oracle不支持这些函数,直接导致语法解析失败。 - CASE语句用法错误:WHERE子句中,CASE表达式需要返回具体值,不能直接返回
oc.start_date > ...这类比较逻辑,Oracle无法识别这种写法,从而触发ORA-00905: missing keyword错误。
修正后的SQL
SELECT fp.object_id inv_id ,nvl(round(SUM((oc.finish_date - oc.start_date) * oc.slice)), 0) forecast_amt FROM odf_ssl_cst_dtl_cost oc LEFT JOIN fin_cost_plan_details fd ON fd.id = oc.prj_object_id LEFT JOIN fin_plans fp ON fp.id = fd.plan_id AND fp.plan_type_code = 'FORECAST' AND fp.is_plan_of_record = 1 WHERE oc.start_date > CASE WHEN EXTRACT(MONTH FROM SYSDATE) BETWEEN 1 AND 6 THEN ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 6) - 1 ELSE ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 18) - 1 END GROUP BY fp.object_id
关键说明
- 替换为Oracle兼容的日期函数:
SYSDATE:Oracle获取当前日期时间的函数,替代SQL Server的GETDATE()EXTRACT(MONTH FROM SYSDATE):提取当前月份,替代MONTH(GETDATE())TRUNC(SYSDATE, 'YYYY'):截断当前日期到当年1月1日,替代SQL Server的年初计算逻辑ADD_MONTHS(日期, 月数):实现日期加减月份,替代DATEADD(MONTH, ...)
- 重构CASE逻辑:让CASE返回需要对比的目标日期,再通过
oc.start_date >这个日期来满足业务需求:- 当前月份1-6月:目标日期为当年6月30日(年初加6个月得到7月1日,减1天即为6月30日)
- 当前月份7-12月:目标日期为下一年6月30日(年初加18个月得到下一年7月1日,减1天即为下一年6月30日)
内容的提问来源于stack exchange,提问作者Paxman
相关产品推荐
相关产品推荐

