2012-03-24 21 views
7

Sto apportando alcune modifiche a un'applicazione legacy costruita su SQL Server 2000, inutile dire che voglio solo fare il minimo assoluto nel timore che tutto possa crollare.INSTEAD OF UPDATE Trigger: è possibile?

Ho una grande tabella di utenti, tbUsers, con un flag BIT per IsDeleted. Voglio archiviare tutti i record attuali e futuri di IsDeleted = 1 nella tabella degli archivi tbDeletedUsers.

Lo spostamento degli utenti attualmente eliminati è semplice, tuttavia voglio un modo per spostare tutti gli utenti futuri in cui è impostato il flag IsDeleted. Potrei usare un trigger AFTER standard sulla colonna, ma ho intenzione di aggiungere alcuni vincoli alla tabella tbUser che violerebbe questo, cosa mi piacerebbe che il trigger INSTEAD OF UPDATE si attivasse e spostassi il record in una tabella di archiviazione?

Suppongo che la mia domanda sia ... è possibile attivare un trigger INSTEAD OF UPDATE sull'aggiornamento di una singola colonna? Questo è quello che ho finora:

CREATE TRIGGER trg_ArchiveUsers 
INSTEAD OF UPDATE ON tbUsers 
AS 
    BEGIN 
     ... 
    END 
GO 

Se così un esempio (compatibile con SQL 2000) sarebbe molto apprezzato!

risposta

12

Utilizzando il test UPDATE(columnname), è possibile controllare in un trigger se una colonna specifica è stata aggiornata (e poi prendere azioni specifiche), ma non si può avere un trigger fuoco solo l'aggiornamento di una colonna specifica . Si attiverà non appena viene eseguito l'aggiornamento, indipendentemente dal fatto che la colonna fosse la destinazione dell'aggiornamento.

Quindi, se pensate di dover usare un INSTEAD OF UPDATE grilletto, è necessario implementare due tipi di azioni in esso:

1) inserire in tbDeletedUsers + eliminare dalla tbUsers - quando IsDeleted viene aggiornato (o più esattamente, aggiornato e impostato su 1);

2) aggiornamento tbUsers normalmente - quando IsDeleted non viene aggiornato (o aggiornato ma non impostato su 1).

Poiché è possibile aggiornare più di una riga con una singola istruzione UPDATE, potrebbe essere necessario tenere conto del fatto che alcune righe potrebbero avere IsDeleted impostato su 1 e altre no.

Io non sono un grande fan di INSTEAD OF trigger, ma se ho dovuto usare uno per un'attività come la tua, potrei omettere il test UPDATE() e implementare il grilletto in questo modo:

CREATE TRIGGER trg_ArchiveUsers 
ON tbUsers 
INSTEAD OF UPDATE 
AS 
BEGIN 
    UPDATE tbUsers 
    SET 
    column = INSERTED.column, 
    … 
    FROM INSERTED 
    WHERE INSERTED.key = tbUsers.key 
    AND INSERTED.IsDeleted = 0 
    ; 
    DELETE FROM tbUsers 
    FROM INSERTED 
    WHERE INSERTED.key = tbUsers.key 
    AND INSERTED.IsDeleted = 1 
    ; 
    INSERT INTO tbDeletedUsers (columns) 
    SELECT columns 
    FROM INSERTED 
    WHERE IsDeleted = 1 
    ; 
END 
+1

AGGIORNAMENTI (columnName) non esiste in SQL Server. Invece, utilizza COLUMNS_UPDATED (columnName). http://msdn.microsoft.com/en-us/library/ms186329.aspx –

+1

Grazie per il commento. Hai ragione, non c'è la funzione UPDATES() in SQL Server, né UPDATED(), come ho scritto inizialmente. In realtà è chiamato [UPDATE()] (http://msdn.microsoft.com/en-us/library/ms187326.aspx). Modifica la mia risposta e grazie ancora per aver portato il mio errore alla mia attenzione. –

+0

E sembra che tu abbia sbagliato anche tu, perché COLUMNS_UPDATED() non accetta un parametro. Restituisce una maschera bit che riflette tutte le colonne interessate dall'istruzione che ha invocato il trigger. Non ho mai usato quella funzione, anche se, dal manuale, penso di avere un'idea approssimativa su come usarla. –

Problemi correlati