我正在尝试执行 SQL 查询并根据参数是否为空或否动态构建 where 条件。我有这样的东西:
SELECT tblOrder.ProdOrder, tblOrder.Customer FROM tblOrder
CASE WHEN @OrderId IS NOT NULL
THEN
WHERE tblOrder.OrderId = @OrderId
ELSE
END
CASE WHEN @OrderCustomer IS NOT NULL
THEN
AND tblOrder.OrderCustomer = @OrderCustomer
ELSE
END
END
这不起作用,但这只是如何组装查询的一个小原型,因此如果 orderid 不为 null 则包含在 where 子句中,或者如果 ordercustomer 不为 null 则包含在 where 子句中。但我在这里看到了问题,例如如果 ordercustomer 不为 null 但 orderid 为 null,则会出现错误,因为不包含 where 关键字。
我该如何解决这个问题?
这应该可以满足你的要求:
SELECT tblOrder.ProdOrder, tblOrder.Customer
FROM tblOrder
WHERE ( @OrderId IS NULL OR tblOrder.OrderId = @OrderId )
AND ( @OrderCustomer IS NULL OR tblOrder.OrderCustomer = @OrderCustomer )
OPRION (RECOMPILE)
但是正如评论所述,您应该包含 OPTION RECOMPILE 提示,否则性能会很差。
值得一读:
无法动态编写
WHERE
子句,但可以使用复合语句来达到预期效果。
由于在 SQL 中 NULL
never 等于任何值,因此您实际上可以实现非常优雅的查询:
SELECT tblOrder.ProdOrder, tblOrder.Customer
FROM tblOrder
WHERE
-- Can only be true if @OrderId isn't NULL, no need to state it explicitly
tblOrder.OrderId = @OrderId
OR
-- Thanks to short-circuit evaluation,
-- we only get here if the first condition evaluated as false
tblOrder.OrderCustomer = @OrderCustomer
这个查询是完全错误的。格式化后,您可以看到有“空白”
ELSE
语句,并且末尾有额外的END
:):
SELECT
tblOrder.ProdOrder, tblOrder.Customer
FROM tblOrder
CASE
WHEN @OrderId IS NOT NULL THEN WHERE tblOrder.OrderId = @OrderId
ELSE
END
CASE
WHEN @OrderCustomer IS NOT NULL THEN AND tblOrder.OrderCustomer = @OrderCustomer
ELSE
END
END
此外,您无法从
WHERE
返回 CASE
子句。
用这个代替。它更简单,而且有效;)。
SELECT
tblOrder.ProdOrder, tblOrder.Customer
FROM tblOrder
where
tblOrder.OrderId = @OrderId
OR
tblOrder.OrderCustomer = @OrderCustomer
如果您设置了
NULL
,您甚至不必担心这两个变量都是 ANSI_NULLS
。默认情况下,Sql Server 不会匹配记录,其中 NULL=NULL
。