Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带子查询的SQL赋值变量_Sql_Sql Server_Tsql - Fatal编程技术网

带子查询的SQL赋值变量

带子查询的SQL赋值变量,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个关于以下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, @

我有一个关于以下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

在执行之前,我认为case部分应该是
null=1或(0>0)
,它将返回
0


但是现在,我想知道为什么第二个SQL会返回1,只是为了扩展@Giorgi的答案:

见本执行计划: 由于首先对
@i2
求值(@i2=1),
当@i2=1或任何东西返回1时的情况

另请参见本msdn条目:和注意事项部分

如果单个SELECT语句中有多个赋值子句, SQL Server不保证计算的顺序 表达。请注意,只有在存在 作业中的参考资料


这一切都与内部优化有关。

我将把它作为一个答案发布,因为它是来自
培训工具包(70-461)
的一篇相当大的文本:

其中propertytype='INT'和CAST(propertyval AS INT)>10

有些人认为,除非优先规则另有规定,否则谓词 将从左到右进行评估,短路将 在可能的情况下进行。换句话说,如果第一个谓词 propertytype='INT'的计算结果为false,SQL Server不会计算 第二个谓词强制转换(propertyval AS INT)>10,因为结果是 已经知道了。基于这一假设,我们期望 查询在尝试转换不存在的内容时应该不会失败 敞篷车

然而,现实情况却不同。SQL Server确实如此 内部支持短路概念;然而,由于 一次完成概念在语言中,它不一定会 按从左到右的顺序计算表达式。它可以决定, 基于成本相关的原因,从第二个表达式开始, 然后,如果第二个表达式的计算结果为true,则 第一个表达也是。这意味着如果 propertytype与“INT”不同的表,以及这些行中的 propertyval不能转换为INT,查询可能会由于 转换错误


只是为了扩展这两个答案

发件人:

外壳不会总是短路

官方文档暗示整个表达式将短路,这意味着它将从左到右计算表达式,并在匹配时停止计算:

The CASE statement  evaluates its conditions sequentially and stops with the
first condition whose condition is satisfied.
和MS Connect:

CASE语句按顺序计算其条件,并以满足条件的第一个条件停止。在某些情况下,在CASE语句接收表达式的结果作为其输入之前对表达式求值计算这些表达式时可能出现错误。


变量的顺序。检查。当你有
选择@b2=case当@i2=1或(0>0)时,然后选择1其他0结束,@i2=1
你将得到1,0我更感兴趣的是这两者之间的区别:
选择@i1=1,@b1=(case当@i1=1或((从@tn2中选择计数(1)>0)然后从@tn中选择1其他0结束),其中n.Seq=1选择@i1,@b1--result 1,0从@tn中选择@i1=1,@b1=(当@i1=1时为case,然后为1 else 0 end),其中n.Seq=1选择@i1,@b1
Simplified:,因此我猜SQL Server只是通过添加子查询来选择一个不同的<代码>案例不会总是短路到ms connect的部分+链接。那么为什么
@i1
?我已经扩展了我的答案。基本上,这个警告句是问题的全部要点和答案。感谢您提供的信息,但似乎不在我的案例中。根据执行计划(本例中的文本会更好),它表明将首先执行
,其中
,这是由于Giorgi Nakuri的回答中提到的与成本相关的原因。事实上,我不确定这是否回答了您的问题,但看起来似乎与这个概念有关。是的,这似乎是答案的一部分,带有“与成本相关的原因”,它首先评估
语句时的
(带子查询),然后评估
案例
,并在最新阶段分配
@i
。由于所有“部分”都具有相同的“成本”,因此它从左到右进行评估