ON tabela_lub_widok

Transkrypt

ON tabela_lub_widok
Wyzwalacze są specjalnym rodzajem procedur przechowywanych na serwerze, które są
automatycznie uruchamiane podczas modyfikacji danych. Tworzy się je na poziomie tabeli i
kojarzy z jedną lub większą liczbą akcji odpowiedzialnych za modyfikację da nych (INSERT,
UPDATE lub DELETE). Gdy wykonywana jest jedna z operacji, dla których został zdefiniowany
wyzwalacz, jest on automatycznie uruchamiany. Wyzwalacz wykonywany jest w tej samej
transakcji, co polecenie modyfikujące dane, a więc staje się jego częścią.
Wyzwalacze ułatwiają utrzymywanie spójności danych, ponieważ można za ich pomocą
zweryfikować dane przed ostatecznym przesłaniem ich do bazy. Za pośrednictwem
wyzwalaczy można przeprowadzać wiele akcji, w tym:
•
Porównywać dane przed i po wykonaniu danej operacji.
•
Cofać nieprawidłowe modyfikacje.
•
Odczytywać dane z innych tabel, nawet, jeśli wchodzą one w skład innych
baz danych.
•
Modyfikować inne tabele, nawet, jeśli wchodzą one w skład innych baz danych.
•
Wywoływać lokalne i zdalne procedury przechowywane na serwerze.
Przykładowe zastosowania wyzwalaczy:
•
Utrzymywanie danych zdublowanych lub wyprowadzonych na podstawie innych danych.
W nieznormalizowanych bazach danych pojawiają się często zdublowane (zbędne)
informacje.
Zamiast
pokazywać
je
użytkownikom
i
programistom,
można
zsynchronizować dane za pomocą wyzwalaczy. Jeżeli pozwalamy na to, by dane
wyprowadzane na podstawie innych danych były niezsynchronizowane, to ich
odświeżanie może być przeprowadzane wsadowo albo w jeszcze inny sposób.
•
Skomplikowane ograniczenia kolumn. Jeżeli jakaś kolumna zależy od wartości
przechowywanych w wybranych wierszach tej lub innej tabeli, wówczas najlepszą metodą
na nałożenie ograniczenia na nią jest zastosowanie wyzwalacza.
•
Kaskadowa spójność odwoławcza. Za pomocą wyzwalaczy można zaimplementować
akcje odpowiedzialne za utrzymywanie spójności odwoławczej. Chodzi tu również o akcje
kaskadowe i tym podobne.
•
Złożone wartości domyślne. Za pomocą wyzwalaczy można generować wartości
domyślne, oparte na danych pochodzących z innych kolumn, wierszy lub tabel.
•
Spójność odwoławcza między bazami danych. Jeżeli w dwóch różnych bazach danych
znajdują się powiązane ze sobą tabele, wówczas wyzwalacze mogą zapewnić zachowanie
między nimi spójności odwoławczej.
We
wszystkich
wyżej
wymienionych
przypadkach
można
zastosować
procedury
przechowywane na serwerze. Jednak wyższość wyzwalaczy polega na tym, że mogą być one
uruchamiane przy każdej modyfikacji danych. Z kolei kod procedury przechowywanej na
serwerze lub kod SQL pochodzący z zewnętrznej aplikacji wykonywane są tylko wtedy, gdy
wprowadzają do danych jakieś zmiany. Kod wyzwalaczy wykonywany jest przy każdej
modyfikacji danych poza hurtowym kopiowaniem danych i kilkoma innymi akcjami, które
nie są odnotowywane w dzienniku zdarzeń. Nawet korzystając z narzędzia np. takiego jak
Query Analyzer, nie można ominąć reguł spójności danych, narzucanych przez wyzwalacze.
Wyzwalacze i procedury przechowywane na serwerze nie wykluczają się wzajemnie. Oba te
rozwiązania mogą być stosowane do modyfikacji i weryfikacji danych w tej samej tabeli.
Jeżeli zachodzi taka potrzeba, część z wymienionych wcześniej zadań można zrealizować za
pomocą wyzwalaczy, a część za pomocą procedur przechowywanych na serwerze.
Stosowanie polecenia CREATE TRIGGER
Podobnie jak w przypadku pozostałych obiektów bazy danych, wyzwalacze tworzone są przy
użyciu jednej z form instrukcji CREATE.
Podstawowa składnia tej instrukcji jest następująca:
CREATE TRIGGER nazwa_wyzwalacza
ON tabela_lub_widok
typ_wyzwalacza lista_poleceń
AS
instrukcje SQL
Nazwa_wyzwalacza
musi
spełniać
ogólne
reguły
tworzenia
identyfikatorów.
Tabela_lub_widok może być nazwą widoku tylko wtedy, gdy wyzwalacz jest typu
INSTEAD_OF - ten typ wyzwalaczy można definiować tylko dla widoków. Wyzwalacze nie
mogą być tworzone dla tabel tymczasowych oraz systemowych, mogą jednak odwoływać się
do tabel tymczasowych.
Typ_wyzwalaeza jest jednym ze słów kluczowych AFTER lub INSTEAD OF, natomiast
lista_poleceń jest dowolną kombinacją poleceń INSERT, UPDATE lub DELETE. Jeżeli lista
zawiera więcej niż jedno polecenie, należy oddzielić je przecinkami.
Instrukcje_SQL występujące za słowem kluczowym AS definiują czynności realizowane przez
wyzwalacz. Mogą to być takie same operacje jak w procedurze przechowywanej - z tą różnicą, że
wyzwalacze nie obsługują parametrów.
Wyzwalacze typu AFTER „po"
Wyzwalacze tego typu w SQL Serverze 2000 są tworzone domyślnie. Oznacza to, że
definiując taki wyzwalacz za pomocą instrukcji CREATE TRIGGER, nie trzeba stosować
słowa AFTER. Co więcej, jeżeli w dokumentacji jest mowa o „wy-zwalaczach", bez
odwoływania się do ich typu, można założyć, że chodzi właśnie o wyzwalacze typu „po".
W tabeli dla każdego zdarzenia można zdefiniować wiele wyzwałaczy typu „po", zaś każdy z
nich może wywoływać wiele procedur przechowywanych oraz wykonywać wiele różnych
czynności na wartościach z określonej kolumny danych. Jednakże kontrola nad kolejnością
przykład, jeżeli w tabeli RELACJA A znajdują się cztery wyzwalacze INSERT, możemy
zadecydować uruchamiania wyzwalaczy w tej samej tabeli jest znacznie ograniczona.
Na, który z nich będzie pierwszy, a który ostatni, lecz pozostałe dwa będą uruchamiane w
nieprzewidywalnej kolejności
Można utworzyć pojedynczy wyzwalacz typu „po", wykonywany dla jednej bądź wszystkich
instrukcji INSERT, UPDATE lub DELETE. Wyzwalacze typu „po" można definiować tylko
dla tabel nie dla widoków. Modyfikacja danych w widoku może spowodować uruchomienie
wyzwalacza zdefiniowanego dla tabeli źródłowej tego widoku. W taki oto sposób tworzone są
wyzwalacze typu „po" dla widoków.
Wyzwalacz typu „po" jest wykonywany tylko raz dla każdej instrukcji UPDATE, INSERT
lub DELETE, niezależnie od liczby wierszy, które obejmuje ta instrukcja.
Przykład
W poniższym skrypcie jest tworzona i wypełniana mała tabela. Następnie dla tej tabeli
tworzony jest wyzwalacz, który zostanie uruchomiony w momencie wykonania instrukcji
DELETE.
CREATE TABLE test_wyzw
(coli int, col2 char(6) )
GO
INSERT INTO test_wyzw VALUES (1, ’jeden’)
INSERT INTO test_wyzw VALUES (2, ‘dwa’)
INSERT INTO test_wyzw VALUES (3, ‘trzy’)
INSERT INTO test_wyzw VALUES (4, ‘cztery’)
INSERT INTO test_wyzw VALUES (5, ‘pięć’)
GO
CREATE TRIGGER delete_test
ON test_wyzw AFTER DELETE
AS
PRINT ‘Został usunięty wiersz!’
GO
Następnie wykonaj poniższą instrukcję
DELETE test_wyzw WHERE coli = 0
Uzyskamy następujący komunikat:
Został usunięty wiersz! (0 row(s) affected)
Pojawił się zdefiniowany przed chwilą komunikat, ponieważ wykonana instrukcja DELETE
była całkowicie poprawna. Wyzwalacz jest uruchamiany jeden raz, bez względu na liczbę
wierszy, które zostały objęte operacją, nawet jeżeli było to 0 wierszy. Aby tego uniknąć w
pierwszej instrukcji wyzwalacza należy sprawdzić liczbę wierszy, (@@ROWCOUNT) którą
objęła instrukcja modyfikująca.
Modyfikacja wyzwalacza
ALTER TRIGGER delete_test
ON test_wyzw AFTER DELETE
AS
IF @@ROWCOUNT =0
RETURN
PRINT ‘został usunięty wiersz’
Przykład 2
Zdefiniuj wyzwalacz, który po aktualizacji relacji olejki zapisze informację o aktualizacji w
relacji KomunikatyWyzawalaczy. W atrybucie nazwawyzwalacza zapisze jego nazwę, a w
atrybucie TekstKomunikatu wpisze informację ‘Nadane przez wyzwalacz’
CREATE TRIGGER PoAktualizacji
ON Olejki
AFTER UPDATE
AS
INSERT INTO KomunikatyWyzwalaczy (NazwaWyzwalacza, TekstKomunikatu)
VALUES ('PoAktualizacji', 'Nadane przez wyzwalacz ')
Zmodyfikuj relacje olejki (operacja ta spowoduje uruchomienie wyzwalacza), np. modyfikując
atrybut Idtypurosliny dla olejku bazylia. W tym samym skrypcie wyświetl zawartość relacji
KomunikatyWyzwalaczy przed i po aktualizacji.
Określanie kolejności wykonywania wyzwalaczy
W większości przypadków nie należy manipulować kolejnością wykonywania wyzwalaczy.
Jeżeli jednak chcemy, aby jeden z nich został wykonany jako pierwszy lub jako ostatni,
możemy skorzystać z procedury sp_settriggerorder. Parametrami tej procedury są: nazwa
wyzwalacza, jego pozycja na liście wykonania (FIRST, LAST lub NONE) oraz akcja
(INSERT, UPDATE lub DELETE). Ustawienie parametru kolejności na NONE powoduje
usunięcie porządku wykonywania zdefiniowanego dla wyzwalacza.
Przykład:
sp_settriggerorder delete_test, first, 'delete'
Jeżeli zostanie podana akcja nieskojarzona z określonym wyzwalaczem, wówczas wystąpi
błąd - na przykład gdyby w powyższym przykładzie ostatni parametr miał wartość update.
Błąd spowodowałaby również próba wykonania jednej z poniższych czynności:
•
Ustawienie kolejności dla wyzwalacza typu „zamiast";
•
Określenie kolejności dla wyzwalacza, gdy dla określonej akcji istnieje już jakiś
wyzwalacz na tej pozycji (na przykład jeżeli jest już pierwszy wyzwalacz DELETE w
określonej tabeli, trzeba najpierw zmienić jego kolejność na NONE, a dopiero potem
można definiować inny pierwszy wyzwalacz DELETE);
•
Próba ustawienia w określonej akcji tego samego wyzwalacza jednocześnie jako
pierwszego i ostatniego. Jeden wyzwalacz może mieć dwie różne pozycje na liście
wykonania, lecz pod warunkiem, że jest zdefiniowany dla dwóch różnych akcji. Aby
uzyskać taki efekt, trzeba odpowiednią liczbę razy wykonać funkcję sp_settriggerorder.
CREATE TRIGGER delete_update_test
ON test_wyzw AFTER DELETE, UPDATE
AS
PRINT 'Wiersz został usunięty lub zmodyfikowany!'
GO
EXEC sp_settriggerorder delete_update_test, first, 'delete'
EXEC sp_settriggerorder delete_update_test, last, 'update'
Funkcja UPDATE
SQL Server posiada funkcje UPDATE, która może być używana w połączeniu z
wyzwalaczem. Pozwala ona stwierdzić, czy aktualizowana była określona kolumna bąź
wiersz. Funkcja ta wzraca TRUE, jeżeli wartość danych w określonej kolumnie ulgła zmianie
na skutek wykonania polecenia INSERT lub UPDATE
UPDATE (nazwa_kolumny)
Przykład 3
Utworzyć wyzwalacz dla relacji OlejkiMoje, który w zalezności od aktualizowanej kolumny
wpisze do tabeli KomunikatyWyzwalaczy odpowiednie informacje.
CREATE TRIGGER FunkcjaUpdate
ON OlejkiMoje
AFTER UPDATE
AS
IF UPDATE(Opis)
INSERT INTO KomunikatyWyzwalaczy (NazwaWyzwalacza, TekstKomunikatu)
VALUES ('FunkcjaUpdate', 'Zaktualizowano kolumnę Opis')
IF UPDATE(NazwaOlejku)
INSERT INTO KomunikatyWyzwalaczy (NazwaWyzwalacza, TekstKomunikatu)
VALUES ('FunkcjaUpdate', 'Zaktualizowano kolumnę NazwaOlejku')
Wyzwalacze typu INSTEAD OF
Wyzwalacze tego typu zastępują polecenie, dla którego zostały zadeklarowane.
Podobnie jak wyzwalacze typu AFTER, można je definiować dla poleceń INSERT, UPDATE
oraz DELETE. Pojedynczy wyzwalacz może być zastosowany do wielu poleceń.
Jednakże w przeciwieństwie do poprzedniego, wyzwalacz typu INSTEAD OF można
zadeklarować zarówno dla tabeli, jak i widoku. Druga różnica polega na tym, że każdej akcji
związanej z tabelą lub widokiem można przypisać, co najwyżej jeden wyzwalacz typu
INSTEAD OF.
Wyzwalacze te są mocno niekompatybilne z kaskadową integralnością referencyjną. Nie
można zadeklarować wyzwalaczy INSTEAD OF DELETE lub INSTEAD OF UPDATE dla
tabeli z kluczem obcym ze zdefiniowaną akcją DELETE lub UPDATE oraz klauzulą
CASCADE
Ponieważ wyzwalacze typu INSTEAD OF mogą być deklarowane również dla widoków, są
one szczególnie przydatne do tworzenia mechanizmów normalnie w widokach niedostępnych.
Na przykład w SQL Serverze nie można wykonać instrukcji INSERT w widoku
zawierającym klauzulę GROUP BY, lecz można zdefiniować w tym widoku wyzwalacz
INSTEAD OF INSERT. Za pomocą wyzwalacza można, więc wstawiać rekordy do tabel
źródłowych składających się na widok, a tym samym udostępniać użytkownikowi nowe
rekordy wstawione przy użyciu tego widoku.
Przykład 4
Utworzenie wyzwalacza typu „zamiast” dla tabeli OlejkMojei
CREATE TRIGGER Zamiast
ON OlejkiMoje
INSTEAD OF UPDATE
AS
INSERT INTO KomunikatyWyzwalaczy (NazwaWyzwalacza, TekstKomunikatu)
VALUES ('Zamiast', 'Nadane przez wyzwalacz Zamiast')
Korzystanie z tabel wstawień (inserted) i usunięć (deleted)
SQL Server tworzy dwie tabele ułatwiające manipulowanie danymi przy użyciu wyzwalaczy.
Tabele wstawień i usunięć mają charakter tymczasowy, są przechowane w pamięci
operacyjnej i zawierają wiersze, na które miało wpływ polecenie wywołane przez wyzwalacz.
Gdy wyzwalacz jest uaktywniany dla instrukcji DELETE, tabela usunięć będzie zawierała
wiersze usunięte z określonej tabeli. Analogicznie, po wykonaniu instrukcji INSERT, w tabeli
wstawień znajdzie się kopia nowych wierszy. Z fizycznego punktu widzenia, instrukcja
UPDATE składa się z instrukcji DELETE, po której następuje instrukcja INSERT - oznacza
to, że w tabeli usunięć znajdą się poprzednie wartości, zaś w tabeli wstawień nowe. Zawartość
obydwu tabel jest dostępna w procedurze wyzwalacza, nie można ich jednak modyfikować.
Należy pamiętać, że wyzwalacze typu AFTER nie są wywoływane, dopóki w tabeli nie
zostaną dokonane modyfikacje, a więc gdy wiersze w tabeli źródłowej zostały już
zmodyfikowane. Z drugiej strony, wyzwalacze typu INSTEAD OF są wywoływane zamiast
czynności, dla której zostały zdefiniowane, a więc zanim tabela zostanie zmodyfikowana.
Wynika z tego, że tabela nie zostanie zmodyfikowana, dopóki wyzwalacz INSTEAD OF nie
wykona odpowiedniego polecenia.
Tabele inserted i delated mają taką samą strukturę i nazwy kolumn jak tabela, która była
modyfikowana.
Przykład 5
Utworzenie kopii relacji olejki (olejkiKopia). Utworzenie wyzwalacza do relacji
OlejkiKopia.Wyświetlenie zawartości tabel inserted i deleted.
--utorzenie kopii tabeli Olejki
SELECT*
INTO OlejkiKopia
FROM Olejki
Go
--utworzenie wyzwalacza dla OlejkiKopia
CREATE TRIGGER wyzw_OlKop
ON OlejkiKopia
FOR INSERT, UPDATE, DELETE
AS
PRINT 'WSTAWIANIE:'
Select * from inserted
PRINT 'USUWANIE:'
Select * from deleted
Update OlejkiKopia
SET idtypuRosliny = 15
Where idolejku IN (1,5,7,13,15,16,20)

Podobne dokumenty