SQL server Where子句变量可能为空
我有以下查询(SQL server): 我的问题是,如果SQL server Where子句变量可能为空,sql,sql-server,Sql,Sql Server,我有以下查询(SQL server): 我的问题是,如果@UserId为空,查询将无法正确计算 如果变量为null或不为null,如何编写此查询以正确计算 编辑: 有许多关于使用以下内容的建议: WHERE (@UserId IS NULL OR userId = @UserId) 或类似的 在这种情况下,如果有一个包含3个条目的表,其中userId为1、2和3,变量'@userId'为NULL,则此查询将返回所有3个条目。实际上,我需要它返回的是没有条目,因为没有一个条目的userId为NU
@UserId
为空,查询将无法正确计算
如果变量为null或不为null,如何编写此查询以正确计算
编辑:
有许多关于使用以下内容的建议:
WHERE (@UserId IS NULL OR userId = @UserId)
或类似的
在这种情况下,如果有一个包含3个条目的表,其中userId为1、2和3,变量'@userId'为NULL,则此查询将返回所有3个条目。实际上,我需要它返回的是没有条目,因为没有一个条目的userId为NULL在阅读编辑后,我想您希望您的查询如下
SELECT *
FROM Users
WHERE COALESCE(userId ,0) = COALESCE(@UserId,0)
编辑:
正如Gordon Linoff和Larnu所指出的,上述查询在性能方面并不好,因为该查询是“不可搜索的”,为了获得更好的性能,可以将相同的查询编写为
SELECT *
FROM Users
WHERE userId = @UserId OR( userId is null and @UserId is null)
使用合并
SELECT *
FROM Users
WHERE userId = coalesce(@UserId,val)
您可以简化布尔逻辑:
WHERE (@UserId IS NULL OR userId = @UserId)
您需要使用
或:
DECLARE @UserId INT;
SET @UserId = //... set by dynamic variable
SELECT *
FROM Users
WHERE (userId = @UserId OR @UserId IS NULL);
但是,如果在存储过程中编写此代码、大量重用此代码或添加更多可为空的参数,则很可能会出现(严重的)性能问题。如果是,请在查询中包含选项(重新编译)
,以便每次运行时都生成查询计划。这将使用生成的查询计划停止数据引擎,该查询计划具有一组不同的NULL
参数
编辑:OP不清楚他们的问题。他们不希望为@UserID
传递值NULL
并返回所有行,他们希望传递NULL
并获取UserID
值为NULL
的行。这将是:
试试这个
DECLARE @UserId INT;
SET @UserId = //... set by dynamic variable
SELECT *
FROM Users
WHERE userId= (case when @UserId is null then userId else @UserId end)
我说如果'@UserId'为null,这将完全忽略where子句。它不会“忽略”where
no@Alex的,但是,如果@UserId
的值为null
,则@UserId为null的部分将计算为TRUE。由于userId=@userId
或
需要计算为TRUE,因此当@userId
的值为NULL
时,将返回所有行。如果有一个包含3个条目的表,其中userId为1,2和3,则变量'@userId'为NULL,我说的所有3行都将由where子句返回,对吗?为什么不测试@Alex?这里的语法也很简单;你有没有不明白的地方?(我只添加了或
,并且为空
,那么您对其中哪一个有问题?)我很抱歉,我应该这么做。我现在已经运行了它,它将带回所有记录。当'@userId'为null时,我只需要它返回userId为null的记录。我说的对吗?如果'@userId'为null,这将完全忽略where子句?在ISNULL之前使用COALESCE。很多原因,在我看来主要的一个原因是COALESCE是ANSI标准,而ISNULL不是。这里有一些支持性讨论:或者感谢@ChrisCarroll,我将浏览链接,但我的印象是,对于单个条件匹配,isnull更好。为此,我不支持COALESCE()
。我对数据中的值进行假设,这也使得查询不可搜索;这意味着随着表用户的增加,性能会越来越差。@GordonLinoff,谢谢你让我知道这一点,我已经适当地更新了答案。
SELECT *
FROM Users
WHERE UserID = @UserID
OR (UserID IS NULL AND @UserID IS NULL);
DECLARE @UserId INT;
SET @UserId = //... set by dynamic variable
SELECT *
FROM Users
WHERE userId= (case when @UserId is null then userId else @UserId end)