Sql 存储过程中的可选参数-案例与或

Sql 存储过程中的可选参数-案例与或,sql,sql-server,tsql,Sql,Sql Server,Tsql,这些过滤方法在性能方面是否存在差异 Method 1: WHERE (@Col1 IS NULL OR t.column = @Col1) Method 2: WHERE 1 = case when @col1 is null then 1 else case when col1 = @col1 then 1 else 0 end end 为什么不使用合并 Where Col1 = Coalesce(@Col1, Col1) 编辑:(点击Joel下面的评论)只有当col1不允许空值,或

这些过滤方法在性能方面是否存在差异

Method 1: WHERE (@Col1 IS NULL OR t.column = @Col1) 


Method 2: WHERE 1 = case when @col1 is null then 1 else case when col1 = @col1 then 1 else 0 end end
为什么不使用合并

Where Col1 = Coalesce(@Col1, Col1)
编辑:(点击Joel下面的评论)只有当col1不允许空值,或者如果它允许空值,并且当@col1为空或不存在时,您希望将空值排除在外时,这才有效。因此,如果@Col1参数为null或不存在时,它允许null,并且您希望包含它们,那么请按如下方式修改:

 Where Coalesce(@Col1, Col1) Is Null Or Col1 = Coalesce(@Col1, Col1)  

如果知道Col1列本身不包含任何空值,可以执行以下操作:

WHERE Col1 = COALESCE(@Col1, Col1)
否则,您的案例陈述通常应该比OR做得好一点。我强调“典型”是因为每个表都不同。您应该始终配置文件以确定


不幸的是,通常最快的方法是在参数为null时首先使用动态sql从查询中排除条件。但当然,把它作为最后的优化手段。

是的。案例有一个有保证的执行顺序,而不是。许多程序员依赖或短路,并且惊讶地发现,像SQL这样的面向集合的声明性语言不能保证布尔运算符短路

也就是说,在WHERE子句中使用OR和CASe是一种不好的做法。将条件分隔为一个clear IF语句,并对每个分支进行单独查询:

IF @col1 IS NOT NULL
  SELECT ... WHERE col1 = @col1;
ELSE
  SELECT ... WHERE <alternatecondition>;
如果@col1不为空
选择。。。其中col1=@col1;
其他的

选择。。。哪里在这里,您会发现一个简单的反例,表明布尔短路不仅是不保证的,而且依赖它实际上可能非常危险,因为它可能会导致运行时错误

,如果列中有任何空值(NULL=NULL返回false),则会失败。否则,这是一个好的选择,尽管如此。因为以这种方式使用COALESCE将启动基于列的扫描或查找,(@Col为NULL或t.column=@Col)不会。但这会削弱可搜索性,使动态SQL成为最佳选择。因为以这种方式使用合并将启动基于列的扫描或搜索,(@Col为NULL或t.column=@Col)不会。但这会削弱可访问性,使动态SQL成为最佳选项。方法1实际上应为:(@Col1为NULL或t.column=@Col1)在与列值进行比较后检查参数是否为NULL是一种浪费。实际上,这是不正确的-SQL确实进行短路计算-举例说明,尝试以下操作:选择“短路”,其中1=1或1/0=0@Rob:特定示例不等于“保证”。我已经看到无数的问题报告给PSS,这些问题源于假设布尔短路。Nigel在(相当老的)聊天中说的是SQL允许短路,但没有说它保证短路。