代码之家  ›  专栏  ›  技术社区  ›  Eoin Campbell

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

  •  3
  • Eoin Campbell  · 技术社区  · 15 年前

    我可能会在谷歌上搜索这个,但它似乎足够古怪,值得在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是否对一次更新的所有行进行快照?
    • 优化器是否意识到它正在进行列交换,并在后台生成一个临时变量?

    欢呼EOC

    3 回复  |  直到 10 年前
        1
  •  4
  •   Daniel Vassallo    15 年前

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

    在某种程度上,是的。

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

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

    这个 UPDATE 语句的工作方式如下:

    • 首先检查 WHERE 条款。所有与匹配的行 在哪里? 子句将标记为子集。如果没有 在哪里? 子句,则整个表都将被标记。使用上面的例子,我们可以有如下的子集:
        user_id  |  first_name  |  last_name  |  age  |  country
        ---------+--------------+-------------+-------+---------
        100      |  John        |  Doe        |  50   |  USA
    
    • 然后根据 SET 条款。中未提及的字段 设置 从子集中复制子句。

      这个 age 新子集中的字段将被赋予 55 直接。同样的情况也会发生在 first_name last_name 字段,但它们的新赋值将从原始子集中检索。这个 country 字段按原样从原始子集复制,因为在 集合 条款。

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

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

    Halloween Protection

    Read Committed Isolation Level

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

        3
  •  2
  •   gbn    15 年前

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

    SQL是 declarative . 你告诉发动机你想要什么,它就会做到。 你的客户代码(也许你的想法)是 procedural

    最后,最好的解释可能是关于 halloween problem “。

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