我希望当用户发送@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
答案 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 Shaw和Aaron Bertrand都针对这些“全部捕获”(或“厨房水槽”)查询撰写了文章,它们将提供很好的免费阅读。