views:

61

answers:

4

Please consider this sql statements

Create table abc 
(A int,
B int
)

insert into abc values (1,2)

Both of the below statements do the same thing. Why?

update abc 
set A = B,
B =0
where A=1

and

update abc 
set B =0,
A = B
where A=1

I was thinking that in the later statement B columns value is set first and then A columns' value is set to B's value

+4  A: 

No. Single update statements are atomic and there is no order in their individual parts.

Both of these:

update abc set A = B, B = 0 where A=1
update abc set B = 0, A = B where A=1

do exactly the same thing because the two assignments are considered to happen concurrently.

In other words, B on the right side of = is the old value of B.


Addendum: How a DBMS implements this behaviour depends on the cleverness of those writing the DBMS.

For example a DBMS might attempt to lock all the rows where A is 1 then, once that's done, go through and execute A = B, B = 0 (in that order because the execution engine deems that will satisfy concurrency, setting A to B before changing B) on each of those rows.

A statement like set A = B, B = A would require somewhat more intelligence but it could do that easily enough by saving the current row first and using values there to set values in the new row, something like:

read in oldrow
copy oldrow to newrow
newrow.A = oldrow.B
newrow.B = oldrow.A
write out newrow

Then it will unlock all the rows.

That's just one option. A very dumb DBMS may just lock the entire database file although that wouldn't make for very intelligent concurrency.

A single-user, single-thread DBMS doesn't have to care about concurrency at all. It would lock absolutely nothing, just going through each relevant row, making the changes.

paxdiablo
Does read and write both happens at the same time? Doesn't it create any concurrency in how sql server works?
Ismail
+1 thanks......
Ismail
+3  A: 

SQL does not evaluate values by order of field. The statements are identical as far as SQL is concerned.

The update happens in one step (atomic), not several ordered ones.

What happens is that SQL accesses each row in the table, then updates A to the current value of B and at the same time updates B to be 0.

If it helps you understand, you can think of it as what happens in an update trigger, which has access to the current value of the table in the DELETED logical table and to the new values in the INSERTED logical table.

Oded
Does read and write both happens at the same time? Doesn't it create any concurrency in how sql server works?
Ismail
You are not doing a read. You are doing a write.
Oded
If you observe the statement I'm actually reading Value of `B` and setting it to `A`.
Ismail
@Ismail - You are doing a _single_ update. SQL server guarantees that the single _update_ will be atomic.
Oded
Agreed. But don't you think `B's` value is being read and set to `A`?
Ismail
@Ismail - that's an internal _implementation_ detail within SQL. The important thing is that the operation is atomic. _How_ SQL does that is a different matter.
Oded
+1 thanks......
Ismail
A: 

Now I understand that, there are two logical tables i.e DELETED and INSERTED that come into picture when we run an Update statement.

So the value being set to A column is retrieved from B column of DELETED table and the value of B which is being set to 0 is the one in the INSERTED table.

Ismail
+1  A: 

Variation on @Ismail 's answer: logically speaking, an update is a delete and an insert that are committed together, that's why you get a row in each of the logical tables deleted and inserted respectively. The unit of work here is the row: when a row is updated it is deleted and re-inserted using the new values (if you want to know which column values actually change you have to work it out yourself).

A useful aide-mémoire is that

UPDATE MyTable
   SET A = B, B = A;

will transpose the columns' values.

onedaywhen
+1 thanks......
Ismail