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

how to check is null in case and if parameter is null then check value with IS NULL

我希望当用户发送 @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

使用简单的布尔逻辑:

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

WHERE 中使用像 (@Dispid IS NULL OR dispid = @Dispid ) 这样的语法会对性能产生 严重的 影响。这是因为SQL 服务器会根据第一个语句运行缓存查询计划。这意味着如果 @DispID 具有非 NULL 值,则当传递 NULL 值时,查询计划将严重低估查询中的行数。

因此,您可以使用 2 个选项来避免查询计划的不良缓存;但是我相信前者在现在 完全不受支持的 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 Shaw and Aaron Bertrand 都有关于这些 Catch-All(或 "Kitchen Sink")查询的文章,这将提供很好的补充阅读。

请尝试:

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