Paweł Łukasiewicz
2017-11-19
Paweł Łukasiewicz
2017-11-19
Udostępnij Udostępnij Kontakt
Wprowadzenie

Kilka tygodni temu napisałałem artykuł SQL - wyzwalacze - część I. Skupiłem się na podstawowych operacjach – najważniejsze z nich to dwie tabele wirtualne: inserted i deleted. Pokazałem również przykład użycia wyzwalacza INSERT w przypadku logowania aktywności użytkownika podczas przeglądania witryny internetowej. W tym artykule pokaże jak używać wyzwlacza UPDATE oraz DELETE. Przygotuje również krótkie wprowadzenie do wyzwalacza INSTEAD OF. Jeżeli chcesz odswieżyć sobie wiedzę bądź też przeczytać pierwszą cześć odsyłam do artykułu wspomnianego na początku.

UPDATE

Jest to wyzwalacz, który uaktywnia się na przypisanej tabeli po wykonaniu akcji UPDATE. Poniższy przykład jest oparty na tabeli używanej w pierwszej cześci artykułu:

CREATE TRIGGER tr_Order_UPDATE
ON Orders
AFTER UPDATE
AS
-- sprawdzamy czy prioryter został zmieniony
IF NOT UPDATE(OrdPiority)
	RETURN
-- Sprawdzenie czy priorytet został zmieniony na wysoki
IF EXISTS(
SELECT * FROM inserted i
JOIN deleted d ON i.OrdID = d.OrdID
WHERE d.OrdPiority <> 'High' 
AND i.OrdPiority = 'High')
BEGIN
	DECLARE @Count tinyint
	SET @Count = (
	SELECT COUNT(*) FROM inserted i
	JOIN deleted d ON i.OrdID = d.OrdID
	WHERE d.OrdPiority <> 'High'
	AND d.OrdPiority = 'High')
	PRINT CAST(@Count as varchar(3))+' row(s) where changed to a priority of High'
	END
go
W cześci I wyzwalacz INSERT obserwuje zamówienia z priorytetem High. Wyzwalacz UPDATE obserwuje zlecenia w których priorytet został zmieniony na inny niż High.

Instrukcja IF sprawdza czy wartość OrdPiority została zmieniona. Jeżeli nie, możemy zaoszczędzić trochę czasu poprzez natychmiastowe opuszczenie wyzwalacza.

Tabela deleted zawiera wartości sprzed operacji UPDATE a tabela inserted zawiera nowe wartości. Kiedy dochodzi do połączenia table bardzo łatwo stwierdzić, kiedy doszło do zmiany priorytetu z High na inny.

DELETE

Jeżeli zrozumiałeś działanie wyzwalacza UPDATE nie będziesz miał problemu ze zrozumieniem jak działa DELETE. Jest łatwy do zaimplementowania. W poniższym przykładzie możecie zobaczyć obliczanie wierszy w tabeli deleted - pozwala to sprawdzić ile rekordów było zapisanych z priorytetem High.

CREATE TRIGGER tr_Orders_DELETE
ON Orders
AFTER DELETE 
AS
-- sprawdzamy czy zlecenie z priorytetem High zostało skasowane
IF EXISTS (SELECT * FROM deleted WHERE OrdPiority = 'High')
	BEGIN
		DECLARE @Count tinyint
		SET @Count = (SELECT COUNT(*) FROM deleted where OrdPiority = 'High')
		PRINT CAST(@Count as varchar(3))+' row(s) where deleted whose priority was High'
	END
GO

INSTEAD OF

Wyzwalacz INSTEAD OF jest dostępny od wersji SQL Server 2000. Powodem ich wprowadzenia było ułatwienie aktualizacji widoków. Pokaże Ci jak działają te wyzwalacze ale nie będę się skupiał na aktualizowaniu widoków. Szczerze mówiąc myslałem, że aktualizowanie widoków jest złym podejściem. Dowiedziałem się jednak, że jest to po części związane z "ograniczonym" doświadczeniem. Jeżeli nie zgadzasz się ze mną – pewnie nie jesteś sam.

Wzywalacz ten jest używany do wykonania czynności zamiast tej, która to wywołanie spowodowała. Brzmi to bardzo dziwnie dlatego postaram się to wyjaśnić. Załóżmy, że przygotowaliśmy wyzwalacz INSTAED OF INSERT zdefiniowany na tabeli i dochodzi do wywołania operacji INSERT. Wiersz nie zostaje dodany do tabeli ale kod wyzwalacza jest uruchamiany. Poniżej przykład takiego zachowania:

CREATE TRIGGER tr_Orders_InsteadOfINSERT
ON ORDERS
INSTEAD OF INSERT
AS 
PRINT 'Widoki z aktualizacjami wprowadzają bałagan'
go
Taka wiadomość jest wyświetalana przez operację INSERT. Należy jednak pamiętać, że wiersz nie jest dodany do tabeli:
INSERT INTO Orders(OrdPiority) VALUES ('Nie dodano')
-- Widoki z aktualizacjami wprowadzaja balagan