我有一个SQL语句,在WHERE cluse中有几个AND,我想知道我是否可以在WHERE子句下有一个IF THEN ELSE语句来确定将执行什么AND。
将向此查询传递三个参数
WHERE tlv.active = 1
AND tli.active = 1
AND t.endWorkShiftId IS NOT NULL
AND t.voidTypeId IS NULL
AND tlv.customerId = 1
AND tlv.locationId = 1
AND tlv.dockId = 3
IF ( :referenceId IS NULL ) {
AND tlv.vendorCldcId = :vendCldId
AND tlv.vendorId = :vendId
}
ELSE {
AND vru.refId = :referenceId
}
答案 0 :(得分:1)
不,没有IF。 CASE也不适用。但是你可以使用更复杂的布尔表达式:
WHERE tlv.active = 1
AND tli.active = 1
AND t.endWorkShiftId IS NOT NULL
AND t.voidTypeId IS NULL
AND tlv.customerId = 1
AND tlv.locationId = 1
AND tlv.dockId = 3
AND (
(
:referenceId IS NULL
AND tlv.vendorCldcId = :vendCldId
AND tlv.vendorId = :vendId
) OR (
:referenceId IS NOT NULL
AND vru.refId = :referenceId
)
)
<强>更新强>
顺便说一下:这种查询是一种性能反模式。复杂表达式阻止了大多数数据库系统中的高效表连接。
除此之外,您应该创建两个单独的,更简单的查询:一个用于referenceId IS NULL
,另一个用于referenceId IS NOT NULL
,并且可以调用其中一个。
答案 1 :(得分:1)
不,因为IF
是命令式语言构造,而SQL查询是根据逻辑谓词定义的(例如,它可以自动优化查询执行计划)。所以你可以达到同样的效果,你只需要在功能上思考&#34; (如在函数式语言中,如Haskell) - 增加了确保查询is still Sargable的难度。
在你的情况下,你可能想要这个:
...
AND
tlv.dockId = 3
AND
(
(
:referenceId IS NULL
AND
tlv.vendorCldcId = :vendCldId
AND
tlv.vendorId = :vendId
)
OR
(
:referenceId IS NOT NULL
AND
vru.refId = :referenceId
)
)
请注意,根据DBMS,这可能有一个次优的执行计划,因为查询引擎在依赖OR
时可能无法优化 - 替代:referenceId
条件,尤其是在MSSQL Server的情况下:
......一般建议似乎是为每个可能的参数集编写单独的查询。