在 SQL Server 中的两列之间交换数据是如何工作的?

Posted

技术标签:

【中文标题】在 SQL Server 中的两列之间交换数据是如何工作的?【英文标题】:How does swapping data between two columns in SQL Server work? 【发布时间】:2010-02-12 11:06:41 【问题描述】:

我可能可以用谷歌搜索这个,但它看起来很古怪,值得在 SA 上作为答案登录。

所以在开发区,如果你想交换两个变量的值,你需要第三个临时变量。

例如

string x = "ABC";
string y = "DEF";

string temp;

temp = x;
x = y;
y = temp;

但是在 SQL 更新中,您可以简单地说

UPDATE table
SET ColumnA = ColumnB, ColumnB = ColumnA

这在后台是如何工作的

SQL Server 是否首先对整行进行快照? SQL Server 是否会一次性对正在更新的所有行进行快照? 优化器是否意识到它正在执行列交换,并在后台创建一个临时变量?

干杯 EoinC

【问题讨论】:

【参考方案1】:

SQL Server 是否首先对整行进行快照?

在某种程度上,是的。

这是一个有趣的场景,突出了声明式代码和过程式代码之间的区别。让我们举个例子:

UPDATE 
    users 
SET 
    first_name = last_name, 
    last_name = first_name,
    age = 55
WHERE
    user_id = 100

UPDATE 语句的工作方式有点像这样:

首先它检查WHERE 子句。所有与WHERE 子句匹配的行都将被标记为子集。如果没有WHERE 子句,那么整个表都会被标记。使用上面的例子,我们可以有一个像下面这样的子集: 用户 ID |名字 |姓氏 |年龄 |国家 ---------+--------------+-------------+--------+--- ------ 100 |约翰 |能源部 | 50 |美国

然后从SET 子句构造一个新的子集。 SET 子句中未提及的字段是从原始子集中复制的。

新子集中的age 字段将直接分配55 的值。 first_namelast_name 字段也会发生同样的情况,但它们的新赋值值将从原始子集中检索。 country 字段是从原始子集中按原样复制的,因为在 SET 子句中没有提到它。

用户 ID |名字 |姓氏 |年龄 |国家 ---------+--------------+-------------+--------+--- ------ 100 |能源部 |约翰 | 55 |美国 然后从表中删除原始子集并插入新子集。

【讨论】:

【参考方案2】:

要添加到 gbn,这可能有助于理解:

Halloween Protection

Read Committed Isolation Level

编辑:实际上我想粘贴这个:Serializable vs. Snapshot Isolation Level。不过没关系,反正都值得一读。

【讨论】:

【参考方案3】:

SQL命令不是串行的,一个接一个,一步一步的操作。这是一次对多个列/行的集合操作。

SQL 是declarative。你告诉引擎你想要什么,它就会做到。 你的客户代码(也许还有你的想法)是procedural

最后,最好的解释可能在于关于“halloween problem”的文章。

注意:SQL Server 内部管理它的方式可能与 Oracle 不同,但两者都解决了相同的问题

【讨论】:

以上是关于在 SQL Server 中的两列之间交换数据是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 中的单词匹配

python交换数据的两列

如何将两个表与 SQL Server 中第二个表中引用同一列的两列连接起来

Access 2016 SQL:查找不同表的两列之间的最小绝对差

从表中的两列中选择相同的数据,并使用一条sql语句显示所有数据

合并数据透视表中的两列