SQL Server 中的两列之间交换数据是如何工作的?
我可能可以用谷歌搜索这个,但它看起来很奇怪,可能值得在 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
I could probably google this, but it seemed quirky enough that it might be worth having logged as an answer on SA.
So in development land, if you want to swap interchance the values of two variables, you need a third temp variable.
e.g.
string x = "ABC";
string y = "DEF";
string temp;
temp = x;
x = y;
y = temp;
However in a SQL Update, you can simply say
UPDATE table
SET ColumnA = ColumnB, ColumnB = ColumnA
How does this work under the hood
- Does SQL Server take a snap shot of the entire row first ?
- Does SQL Server take a snap shot of all the rows being updated in one go ?
- Does the optimizer realize that it's doing a column interchange, and make a temp variable behind the scenes?
Cheers EoinC
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
SQL Server 是否首先拍摄整行的快照?
在某种程度上,是的。
这是一个有趣的场景,突出了声明性代码和过程性代码之间的区别。让我们看下面的例子:
UPDATE
语句的工作方式有点像这样:WHERE
子句。所有与WHERE
子句匹配的行都将被标记为子集。如果没有WHERE
子句,则整个表都会被标记。使用上面的示例,我们可以拥有如下所示的子集:然后从
SET
子句构造一个新子集。SET
子句中未提及的字段将从原始子集中复制。新子集中的
age
字段将直接赋值为55
。first_name
和last_name
字段也会发生同样的情况,但它们的新分配值将从原始子集中检索。country
字段是从原始子集中按原样复制的,因为SET
子句中未提及该字段。Does SQL Server take a snap shot of the entire row first?
In a way, yes it does.
This is an interesting scenario that highlights the difference between declarative and procedural code. Let us take the following example:
The
UPDATE
statement would work somewhat like this:WHERE
clause. All the rows that match theWHERE
clause would be marked as a subset. If there were noWHERE
clause, then the entire table would have been marked. Using the above example, we could have a subset like the following:Then a new subset is constructed from the
SET
clause. Fields that are not mentioned in theSET
clause are copied from the original subset.The
age
field in the new subset will be assigned the value of55
directly. The same will happen for thefirst_name
andlast_name
fields, but their new assignment values would be retrieved from the original subset. Thecountry
field is copied as-is from the original subset, since it was not mentioned in theSET
clause.要添加到 gbn,这可能有助于理解:
万圣节保护
读取提交的隔离级别编辑
:实际上我想粘贴这个:可序列化与快照隔离级别。但没关系,无论如何,所有内容都值得一读。
To add to gbn, this may help understanding:
Halloween Protection
Read Committed Isolation Level
EDIT: Actually I wanted to paste this one: Serializable vs. Snapshot Isolation Level. But never mind, all are worth reading anyway.
SQL命令不是串行的,一个接一个,一步步操作。这是一次性对多列/行进行集合操作。
SQL 是声明性。你告诉引擎你想要什么,它就会做到。
您的客户端代码(也许还有您的想法)是程序
最后,可能最好的解释在于关于“万圣节问题”的文章。
注意:SQL Server内部管理方式可能与Oracle不同,但两者都解决了相同的问题
The SQL command is not a serial, one after the other, step by step operation. It's a set operation on multiple columns/rows in one go.
SQL is declarative. You tell the engine what you want to, and it does it.
Your client code (and your thinking perhaps) is procedural
Finally, possibly the best explanation lies in the article about the "halloween problem".
Note: how SQL Server manages it internally may be different to Oracle, but the same issues are solved by both