MERGE с OUTPUT, похоже, не правильно делает


8

Я добавляю внешний ключ в таблицу и удаляю все строки, которые нарушают FK, копируя их в таблицу ModifiedTable_invalid. Как часть сценария, у меня есть следующая команда MERGE:

MERGE ModifiedTable t1
USING TargetTable tt
ON t1.JoinColumn = tt.JoinColumn
WHEN MATCHED THEN
    UPDATE SET t1.FkColumn = tt.FkSource
WHEN NOT MATCHED BY SOURCE THEN DELETE
OUTPUT DELETED.* INTO ModifiedTable_invalid;

Однако эта команда, похоже, вставляет КАЖДУЮ строку из ModifiedTable в ModifiedTable_invalid, а не только те, которые были удалены командой MERGE. Что происходит, и как мне заставить его поместить только удаленные строки в ModifiedTable_invalid?

Ответы:


11

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

При использовании с MERGE, OUTPUTпредложение может включать дополнительный столбец с именем $action. Добавление этого столбца в запросе будет показано , какие действия были предприняты ( 'INSERT', 'UPDATE'или 'DELETE') для каждой строки.

Например:

insert into ModifiedTable_invalid(Id /* And other columns */)
select
    Id
    /* And other columns */
from
(
    merge ModifiedTable t1
    using TargetTable t2 on t1.JoinColumn = t2.JoinColumn
    when matched then update set t1.FkColumn = t2.FkSource
    when not matched by source then delete
    output 
        $action as DMLAction,
        deleted.Id as Id /* And other columns... */
) outputs
where
    DMLAction = 'DELETE';

Обновленные строки будут иметь $action= 'UPDATE'.

Также см. Пост Адама Маханича об использовании OUTPUT с оператором MERGE для некоторых других хороших примеров.


Такое поведение не имеет смысла для меня. Почему строки, которые не были удалены, появляются в DELETED.*?
Thecoop

3
@thecoop - позволяет получить доступ к значениям «до» и «после» для обновления. Концептуально вы можете рассматривать обновление как удаление, за которым следует вставка, даже если это часто не так, как это происходит на самом деле.
Мартин Смит
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.