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

3

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

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的初始化。


似乎是一个“几乎重复”的https://dev59.com/Km7Xa4cB1Zd3GeqPqXwr?rq=1(本身就是另一个有趣的帖子的几乎重复 =) - deroby
2个回答

3

实际上,这是不同的问题。文章描述了别名无法在其他地方重复使用。我同意这一点,系统也明显如此,因为它会导致语法错误。然而,当通过变量进行操作时,情况会发生很大变化,到目前为止,我还没有成功破解它。这并不意味着你错了;相反,链接的文章在所说的内容上绝对是正确的,我只是不确定它是否适用于原始问题。 - deroby

1
在我的经验中,到目前为止这种方法总是对我有效的。然而,每当我写类似的东西时,我也感到有点不安,并且已知道在某些更多疑的日子里将其拆分成两个单独的命令,也许我应该有更多这样的日子 =)
话虽如此,这个问题可以扩展到这些语法上,我“通过经验”认为它们是正确的,但我再次想知道是否有更确定的答案:
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”的例子,但我记得在添加 ORDER BY 后,它会变得混乱不堪,而这通常是必需的。

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

更新:这些东西(很可能)在数据集较小的情况下运行良好,但是当数据大小增长且查询优化器决定使用多线程等不同计划时,奇怪的事情开始发生... 因此,我尝试通过设置一个大表来“破坏”事物,该表将不再适合内存,然后看看会发生什么。我选择了一个简单的例子,可以轻松地分成多个线程。这里可以找到结果,但您需要根据自己的硬件进行适应(请不要使sqlFiddle崩溃!)。到目前为止,结果表明,虽然查询的计划因我们运行的查询而异(带或不带@x和@y),但事情仍在继续工作!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接