处理NULL时,SELECT @Var和SET @Var在T-SQL中的行为

cea*_*rny 5 sql t-sql select

每天我都会学到新东西,似乎:)有人可以向我解释以下代码行为背后的基本原理:

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
Run Code Online (Sandbox Code Playgroud)

根据我的看法,如果结果集为NULL,则SET会更改变量的值,而SELECT则不会.这是正常的ANSI行为还是特定于T-SQL?

当然,如果我这样做SELECT @A = NULL,分配正确.

And*_*mar 4

第一个版本将 A 设置为查询结果:

SET @A = (SELECT ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound')
Run Code Online (Sandbox Code Playgroud)

基本上是select标量上下文中的 in ,如果没有找到行,则计算结果为null

第二个版本为结果集中的每一行设置 A:

SELECT @A = ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound'
Run Code Online (Sandbox Code Playgroud)

由于没有行,因此永远不会分配 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
Run Code Online (Sandbox Code Playgroud)

这将为 分配 3 个值@a。最后分配的一个是3,所以这就是查询打印的内容。