我正在创建一个存储过程(简化)
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
所以问题是,如果@p1 等于 1,SQL 会一直检查 mytable1 中的数据还是只检查 mytable1 中的数据
(类似于c#中的&&)
最佳答案
无法保证这种行为。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'
EXISTS(SELECT COUNT(*) FROM master..spt_monitor HAVING COUNT(*)=2)
是 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.
不过,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'
输出是
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)
显示
spt_values
从未被访问过。这是通过执行计划中的传递谓词条件实现的。有一些关于那些here的信息.
If the passthru predicate evaluates to true, the join returns the row .... If the passthru predicate evaluates to false, the join proceeds normally
关于sql-server - MS-SQL AND/OR 是否有条件(执行短路评估)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46134872/