我有以下查询(SQL Server):
DECLARE @UserId INT;
SET @UserId = //... set by dynamic variable
SELECT *
FROM Users
WHERE userId = @UserId
我的问题是,如果@UserId
为null,则查询将无法正确评估。
如果变量为null或不为null,如何编写此查询以正确评估?
编辑:
有很多建议使用以下内容:
WHERE (@UserId IS NULL OR userId = @UserId)
或类似。
在这种情况下,如果存在一个包含3个条目的表,其中userId为1,2,3变量'@UserId'为NULL,则此查询将返回所有3个条目。我实际上需要它返回的是没有条目,因为它们都没有userId为NULL
答案 0 :(得分:1)
阅读编辑后,我想您希望像这样的查询
SELECT *
FROM Users
WHERE COALESCE(userId ,0) = COALESCE(@UserId,0)
编辑:
正如 Gordon Linoff 和 Larnu 所指出的那样,上述查询在性能方面并不理想,因为该查询是“非SARGable”的,因此性能更好查询可以写为
SELECT *
FROM Users
WHERE userId = @UserId OR( userId is null and @UserId is null)
答案 1 :(得分:1)
使用合并
SELECT *
FROM Users
WHERE userId = coalesce(@UserId,val)
答案 2 :(得分:1)
您需要使用OR
:
DECLARE @UserId INT;
SET @UserId = //... set by dynamic variable
SELECT *
FROM Users
WHERE (userId = @UserId OR @UserId IS NULL);
但是,如果您在存储过程中编写此代码,重用此代码很多或添加更多可空参数,则很可能会遇到(严重)性能问题。如果是这样,请在您的查询中包括OPTION (RECOMPILE)
,以便在每次运行时生成查询计划。这将使用生成的查询计划停止数据引擎,该查询计划具有一组不同的NULL
参数。
编辑:操作员不清楚他们的问题。他们不想传递NULL
的值@UserID
并返回所有行,他们想传递NULL
并获得其中UserID
的值为{{1 }}。那应该是:
NULL
答案 3 :(得分:0)
您可以改为简化布尔逻辑:
WHERE (@UserId IS NULL OR userId = @UserId)
答案 4 :(得分:0)
尝试一下
DECLARE @UserId INT;
SET @UserId = //... set by dynamic variable
SELECT *
FROM Users
WHERE userId= (case when @UserId is null then userId else @UserId end)