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

时间:2010-02-12 11:06:42

标签: sql sql-server query-optimization sql-update

我可能会谷歌这个,但它似乎很古怪,它可能值得记录为SA的答案。

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

e.g。

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

string temp;

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

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

UPDATE table
SET ColumnA = ColumnB, ColumnB = ColumnA

这是如何工作的

  • SQL Server是否首先拍摄整行的快照?
  • SQL Server是否会快速拍摄一次更新的所有行?
  • 优化器是否意识到它正在进行列交换,并在幕后制作临时变量?

干杯EoinC

3 个答案:

答案 0 :(得分:4)

SQL Server是否首先拍摄整行的快照?

在某种程度上,是的。

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

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

UPDATE语句有点像这样:

  • 首先检查WHERE子句。与WHERE子句匹配的所有行都将标记为子集。如果没有WHERE子句,那么整个表都会被标记。使用上面的示例,我们可以有如下的子集:
    user_id  |  first_name  |  last_name  |  age  |  country
    ---------+--------------+-------------+-------+---------
    100      |  John        |  Doe        |  50   |  USA
  • 然后从SET子句构造一个新的子集。 SET子句中未提及的字段将从原始子集中复制。

    新子集中的age字段将直接分配给55的值。 first_namelast_name字段也会出现相同的情况,但会从原始子集中检索新的分配值。 country字段按原样从原始子集复制,因为SET子句中未提及该字段。

    user_id  |  first_name  |  last_name  |  age  |  country
    ---------+--------------+-------------+-------+---------
    100      |  Doe         |  John       |  55   |  USA
  • 然后从表中删除原始子集并插入新子集。

答案 1 :(得分:3)

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

Halloween Protection

Read Committed Isolation Level

编辑:其实我想粘贴这个:Serializable vs. Snapshot Isolation Level。但是没关系,无论如何都值得一读。

答案 2 :(得分:2)

SQL命令不是串行的,一个接一个,一步一步的操作。它是一次性对多个列/行进行的设置操作。

SQL是declarative。你告诉引擎你想要什么,它就是这样做的。 您的客户代码(或许您的想法)是procedural

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

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