在同一个表中使用其他值更新一列

Ism*_*ilS 6 sql t-sql sql-server

请考虑这个sql语句

Create table abc 
(A int,
B int
)

insert into abc values (1,2)
Run Code Online (Sandbox Code Playgroud)

以下两个陈述都做同样的事情.为什么?

update abc 
set A = B,
B =0
where A=1
Run Code Online (Sandbox Code Playgroud)

update abc 
set B =0,
A = B
where A=1
Run Code Online (Sandbox Code Playgroud)

我在想,在后面的语句中,B首先设置列值,然后将A列的值设置为B'svalue

pax*_*blo 8

不可以.单个更新语句是原子的,各个部分没有顺序.

这两个:

update abc set A = B, B = 0 where A=1
update abc set B = 0, A = B where A=1
Run Code Online (Sandbox Code Playgroud)

这样做正是同样的事情,因为这两个任务都被认为同时发生.

换句话说,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
Run Code Online (Sandbox Code Playgroud)

然后它将解锁所有行.

这只是一个选择.一个非常愚蠢的DBMS可能只是锁定整个数据库文件,尽管这不会产生非常智能的并发性.

单用户,单线程DBMS根本不必关心并发性.它绝对没有锁定,只是通过每个相关的行,进行更改.