如何解决SQL where子句在过滤器为null的情况下返回所有内容
我在下面有一个sql表-
store.getState()
我正在尝试通过以下两种条件将表中的所有记录- a)如果“ @Value”列上的过滤器为空,如下所示,则它应返回所有记录,包括空
SrNo Name Value
1 A X1
2 B NULL
3 C X3
4 D X4
5 E NULL
6 F NULL
b)如果提供的@Value不为null,则应返回该列(这肯定有效)
我试图实现以下条件
BEGIN
Declare @Value varchar(50)
SET @Value = NULL
SELECT * from TestTable where Value = @Value
END
但是上面也删除了Null列。任何帮助或建议将不胜感激。
解决方法
典型的方法是根据是否提供了参数使用OR
:
WHERE (Value = @Value OR @Value IS NULL);
但是,这可能会带来问题,因为您会基于第一个调用获得针对此查询的一个执行计划。这意味着,如果第一个调用指定了@Value = 1
,并导致了索引查找,则第二个调用将在参数为NULL时获取索引查找(并且您不会喜欢该索引的性能) )。在另一个方向上类似,第一个参数为NULL,因为要返回整个表,所以将进行扫描,但是在第二次调用中,当您只想要一个(或很少)行时,您将仍然要进行扫描。
对此的典型反应是“添加OPTION (RECOMPILE);
”!
这很不错,除非Value
是唯一的,或者总是具有很少的任何给定值,并且您不断用显式值调用查询,从而导致较小的查找,因此您要重新编译每次都没有查询。而且每次需要扫描时,每次都将重新编译该查询,也一无所获。
这种带有可选搜索参数的“厨房水槽”类型的查询的折衷方案是使用动态SQL(以不可注入的方式进行此操作很重要):
DECLARE @sql nvarchar(max) = N'SELECT ... FROM dbo.TestTable';
IF @Value IS NOT NULL
BEGIN
SET @sql += N' WHERE Value = @Value';
END
SET @sql += N';';
EXEC sys.sp_executesql @sql,N'@Value varchar(50)',@Value;
现在,您有两个不同的查询,它们将在两种不同的情况下按预期执行,而无需重新编译。如果您有可能会歪斜的数据(某些Value
值可以更好地用作扫描或不同的平面形状),则可以重新编译在这种情况下:
SET @sql += N' WHERE Value = @Value OPTION (RECOMPILE)';
如果您知道有特殊值或不会导致问题,或者如果您有多个参数并且某些参数违反唯一列而其他参数则没有,您甚至可以执行此操作。
更多信息:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。