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)