在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 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)上建立复合索引)。