请考虑这个SQL语句更新与其它的值一列在同一表
Create table abc
(A int,
B int
)
insert into abc values (1,2)
两个下面的语句做同样的事情。为什么?
update abc
set A = B,
B =0
where A=1
和
update abc
set B =0,
A = B
where A=1
我在想,在以后的声明B
列值设置,然后再A
列的值设置为B's
值
请考虑这个SQL语句更新与其它的值一列在同一表
Create table abc
(A int,
B int
)
insert into abc values (1,2)
两个下面的语句做同样的事情。为什么?
update abc
set A = B,
B =0
where A=1
和
update abc
set B =0,
A = B
where A=1
我在想,在以后的声明B
列值设置,然后再A
列的值设置为B's
值
号单UPDATE语句原子,他们各自的部分没有秩序。
这两种:
update abc set A = B, B = 0 where A=1
update abc set B = 0, A = B where A=1
做正是同样的事情,因为这两个任务都被认为同时发生。
换句话说,=
右边的B
是旧值B
。
附录:一个DBMS如何实现此行为取决于那些写DBMS的聪明。
例如,一个DBMS 威力试图锁定其中A
是1,那么,一旦这样做了,经过和执行A = B
,B = 0
(按顺序,因为执行引擎认为,将满足并发,设置A
的所有行在B
之前更改为B
)。
像set A = B, B = A
声明将需要稍微更智能,但它可以做到这一点很轻松地通过先保存当前行并使用值出现在新行中设置的值,是这样的:
read in oldrow
copy oldrow to newrow
newrow.A = oldrow.B
newrow.B = oldrow.A
write out newrow
然后将解锁所有行。
这只是一个选项。一个非常笨的DBMS可能只是锁定整个数据库文件,尽管这不会实现非常智能的并发性。
单用户单线程DBMS根本不必关心并发性。它绝对不会锁定任何东西,只需遍历每个相关行,进行更改即可。
SQL不按字段顺序评估值。就SQL而言,这些陈述是相同的。
更新发生在一个步骤(原子),而不是几个有序的更新。
什么情况是,SQL访问的每个行的表,然后在同一时间更新A
到B
和的当前值更新B
为0
如果它可以帮助你理解,您可以将其视为更新触发器中发生的情况,该更新触发器可以访问DELETED
逻辑表中的表的当前值以及INSERTED
逻辑表中的新值。
现在我明白了,当我们运行Update语句时,有两个逻辑表格,即DELETED
和INSERTED
。
所以此值被设置为A
柱从DELETED
表的B
柱并且被设置为0是一个在INSERTED
表中的值B
检索。
@Ismail回答的变化:从逻辑上讲,更新是一起提交的删除和插入,这就是为什么您分别在每个逻辑表deleted
和inserted
中获得一行。这里的工作单位是行:当行更新时,它将被删除并使用新值重新插入(如果您想知道哪个列的值实际上发生了变化,您必须自行解决)。
有用的备忘录是
UPDATE MyTable
SET A = B, B = A;
将转置的列的值。
+1谢谢...... – IsmailS 2010-08-14 11:50:38
读取和写入都发生在同一时间吗?它不会在sql server的工作方式上创建任何并发性吗? – IsmailS 2010-08-13 08:26:10
+1谢谢...... – IsmailS 2010-08-14 11:50:56