使用SELECT在SQL Server变量分配中的执行顺序

使用SELECT在SQL Server变量分配中的执行顺序,sql,sql-server,tsql,variable-assignment,operator-precedence,Sql,Sql Server,Tsql,Variable Assignment,Operator Precedence,给出以下示例: declare @i int select @i = 1, @i = 2 select @i 我永远都是2岁吗 这是我能想到的最简单的例子,但我正在考虑使用它来交换变量中的值。我也相信这种赋值选择的方法不符合ANSI标准,但是很有用,但是在这种情况下,我并不真正关心可移植代码 更新 多亏了@MichaelFredrickson,我们才有了@MartinSmith's和这方面的参考资料。我现在正在努力理解本文档中第二句话的含义,强调的正是: 如果单个SELECT语句中有多个赋值子

给出以下示例:

declare @i int
select @i = 1, @i = 2
select @i
我永远都是2岁吗

这是我能想到的最简单的例子,但我正在考虑使用它来交换变量中的值。我也相信这种赋值选择的方法不符合ANSI标准,但是很有用,但是在这种情况下,我并不真正关心可移植代码

更新

多亏了@MichaelFredrickson,我们才有了@MartinSmith's和这方面的参考资料。我现在正在努力理解本文档中第二句话的含义,强调的正是:

如果单个SELECT语句中有多个赋值子句,SQL Server不保证表达式的求值顺序。请注意,只有在指定之间存在引用时,效果才可见

然而,第一句话足以让我不依赖于行为。

对于变量赋值,参考:

如果单个SELECT语句中有多个赋值子句, SQL Server不保证计算的顺序 表达。请注意,只有在存在 作业中的参考资料

但是 如果我们处理的是表格,而不是变量,情况就不同了

在本例中,Sql Server使用一次完成所有操作,如中所述

这个概念表明,在同一逻辑阶段中的所有表达式都会像在同一时间点。。。不管他们从左到右的位置

因此,在处理相应的UPDATE语句时:

DECLARE @Test TABLE (
    i INT,
    j INT
)

INSERT INTO @Test VALUES (0, 0)

UPDATE @Test
SET
    i = i + 10,
    j = i

SELECT 
    i, 
    j 
FROM 
    @Test
我们得到以下结果:

i           j
----------- -----------
10          0   
通过使用“一次全部”评估。。。在Sql Server中,您可以在不使用中间变量/列的情况下交换表中的列值

大多数RBDM的行为都是这样的

编辑: 请注意,仅当在 作业

我理解这意味着,如果您有如下SELECT语句:

SELECT
    @A = ColumnA,
    @B = ColumnB,
    @C = ColumnC
FROM MyTable
那么任务的执行顺序就不重要了。。。不管怎样,你都会得到同样的结果。但是如果你有像

SELECT
    @A = ColumnA,
    @B = @A,
    @C = ColumnC
FROM MyTable

现在在分配@B=@a之间有一个引用,@a和@B的分配顺序现在很重要。

甚至不确定这在任何地方都有定义。我不会指望任何观察到的行为。这正是我所担心的,所以可能不会将其投入生产只是为了节省一些loc。剃掉一些loc永远不是一个好的理由。让某些东西可靠地工作,并使其易读。别担心,完全同意。不过仍然很有趣。+1,答案很好,几乎是重复的问题。在我的问题中,我曾讨论过是否承认列交换反例,但为了简洁起见,将其省略了。现在,我应该投票结束我自己的问题吗?@TimLehner我花了很长时间才找到包含马丁答案的问题。。。而你刚刚发布的问题总是在我谷歌搜索的顶端。。。我认为,至少,这个问题仍然可以作为指向另一个问题的指针,以及稍微扩展的讨论。。。