Tsql 使用一个SELECT语句初始化多个变量

Tsql 使用一个SELECT语句初始化多个变量,tsql,select,sql-server-2012,variable-assignment,Tsql,Select,Sql Server 2012,Variable Assignment,这是一种众所周知的做法: DECLARE @A INT ,@B INT SELECT @A = [Column01] ,@B = [Column02] FROM [dbo].[data] 我想知道以下代码是否正确: DECLARE @A INT ,@B INT SELECT @A = [Column01] ,@B = @A + [Column02] FROM [dbo].[data] @A总是在@B之前获取值 在我的实际案例中,[Co

这是一种众所周知的做法:

DECLARE @A INT
       ,@B INT

SELECT @A = [Column01]
      ,@B = [Column02]
FROM [dbo].[data]
我想知道以下代码是否正确:

DECLARE @A INT
       ,@B INT

SELECT @A = [Column01]
      ,@B = @A + [Column02]
FROM [dbo].[data]
@A
总是在
@B
之前获取值



在我的实际案例中,
[Column01]
Column02
是一个包含许多列和
T-SQL
函数的表达式,使用
@A
作为参考可以简化
@B
的初始化

是否@A总是在@B之前获得值?

答案是否定的

引自伊兹克·本·甘的

SQL支持一种称为“一次所有操作”的概念,这意味着在同一逻辑查询处理阶段出现的所有表达式都在同一时间点进行逻辑计算


请检查我迄今为止的经验

这对我来说一直是“自上而下”的。然而,每当我写这样的东西时,我也会感到有点恶心,而且当我有一天更偏执的时候,我会把它分成两个独立的命令,也许我应该有更多的命令=)

这就是说,这个问题可以扩展到这些语法,我“根据经验”假设它们是正确的,但再次怀疑是否有人对此有更明确的答案:

DECLARE @a int,
        @b int,
        @x int

SELECT @a = (CASE name WHEN 'A' THEN value ELSE @a END),
       @b = (CASE name WHEN 'B' THEN value ELSE @b END)
  FROM myTable
 WHERE name IN ('A', 'B')
这将得到与下面相同的结果,但速度要快得多,特别是如果您必须获取其中的许多

SELECT @a = value FROM myTable WHERE name = 'A'
SELECT @b = value FROM myTable WHERE name = 'B'
或者,这个:

DECLARE @a int = 8,
        @b int = 5,
        @x int

UPDATE myTable
   SET @x = @a * leftField + @b * rightField,
       mySum = @x,
       mySquare = Power(@x, 2)
 WHERE ...
其中,我使用@x计算给定记录的中间值,然后使用该值设置字段或再次作为公式的一部分。(我同意这是一个愚蠢的例子,但目前无法想出更明智的办法)

或者这个现在似乎被普遍接受为“OK”,但我确实记得,如果你在它上面添加一个
orderby
,这通常是一个要求,那么它会变得混乱

DECLARE @a varchar(max)

SELECT @a = (CASE WHEN @a IS NULL THEN name ELSE @a + ',' + name END)
  FROM sys.objects
 WHERE type = 'S'

SELECT @a


更新:只要数据集很小,这些事情(可能)通常都可以正常工作,但当数据的大小增加,并且QO决定使用多线程等不同的计划时,奇怪的事情开始发生。。。所以我试着通过设置一个更大的表来“打破”事情,这个表不再适合内存,然后看看会发生什么。我举了一个简单的例子,可以很容易地分成多个线程。结果是可以找到的,但您需要调整它以适应您的硬件偏离轨道(请不要让sqlFiddle屈服!)。到目前为止,结果是一切正常,但查询计划因我们运行的查询而异(带或不带@x和@y)

事实上,那是苹果和橘子。本文介绍了别名如何不能在其他地方重复使用。我同意这一点,系统显然也同意,因为它会导致语法错误。然而,当通过变量时,情况发生了很大的变化,到目前为止,我还没有设法打破这一点。这并不意味着你错了;相反,链接文章所说的绝对正确,我只是不确定它是否适用于原始问题。似乎是的“几乎复制品”(其本身几乎复制了另一篇有趣的帖子btw=)