SQL Server 是否支持短路 IF 语句?

17

我正在优化一些被频繁使用的存储过程,遇到了一个场景,让我产生了一个问题,但我找不到任何答案:在评估存储过程中的TSQL时,SQL Server是否会短路IF语句?

例如,假设一个存储过程有类似于以下代码:

IF @condition1 = 1
OR EXISTS(SELECT 1 FROM table1 WHERE column1 = @value1)
...

在这种情况下,SQL Server是否会短路计算,使得当前面的子句为true时EXISTS语句永远不会被执行?

如果它从不或只有有时会这样做,那么我们需要进行一些重写。


2
不保证。请检查执行计划以确定其在您的情况下是否有效。 - Martin Smith
谢谢,"不保证"正是我想要的。问题在于这些存储过程在数百个客户数据库上执行,因此如果执行计划确定了这一点,我们不能假设它将在每个客户系统上得到相同的评估并需要重写。 - competent_tech
1
如果你想要一个铁板钉钉的保证,那么将其分成多个 if 语句就可以做到。当我之前查看过这个问题时,我发现有一些例子没有短路。你也可以考虑使用 case 语句。 - Martin Smith
@MartinSmith:这是非常有用的信息,我非常喜欢使用case语句的方法。 - competent_tech
这个问题似乎在询问短路是否发生在查询之外。我看到的所有答案和链接都涉及到查询内部的情况。我猜在这种特殊情况下,短路确实会发生并且是有保障的,但我不确定。是否有人可以回答一下,在一个语句(不是像Where子句这样的东西)之外是否会发生短路? - Jules
2个回答

10
即使它看起来可以工作,也不应该依赖它。文档中指出的唯一短路语句是CASE语句,但即使这样也并非总是如此(嘿嘿)。以下是一个错误,幸运的是在SQL Server 2012中已经修复(请参阅评论)。
除了@Martin在问题评论中发布的链接外,您还应该查看这篇文章: 理解T-SQL表达式短路 以及与该文章相关的讨论论坛。

4
好消息是它似乎可以短路。以下是一个最小的示例:
DECLARE @condition1 bit = 1

IF (@condition1 = 1) OR EXISTS(SELECT 1 FROM sys.objects)
    PRINT 'True'
ELSE
    PRINT 'False'

@condition 的值为1时,执行计划如下:从sys.objects表中扫描了0行 execution plan 1 而当 @condition 的值为0时,它扫描了sys.objects表: execution plan 2 但不能保证每次都会是这种情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接