如果参数为null,如何检查是否为null,然后使用IS NULL检查值

时间:2019-11-07 12:29:13

标签: sql sql-server sql-server-2008

我希望当用户发送@dispid null时,它将在DISPID = IS NULL的where子句中检查;当用户发送任何值时,它将在下面的查询中使用该值进行检查。这里DISPID是int类型,允许为空

SELECT *
FROM orde_ 

WHERE
  CANCELLED = 0
  AND DISPID =CASE WHEN @DISPID IS NULL THEN '' ELSE @DISPID END -- HERE i trying to implement

3 个答案:

答案 0 :(得分:2)

使用简单的布尔逻辑:

where cancelled = 0 and
      (@dispid is null or dispid = @dispid)

答案 1 :(得分:2)

请尝试:

WHERE CANCELLED = 0 AND
    ((DISPID IS NULL and @DISPID IS NULL) OR DISPID=@DISPID)

答案 2 :(得分:0)

(@Dispid IS NULL OR dispid = @Dispid )中使用WHERE之类的语法可能会严重影响性能。这是因为SQL Server将基于第一次运行语句来缓存查询计划。这意味着,如果@DispID的值不为NULL,则当传递NULL值时,查询计划将严重低估查询中的行数。

因此,有两个选项可用于避免查询计划的错误缓存;但是我相信,现在完全不受支持的2008版本中不存在前者。

第一个(请注意)使用OPTION RECOMPILE;这将强制在每次运行查询时重新创建查询计划。这更容易编写,但是,以不缓存计划为代价:

SELECT ...
FROM ...
WHERE Cancelled = 0
  AND (@Dispid IS NULL OR dispid = @Dispid)
OPTION (RECOMPILE);

第二种是使用动态语句:

DECLARE @SQL nvarchar(MAX),
        @CRLF nchar(2) = NCHAR(13) + NCHAR(10);

SET @SQL = N'SELECT Column1,' + @CRLF +
           N'       ...,' + @CRLF + --....etc
           N'FROM ...' + @CRLF +
           N'WHERE Cancelled = 0' +
           CASE WHEN @DispID IS NOT NULL THEN @CRLF + N'  AND DispID = @Disp' ELSE N'' END + N';'

EXEC sp_executesql @SQL, N'@DispID int', @DispID; --@DispID data type guessed

这样做的优点是,不同的语句将具有不同的缓存计划,不需要每次都重新创建,但是,对于某些人而言,它并不那么容易理解。

Gail ShawAaron Bertrand都针对这些“全部捕获”(或“厨房水槽”)查询撰写了文章,它们将提供很好的免费阅读。