Wyzwalacze Wyzwalacze są specjalnymi procedurami składowanymi, uruchamianymi automatycznie w następstwie zaistnienia określonego typu zdarzenia. Ich główne zadanie polega na wymuszaniu integralności danych i zapewnienie, aby dane przechowywane w bazie były zgodne z regułami narzuconymi przed projektanta bazy. Każdy wyzwalacz jest związany z określoną tabelą (lub widokiem) i jest uruchamiany w następstwie zajścia jednego z trzech zdarzeń: wywołanie instrukcji INSERT, UPDATE lub DELETE dla danej tabeli (widoku). Dodatkowo, można określić kiedy wyzwalacz ma zostać uruchomiony: przed zdarzeniem (wyzwalacz typu BEFORE), po zdarzeniu (AFTER) lub zamiast zdarzenia (INSTEAD OF) (ten typ wyzwalaczy stosujemy do widoków). Za pomocą wyzwalaczy można zrealizować wiele istotnych, z punktu widzenia integralności i bezpieczeństwa danych, zadań, m.in. zapewnienie integralności danych; sprawdzanie reguł poprawności wstawianych (modyfikowanych) danych; logowanie zdarzeń w systemie; można stworzyć własną tabelę z logami, a następnie wyzwalacze, które będą do tej tabeli wstawiać kolejne wiersze w odpowiedzi na działania na obiektach bazy danych; modyfikowanie danych, które mają zostać wstawione do tabeli (np. odpowiednie formatowanie) przed ich umieszczeniem w tabeli; automatyczne generowanie treści, np. obsługa pól auto increment, w szczególności, można wykorzystać wyzwalacz w połączeniu z sekwencja do automatycznego generowania wartości kluczy głównych. Wybieramy jedną z opcji przed zdarzeniem (wyzwalacz typu BEFORE), po zdarzeniu (AFTER), zamiast zdarzenia (INSTEAD OF) (ten typ wyzwalaczy stosujemy do widoków).
Wybieramy jedną z opcji Określamy, dla którego ze zdarzeńinsert / UPDATE / DELETE wyzwalacz ma zostać zdefiniowany. Jeden wyzwalacz może zostać zdefiniowany dla kilku zdarzeń. Wybieramy jedną z opcji Określamy, dla którego ze zdarzeńinsert / UPDATE / DELETE wyzwalacz ma zostać zdefiniowany. Jeden wyzwalacz może zostać zdefiniowany dla kilku zdarzeń. W klauzulion określamy tabelę lub widok. Wyzwalacze na poziomie wiersza lub instrukcji Dwa typy wyzwalaczy: typu ROW działające na poziomie wiersza (wierszowe), które definiujemy za pomocą klauzuli, działające na poziomie instrukcji (opcja domyślna). Wyzwalacz wierszowy jest uruchamiany dla każdego wiersza, na którym operuje instrukcja DML, wyzwalacz zdefiniowany na poziomie instrukcji jest uruchamiany raz w odpowiedzi na instrukcję. np. w przypadku aktualizacji 10 wierszy, wyzwalacz typu ROW będzie uruchamiany 10 razy. Kwalifikatory new i old w wyzwalaczach wierszowych W ciele wyzwalacza można korzystać ze wszystkich instrukcji, które są dostępne dla procedur zapamiętanych. W wyzwalaczach wierszowych mamy dodatkowo dostępne dwa kwalifikatorynew orazold, które pozwalają odwoływać się odpowiednio do nowych lub poprzednich wartości pól wstawianego lub usuwanego czy modyfikowanego wiersza. Uwaga. Dla wyzwalaczy uruchamianych w następstwie wykonania instrukcji INSERT mamy dostępne tylko wartości new, dla wyzwalaczy dla DELETE tylko wartości old, natomiast w przypadku zdarzenia UPDATE dostępne są obie wartości. Dla przykładu, jeżeli mamy zdefiniowany wyzwalacz wierszowy dla tabeli employee, dla zdarzenia UPDATE, to aby odwołać się do poprzedniej wartości zarobków w modyfikowanym wierszu, należy użyć składni:old.salary, natomiast aby odczytać nową wartość zarobków, należy użyć odwołania:new.salary.
Wyzwalacze działajace dla kilku zdarzeń DML Uwaga. W ciele wyzwalacza nie może być instrukcji, które modyfikują strukturę tabeli, na którą nałożony jest wyzwalacz; modyfikują dane w tabeli, dla której zdefiniowany jest dany wyzwalacz; wpływają na transakcję; odowłują się do podprogramów (procedur, funkcji), które zawierają takie instrukcje. Jeden wyzwalacz może zostać zdefiniowany dla kilku zdarzeń, np. aby zdefiniować wyzwalacz wierszowy dla tabeli employee, wywoływany po instrukcji UPDATE lub INSERT, użyjemy składni: CREATE OR REPLACE TRIGGER nowy AFTER INSERT OR UPDATE ON employee... Stosowanie predykatów INSERTING, UPDATING, DELETING Zarzadzanie wyzwalaczami Czasem wygodnie jest mieć wyzwalacz, który jest wywoływany w odpowiedzi na zajście więcej niż jednego ze zdarzeń INSERT, UPDATE, DELETE. Jeżeli mamy taki wyzwalacz, to musimy mieć możliwość sprawdzić, które zdarzenie wywołało ten wyzwalacz. W tym celu można użyć predykatów INSERTING, UPDATING, DELETING. Predykatów można użyć np. w warunku instrukcji IF, aby móc wykonać różne operacje, w zależności od tego, jaka instrukcja została wykonana, np. IF INSERTING THEN... ELSIF UPDATING THEN... ELSIF DELETING THEN... END IF; Do usuwania wyzwalaczy służy instrukcjadrop TRIGGER nazwa. Często nie chcemy usuwać wyzwalacza, a jedynie go czasowo dezaktywować (wyzwalacze wydłużają czas wykonywania modyfikacji, jeżeli planujemy przeprowadzić dużą liczbę instrukcji DML, aby przyspieszyć działanie, można przedtem wyłączyć pewne wyzwalacze). Wyzwalacz wyłączamy instrukcją ALTER TRIGGER nazwadisable. Aby ponownie aktywować wyzwalacz, należy użyć instrukcji ALTER TRIGGER nazwaenable. Dla jednej tabeli może być zdefiniowanych kilka wyzwalaczy tego samego typu. Są one wówczas uruchamiane sekwencyjnie.
Sekwencje Uwaga. Od wersji 11g bazy Oracle, można użyć klauzulifollows w definicji wyzwalacza, aby określić kolejność wykonywania wyzwalaczy tego samego typu: CREATE OR REPLACE TRIGGER nowy1 AFTER INSERT ON employee FOLLOWS nowy... Sekwencje w bazie Oracle to mechanizmy umożliwiające generowanie kolejnych wartości liczbowych. Instrukcja tworząca sekwencję: CREATE SEQUENCE nazwa INCREMENT BY liczba START WITH liczba Znaczenie opcji INCREMENT BY liczba skok sekwencji (domyślnie 1), START WITH liczba wartość początkowa (domyślnie 1). Metody sekwencji: CURRVAL pobranie bieżącej wartości, NEXTVAL pobranie następnej wartości. Sekwencje Sekwencje Definiujemy sekwencję dla klucza głównego emp_no tabeli employee: CREATE SEQUENCE emp_no_seq INCREMENT BY 1 START WITH 200 Wykorzystanie sekwencji: INSERT INTO employee (emp_no, first_name, last_name, salary, dept_no, hire_date, job_code, job_grade, job_country) VALUES(emp_no_seq.NEXTVAL, Anna, Kowalska,5000, 000,sysdate, Admin,4, USA ); Każde wywołanie metody NEXTVAL powoduje zwiększenie wartości sekwencji o zadany skok. Jeżeli wartość ta nie zostanie wykorzystana, np. z powodu błędu w instrukcji INSERT, wycofania transakcji, zostaje utracona. Przy następnym wywołaniu NEXTVAL zwraca kolejną wartość. Jedną sekwencję można wykorzystywać do generowania wartości kluczy głównych w kilku tabelach. Metoda CURRVAL nie zmienia wartości sekwencji, a jedynie zwraca bieżącą. Uwaga. Metodę CURRVAL można stosować dopiero po pobraniu pierwszej wartości z sekwencji za pomocą NEXTVAL.
Wykorzystanie sekwencji w wyzwalaczach Wyzwalacz dla tabeli employee, wstawiający do pola klucza głównego emp_no kolejną wartość pobraną z sekwencji emp_no_seq. CREATE OR REPLACE TRIGGER wstaw_emp_no BEFORE INSERT ON employee DECLARE numer INT; BEGIN IF (:NEW.emp_no IS NULL) THEN SELECT emp_no_seq.nextval INTO numer FROM dual; :NEW.emp_no := emp_no_seq.nextval; END IF; END;