每天我都会学到一些新东西,似乎:)有人可以向我解释以下代码行为背后的基本原理:
DECLARE @A INT
SET @A = 15
SET @A = (SELECT ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound')
SELECT @A
-- Rsultset is NULL
SET @A = 15
SELECT @A = ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound'
SELECT @A
-- Resultset is 15
从我看到的情况来看,如果结果集为NULL,则SET会更改变量的值,而SELECT则不会。这是正常的ANSI行为还是特定于T-SQL?
当然,如果我SELECT @A = NULL
,则分配正确。
答案 0 :(得分:4)
第一个版本将A设置为查询结果:
SET @A = (SELECT ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound')
基本上是标量上下文中的select
,如果找不到行,则计算结果为null
。
第二个版本在结果集中为每一行设置A:
SELECT @A = ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound'
由于没有行,因此永远不会分配A.另一个例子:
declare @a int
select @a = i
from (
select 1
union all select 2
union all select 3
) as SubQueryAlias(i)
order by
i
select @a
这将为@a
分配3个值。分配的最后一个是3
,这就是查询打印的内容。
答案 1 :(得分:2)
那么select不会返回任何行。所以实际上没有任务。
虽然该集合的结果为null。
答案 2 :(得分:2)
SELECT
子句中的变量赋值是不可预测的。当你有:
SELECT @A = ...
和完全一行在结果集中,该值已明确定义。如果返回多个行,则可以为任意行计算值 一次,或者可以计算多次次,直到结果集中的行数。
但是,如果查询生成零行,则永远不会执行赋值。
答案 3 :(得分:1)
SET @A = (SELECT ValueThatDoesntExist
FROM dbo.MyTable WHERE MyColumn = 'notfound')
此处由于执行查询
而返回NULL但是当你做的时候
SELECT @A = ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound'
查询没有返回任何内容