2012-03-24 15 views
7

Wprowadzam kilka poprawek do starszej aplikacji zbudowanej na bazie SQL Server 2000, nie trzeba dodawać, że chcę zrobić absolutne minimum w obawie, że może się po prostu rozpaść.INSTEAD OF UPDATE Trigger - czy to możliwe?

Mam dużą tabelę użytkowników, tbUsers, z flagą BIT dla IsDeleted. Chcę zarchiwizować wszystkie obecne i przyszłe rekordy użytkownika IsDeleted = 1 w mojej tabeli archiwum tbDeletedUsers.

Przenoszenie aktualnie usuniętych użytkowników jest proste, jednak chcę mieć sposób na przeniesienie wszystkich przyszłych użytkowników, dla których ustawiono flagę IsDeleted. Mógłbym użyć standardowego wyzwalacza AFTER na kolumnie, jednak planuję dodać pewne ograniczenia do tabeli tbUser, które naruszają to, co chciałbym, aby mój wyzwalacz INSTEAD OF UPDATE uruchamiał i przenosił rekord do tabeli archiwum?

Domyślam się, że moje pytanie brzmi ... czy można wywołać wyzwalacz INSTEAD OF UPDATE w aktualizacji pojedynczej kolumny? Oto, co mam do tej pory:

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

Jeśli tak, przykładowy plik (zgodny z SQL 2000) byłby bardzo doceniany!

Odpowiedz

12

Stosując test UPDATE(columnname), można sprawdzić w wyzwalacz, czy dany kolumna została zaktualizowana (a następnie podjąć konkretne działania), ale nie można mieć wyzwalacz ogień tylko na aktualizację określonej kolumny . Uruchomi się zaraz po aktualizacji, niezależnie od tego, która kolumna była celem aktualizacji.

Tak więc, jeśli uważasz, że trzeba użyć INSTEAD OF UPDATE spust, trzeba realizować dwa rodzaje działań, w tym:

1) wstawić do tbDeletedUsers + usunąć z tbUsers - kiedy IsDeleted jest aktualizowana (lub , dokładniej, zaktualizowano i ustawioną na 1);

2) aktualizacja tbUsers zwykle - gdy IsDeleted nie jest aktualizowany (ani aktualizowany, ale nie ustawiony na 1).

Ponieważ więcej niż jeden wiersz może zostać zaktualizowany za pomocą pojedynczej instrukcji UPDATE, może być również konieczne uwzględnienie, że niektóre wiersze mogą mieć wartość IsDeleted ustawioną na 1, a inne nie.

Nie jestem wielkim fanem INSTEAD OF wyzwalaczy, ale czy naprawdę musiał użyć jednego dla zadania jak twoje, mogę pominąć test UPDATE() i wdrożenie spust tak:

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

aktualizacji (columnName) nie istnieje w SQL Server. Zamiast tego użyj COLUMNS_UPDATED (columnName). http://msdn.microsoft.com/en-us/library/ms186329.aspx –

+1

Dziękuję za komentarz. Masz rację, nie ma żadnej funkcji UPDATES() w SQL Server ani UPDATED(), jak pisałem na początku. W rzeczywistości nazywa się [UPDATE()] (http://msdn.microsoft.com/en-us/library/ms187326.aspx). Edytuję moją odpowiedź i jeszcze raz dziękuję za zwrócenie mojej uwagi na moją uwagę. –

+0

I wydajesz się też być w błędzie, ponieważ COLUMNS_UPDATED() nie akceptuje parametru. Zwraca bitową maskę odzwierciedlającą wszystkie kolumny, których dotyczy instrukcja, która wywołała wyzwalacz. Nigdy nie używałem tej funkcji, chociaż z podręcznika, myślę, że mam ciekawy pomysł, jak z niego korzystać. –