SQL Server其中Clause变量可以为空

时间:2019-01-31 09:47:54

标签: sql sql-server

我有以下查询(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

5 个答案:

答案 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)