【问题标题】:Behaviour of SELECT @Var and SET @Var in T-SQL when dealing with NULLs处理 NULL 时 T-SQL 中 SELECT @Var 和 SET @Var 的行为
【发布时间】:2012-09-09 10:07:45
【问题描述】:

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

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,则分配正确。

【问题讨论】:

    标签: sql tsql select


    【解决方案1】:

    第一个版本将 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,这就是查询打印的内容。

    【讨论】:

    • 对于您的最后一个示例 - 我不确定您是否保证 @a 之后将是 3,也不会执行 3 个分配。
    【解决方案2】:

    好吧,选择不返回任何行。所以实际上没有分配。

    虽然结果集将有一个空值。

    【讨论】:

      【解决方案3】:
      SET @A = (SELECT ValueThatDoesntExist 
                             FROM dbo.MyTable WHERE MyColumn = 'notfound')
      

      这里执行查询返回NULL

      但是当你这样做时

      SELECT @A = ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound'
      

      查询没有返回任何内容

      【讨论】:

        【解决方案4】:

        SELECT 子句中的变量赋值是相当不可预测的。当你有:

        SELECT @A = ...
        

        并且正好一行在结果集中,值是明确定义的。如果返回 multiple 行,则值 可能 计算一次,对于任意行,或者它可能计算 multiple 次,直到结果集中的行数。

        但是,如果查询产生 0 行,则永远不会执行分配。

        【讨论】:

          猜你喜欢
          • 2013-06-24
          • 2012-03-12
          • 2012-05-07
          • 2016-06-24
          • 1970-01-01
          • 2010-09-15
          • 1970-01-01
          • 2015-01-26
          • 1970-01-01
          相关资源
          最近更新 更多