MERGE con OUTPUT non sembra fare la cosa giusta


8

Sto aggiungendo una chiave esterna a una tabella e rimuovendo tutte le righe che violano l'FK, copiandole in una tabella ModifiedTable_invalid. Come parte dello script, ho il seguente comando 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;

Tuttavia, questo comando sembra inserire OGNI riga da ModifiedTable in ModifiedTable_invalid, non solo quelli eliminati dal comando MERGE. Cosa sta succedendo e come ottengo per inserire solo le righe eliminate in ModifiedTable_invalid?

Risposte:


11

Quando aggiorni una riga, questa apparirà sia nelle pseudo-tabelle ( insertedvalore post-aggiornamento) che deleted(valore pre-aggiornamento). Se questo sembra strano, considera che un aggiornamento è logicamente una cancellazione seguita da un inserimento (anche se l'aggiornamento potrebbe non essere eseguito fisicamente in quel modo).

Se utilizzata con MERGE, la OUTPUTclausola può includere una colonna aggiuntiva denominata $action. Aggiungendo questa colonna alla query mostrerà quale azione è stata presa ( 'INSERT', 'UPDATE'o 'DELETE') per ogni riga.

Per esempio:

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';

Le righe aggiornate avranno $action= 'UPDATE'.

Vedi anche il post di Adam Machanic sull'uso di OUTPUT con l'istruzione MERGE per alcuni altri esempi interessanti.


Questo comportamento non ha senso per me. Perché dovrebbero apparire le righe che non sono state eliminate DELETED.*?
thecoop

3
@thecoop: consente di accedere ai valori "prima" e "dopo" per un aggiornamento. Concettualmente potresti considerare un aggiornamento come un'eliminazione seguita da un inserimento, anche se spesso non è così che succede.
Martin Smith,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.