
在 oracle 中,where 子句内不能直接使用 case 语句实现条件逻辑判断;这是因为 case 是一个 ** 标量表达式 **,设计用于返回值(如数字、字符串),而非生成布尔真假条件。因此,当您在 where 中写入 case …… then condition1 else condition2 end 时,oracle 会报“ora-00905: missing keyword”等语法错误——本质是语法不合法,而非逻辑错误。
要实现“根据发票类型(’REN’/’TRS’)应用不同判断逻辑”的需求,正确做法是将 CASE 逻辑重构为标准的布尔逻辑组合,即使用括号明确分组的 AND/OR 结构:
AND ((ar_invoice_master.FK_INVOICE_TYPE_CODE NOT IN ('REN', 'TRS') AND ar_invoice_master.AR_INVOICE_OS_AMOUNT > 0) OR (ar_invoice_master.FK_INVOICE_TYPE_CODE IN ('REN', 'TRS') AND (ar_invoice_master.AR_INVOICE_OS_AMOUNT / ar_invoice_master.AR_INVOICE_TOTAL_AMOUNT * 100) <100) )
✅ 关键要点说明:
- 每个分支必须完整包含“类型判断 + 对应条件”,用 AND 连接;
- 整体用 OR 合并互斥分支,确保逻辑覆盖所有情况;
- 外层括号必不可少,避免运算符优先级干扰(如 AND 优先于 OR);
- 所有列名建议加上表别名前缀(如 ar_invoice_master.AR_INVOICE_OS_AMOUNT),提升可读性与健壮性;
- 注意除零风险:若 AR_INVOICE_TOTAL_AMOUNT 可能为 0,应在条件中前置校验,例如:
AND ar_invoice_master.AR_INVOICE_TOTAL_AMOUNT != 0
⚠️ 补充提醒:该查询还使用了过时的隐式 JOIN 语法(逗号分隔表名)。推荐升级为显式 JOIN 写法,提升可维护性与执行计划稳定性:
SELECT COUNT(1) FROM ar_invoice_master JOIN proposal_to_opportunity ON proposal_to_opportunity.FK_AR_INVOICE_ID = ar_invoice_master.AR_INVOICE_ID JOIN proposal ON proposal.PROPOSAL_ID = proposal_to_opportunity.FK_PROPOSAL_ID WHERE -- 动态金额条件(重构后)((ar_invoice_master.FK_INVOICE_TYPE_CODE NOT IN ('REN', 'TRS') AND ar_invoice_master.AR_INVOICE_OS_AMOUNT > 0) OR (ar_invoice_master.FK_INVOICE_TYPE_CODE IN ('REN', 'TRS') AND ar_invoice_master.AR_INVOICE_TOTAL_AMOUNT != 0 AND (ar_invoice_master.AR_INVOICE_OS_AMOUNT / ar_invoice_master.AR_INVOICE_TOTAL_AMOUNT * 100) <100) ) AND proposal.FK_GLUSR_USR_ID = :glid;
这种写法既符合 SQL 标准,又便于后续添加索引优化(例如在 (FK_INVOICE_TYPE_CODE, AR_INVOICE_OS_AMOUNT) 或(FK_INVOICE_TYPE_CODE, AR_INVOICE_TOTAL_AMOUNT)上建立复合索引)。






























