在SQL中比较NULL或值的有效方法

时间:2010-06-24 14:39:13

标签: sql-server tsql comparison null

在SQL查询中检查列的null或值的有效方法是什么。考虑具有整数列table的sql表column,其具有索引。 @value可以是某个整数或null ex:16或null。

查询1:不确定,但似乎不应该依赖SQL中的短路。但是,当@value为某个整数或null时,下面的查询始终可以正常工作。

select * from
table
where (@value is null or column = @value)

以下查询是上述查询的扩展版本。它也正常工作。

select * from 
table 
where ((@value is null) 
    or (@value is not null and column = @value))

以上2个查询是否会利用索引?

查询2:以下查询将列与非空@value进行比较,否则将列column与其自身进行比较,该列始终为true并返回所有内容。它也正常工作。这个查询会利用索引吗?

select * from
table
where (column = isnull(@value, column))

最好的方法是什么?

注意:如果答案因数据库而异,我对MS-SQL感兴趣。

2 个答案:

答案 0 :(得分:2)

在过去的几天里,这个问题的变化多次出现(为什么这些事情总是在小组中发生?)。简而言之,是的,SQL Server将使用已知值创建查询计划的逻辑短路。因此,如果您在设置变量的脚本中有该代码,那么我认为它应该使逻辑短路(测试以确保)。但是,如果它在存储过程中,则SQL Server将提前创建查询计划,并且它不知道它是否可以使查询短路,因为它在生成时不知道参数值查询计划。

无论是否短路,SQL Server都应该能够使用索引,如果这是查询的唯一部分。如果变量为NULL,那么您可能不希望SQL Server使用索引,因为它将是无用的。

如果您在存储过程中,那么最好的办法是在查询中使用OPTION(RECOMPILE)。这将导致SQL Server每次都创建一个新的查询计划。这有点开销,但收益通常会大大超过这一点。这仅适用于SQL 2008,甚至只适用于某些后续的Service Pack。在使用它之前,RECOMPILE存在一个错误。有关更多信息,请查看Erland Sommarskog关于此主题的great article。具体来说,您需要查看静态SQL部分。

答案 1 :(得分:1)

为了澄清一点,SQL并不像我们在基于C语言中所知的那样短路。看起来像是短路的是SQL Server三元逻辑TRUE OR NULL评估为TRUE

TRUE OR NULL ===> TRUE
TRUE AND NULL ===> NULL

例如:

if 1=null or 1=1 print 'true' else print 'false'
if 1=null and 1=1 print 'true' else print 'false'