sql - 使用 SELECT 的 SQL Server 变量赋值中的执行顺序

标签 sql sql-server tsql variable-assignment operator-precedence

给出以下示例:

declare @i int
select @i = 1, @i = 2
select @i

威尔@i永远是2?

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

更新

感谢@MichaelFredrickson,我们有了@MartinSmith 的 answer并引用 MSDN在这一点上。我现在正在努力解决本文档中第二句话的确切含义(强调):

If there are multiple assignment clauses in a single SELECT statement, SQL Server does not guarantee the order of evaluation of the expressions. Note that effects are only visible if there are references among the assignments.



然而,第一句话足以让我远离依赖这种行为。

最佳答案

对于变量赋值,Martin Smith answers this question here引用 MSDN :

If there are multiple assignment clauses in a single SELECT statement, SQL Server does not guarantee the order of evaluation of the expressions. Note that effects are only visible if there are references among the assignments.



但...

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

在这种情况下,Sql Server 使用 All-At-Once 操作,如 Itzik Ben-Gan in T-Sql Fundamentals 所讨论的。 .

这个概念表明,同一逻辑阶段中的所有表达式都被评估为好像同一时间点......无论它们的从左到右的位置如何。

所以在处理对应的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 中使用 All-At-Once 评估...,您可以在没有中间变量/列的情况下交换表中的列值。

大多数 RBDMS 都以这种方式运行 as far as I know, but MySql is an exception .

编辑:

Note that effects are only visible if there are references among the assignments.



我理解这意味着如果您有 SELECT声明如下:
SELECT
    @A = ColumnA,
    @B = ColumnB,
    @C = ColumnC
FROM MyTable

那么,分配的执行顺序无关紧要……无论如何,您都会得到相同的结果。但如果你有类似...
SELECT
    @A = ColumnA,
    @B = @A,
    @C = ColumnC
FROM MyTable

现在有一个 作业中的引用 ( @B = @A ),以及 @A 的顺序和 @B现在分配的事项。

关于sql - 使用 SELECT 的 SQL Server 变量赋值中的执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14883930/

相关文章:

php - 列数与第 1 行 php mysql 的值计数不匹配

mysql - 为什么这个 SQL INNER JOIN 有效而这个无效?

sql - "Explode"SQL函数返回的表成列

sql - 为什么 object_id 总是返回 null?

sql - SQL Server 2008 R2 中重命名数据库时出错

sql - 两列分组在另一列上的区别

c# - 从 SQLDataReader 读取结果时出现无效的转换异常

sql - 比较快照表中的两个日期 -TSQL

sql - 总和列以显示每一行的总数

sql - 每当将项目添加到 Service Broker 队列时,如何执行存储过程?