是MS-SQL AND/OR条件(执行短路评估)?

Mr *_*ach 3 sql-server stored-procedures

我正在创建一个存储过程(简化)

create procedure sp_mysp @p1 bit AS
if (@p1 = 1 AND EXISTS(select  * from mytable1))
BEGIN....END
ELSE IF (@p = 0 AMD EXISTS(select * from mytable2))
BEGIN....END
Run Code Online (Sandbox Code Playgroud)

所以问题是,SQL总是会检查mytable1中的数据,还是只检查mytable1中的数据,如果@ p1等于1

(类似于&#in c#)

Mar*_*ith 6

无法保证此行为.

没有发生短路评估的一个例子expr1 AND expr2

SET STATISTICS IO ON

IF EXISTS(SELECT COUNT(*) FROM master..spt_monitor HAVING COUNT(*)=2)  
AND EXISTS (SELECT COUNT(*) FROM master..spt_values HAVING COUNT(*)=1)
PRINT 'Y'
Run Code Online (Sandbox Code Playgroud)

EXISTS(SELECT COUNT(*) FROM master..spt_monitor HAVING COUNT(*)=2)IS false(意味着And-ed表达式必须是False),但是IO结果表明所述第二条件仍然评价.

Table 'spt_values'. Scan count 1, logical reads 14, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'spt_monitor'. Scan count 1, logical reads 1, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Run Code Online (Sandbox Code Playgroud)

SQL Server 可以做到这一点.我在测试中看到了这一点

SET STATISTICS IO ON

DECLARE @p1 BIT = NULL

IF ( @p1 = 1
     AND EXISTS(SELECT *
                FROM   master..spt_values) )
  PRINT '1'

ELSE IF ( @p1 = 0
     AND EXISTS(SELECT *
                FROM   master..spt_values) )
  PRINT '2'
Run Code Online (Sandbox Code Playgroud)

输出是

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)
Run Code Online (Sandbox Code Playgroud)

显示spt_values从未访问过.

这是通过执行计划中的传递谓词条件来实现的.这里有一些关于这些的信息.

如果passthru谓词的计算结果为true,则join返回行....如果passthru谓词的计算结果为false,则连接正常进行

在此输入图像描述