Обновление одного столбца со значением другого в той же таблице

пожалуйста, рассмотрите эту инструкцию 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 стоимостью

4 ответов


нет. Одиночные операторы обновления являются атомарными, и в их отдельных частях нет порядка.

оба эти:

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

do ровно то же самое, потому что два назначения считаются происходящими одновременно.

другими словами, B на правой стороне = - Это старое значение B.


дополнение: как СУБД реализует это поведение в зависимости от ума из тех, кто пишет СУБД.

например, СУБД может попытка заблокировать все строки, где A это 1, Как только это будет сделано, пройдите и выполните A = B, B = 0 (в этом порядке, потому что механизм выполнения считает, что будет удовлетворять параллелизму, установка A to 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

затем он разблокирует все строки.

это только один вариант. Очень глупая СУБД может просто заблокировать весь файл базы данных, хотя это не приведет к очень интеллектуальному параллелизму.

однопользовательская, однопоточная СУБД не должна заботиться о параллелизме вообще. Он не запирал бы абсолютно ничего, просто проходя через каждую соответствующую строку, делая изменения.


SQL не оценивает значения по порядку поля. Операторы идентичны в том, что касается SQL.

обновление происходит за один шаг (атомарный), а не несколько упорядоченных.

что происходит, так это то, что SQL обращается к каждой строке в таблице, а затем обновляет A до настоящее стоимостью B и в то же время обновления B к 0.

если это поможет вам понять, вы можете думать об этом как о том, что происходит в обновить триггер, который имеет доступ к текущему значению таблицы в DELETED логическая таблица и новые значения в INSERTED логическая таблица.


вариант ответа @Ismail: логически говоря, обновление-это удаление и вставка, которые фиксируются вместе, поэтому вы получаете строку в каждой из логических таблиц deleted и inserted соответственно. Единицей работы здесь является строка: при обновлении строки она удаляется и вставляется заново, используя новые значения (если вы хотите знать, какие колонки значения на самом деле меняются, вы должны решить это сами).

полезное памятную записку, что

UPDATE MyTable
   SET A = B, B = A;

будет транспонировать значения столбцов'.


теперь я понимаю, что есть две логические таблицы i.e DELETED и INSERTED которые появляются при запуске инструкции Update.

таким образом, значение устанавливается в на DELETED таблица и значение B который устанавливается в 0 является одним в INSERTED таблица.