Pri*_*ner 13 sql t-sql sql-server
我有一个关于2 SQL的问题:
declare @i1 bit, @b1 bit
declare @i2 bit, @b2 bit
declare @t table (Seq int)
insert into @t values (1)
-- verify data
select case when (select count(1) from @t n2 where 1 = 2) > 0 then 1 else 0 end
-- result 0
select @i1 = 1, @b1 = case when @i1 = 1 or ((select count(1) from @t n2 where 1 = 2) > 0) then 1 else 0 end from @t n where n.Seq = 1
select @i1, @b1
-- result 1, 0
select @i2 = 1, @b2 = case when @i2 = 1 or (0 > 0) then 1 else 0 end from @t n where n.Seq = 1
select @i2, @b2
-- result 1, 1
Run Code Online (Sandbox Code Playgroud)
在执行之前,我认为案例部分应该是null = 1 or (0 > 0)
,并且它将返回0
.
但现在,我想知道为什么第二个SQL会返回1
只是为了扩展@ Giorgi的答案:
请参阅此执行计划:
由于
@i2
首先评估(@ i2 = 1),case when @i2 = 1 or anything
返回1.
另请参阅此msdn条目:https://msdn.microsoft.com/en-us/library/ms187953.aspx和警告部分
如果单个SELECT语句中有多个赋值子句,则SQL Server不保证表达式的计算顺序.请注意,只有在分配中有引用时才会显示效果.
这一切都与内部优化有关.
我会将此作为答案发布,因为它是非常大的文本来自Training Kit (70-461)
:
WHERE propertytype = 'INT' AND CAST(propertyval AS INT) > 10
有些人认为除非优先规则另有规定,否则谓词将从左到右进行评估,并且在可能的情况下会发生短路.换句话说,如果第一个谓词propertytype ='INT'的计算结果为false,则SQL Server将不会计算第二个谓词CAST(propertyval AS INT)> 10,因为结果已知.基于这个假设,期望是查询应该永远不会尝试转换不可转换的东西.
然而,现实是不同的.SQL Server内部支持短路概念; 但是,由于 语言中的一次性概念,它不一定会以从左到右的顺序来评估表达式.它可以基于成本相关的原因决定从第二个表达式开始,然后如果第二个表达式的计算结果为true,则也可以计算第一个表达式.这意味着如果表中的行与propertytype不同于'INT',并且在那些行中propertyval不可转换为INT,则查询可能由于转换错误而失败.
归档时间: |
|
查看次数: |
1023 次 |
最近记录: |