BAZY DANYCH II WYKŁAD 8 Plan wykładu Wyzwalacze Wyzwalacze
Transkrypt
BAZY DANYCH II WYKŁAD 8 Plan wykładu Wyzwalacze Wyzwalacze
2011-01-20 Plan wykładu BAZY DANYCH II WYKŁAD 8 Wyzwalacze: zalety, rodzaje, tworzenie, Wyzwalacze DML, Wyzwalacze zastępujące, Wyzwalacze systemowe, Tabele mutujące, Wyzwalacze złożone, Wyzwalacze a SQL Developer, dr inż. Agnieszka Bołtuć Wyzwalacze Są to nazwane bloki języka PL/SQL, Posiadają sekcje deklaracji, wykonawczą i obsługi wyjątków, Są przechowywane w bazie jako odrębne obiekty, Są jednak uruchamiane niejawnie w momencie gdy nastąpi wyzwalające zdarzenie, Nie posiadają argumentów. Wyzwalacze Wyzwalacze mogą być zdefiniowane na tabelach, widokach, schematach lub bazach danych, Zdarzeniem wyzwalającym może być operacja DML (DELETE, INSERT, UPDATE), zdarzenie systemowe (otwarcie lub zamknięcie bazy danych, wystąpienie błędu, logowanie lub wylogowanie użytkownika) lub określone operacje DDL (CREATE, ALTER, DROP), 1 2011-01-20 Zalety używania wyzwalaczy Zachowywanie złożonych ograniczeń integralnościowych, których nie można zapewnić za pomocą ograniczeń tworzonych podczas definicji tabeli, Kontrola informacji z tabel, rejestracja zmian i ich autorów, W razie wprowadzania zmian w tabeli automatyczne powiadamianie innych programów o konieczności wykonania niezbędnych operacji, Bezpieczne – użytkownicy i aplikacje nie mogą ich ominąć, Typy wyzwalaczy DML – uruchamiane w wyniku wykonania instrukcji INSERT, UPDATE, DELETE, można je uruchamiać przed lub po operacji, mogą działać dla wybranych wierszy lub dla wszystkich, Zastępujące – definiowane są jedynie dla widoków, są uruchamiane zamiast wywołujących je instrukcji DML, działają na poziome wierszy, Systemowe – jest uruchamiany, gdy zajdzie zdarzenie systemowe lub operacja DDL. Tworzenie wyzwalaczy Tworzenie wyzwalaczy CREATE [OR REPLACE] TRIGGER nazwa {BEFORE | AFTER | INSTEAD OF} Zdarzenie ON obiekt [REFERENCING [OLD AS nazwa | NEW AS nazwa]] [FOR EACH ROW] [WHEN warunek] [DECLARE] BEGIN Ciało; [EXCEPTION … ] END; Nazwa –nazwa identyfikująca wyzwalacz, Zdarzenie – zdarzenie, które uruchamia wyzwalacz, najczęściej na konkretnym obiekcie INSERT | DELETE | UPDATE | UPDATE OF kolumny REFERENCING – nadawanie innych nazw identyfikatorom korelacji, tylko wyzwalacze z poziomu wierszy, FOR EACH ROW – określenie wyzwalacza z poziomu wierszy, WHEN warunek – ciało wyzwalacza uruchamiane jest tylko wtedy, gdy podany warunek ma wartość TRUE, jest sprawdzane na samym początku, tylko wyzwalacze z poziomu wierszy, 2 2011-01-20 Tworzenie wyzwalaczy Ciało wyzwalacza składa się z opcjonalnej sekcji deklaracji, wówczas rozpoczyna się ona słowem DECLARE, Sekcja wyjątków jest opcjonalna, Ciało wyzwalacza nie może być większe niż 32 KB, ze względu na to że jest często wywoływane musi być krótkie. Rodzaje wyzwalaczy DML Kategoria Wartości Instrukcja INSERT, UPDATE, DELETE Pojedyncze instrukcje powodujące uruchamianie wyzwalacza lub ich kombinacje BEFORE, AFTER Wyzwalacz jest uruchamiany przed lub po wykonaniu instrukcji, Moment wykonania Poziom wykonania Wiersze lub instrukcje Tworzenie wyzwalaczy DML Kolejność uruchamiania wyzwalaczy DML Wyzwalacz działający dla wierszy uruchamia się raz dla każdego z nich użytego przez instrukcję ( za jego utworzenie odpowiada klauzula FOR EACH ROW), wyzwalacze z poziomu instrukcji są uruchamiane jeden raz przed lub po jego wykonaniu, Uruchamiane są dla instrukcji INSERT, UPDATE, DELETE, przed ich wykonaniem lub po, jeden raz dla każdego zmodyfikowanego wiersza lub instrukcji, W związku z różnymi trybami istnieje 28 typów wyzwalaczy DML – 7 instrukcji wraz z kombinacjami * 2 momenty wykonania * 2 poziomy wykonania. Wyzwalacze z poziomu instrukcji BEFORE, Dla każdego wiersza, którego dotyczy instrukcja: BEFORE z poziomu wiersza, Polecenie, AFTER z poziomu wiersza, Wyzwalacze z poziomu instrukcji typu AFTER. 3 2011-01-20 Wyzwalacz z poziomu instrukcji przykład Wyzwalacz z poziomu wierszy przykład CREATE OR REPLACE TRIGGER test BEFORE INSERT ON employees BEGIN IF (TO_CHAR(SYSDATE,’DY’) IN (’SO’,’N’)) THEN RAISE_APPLICATION_ERROR(-20500,’Nie wstawiaj do tabeli w weekend’); END IF; END; CREATE OR REPLACE TRIGGER test BEFORE INSERT OR UPDATE ON employees FOR EACH ROW BEGIN :new.job_id:=upper(:new.job_id); END; Identyfikatory :old i :new Identyfikatory :old i :new W wyzwalaczu z poziomu wiersza można uzyskać dostęp do danych tego wiersza, W tym celu używamy dwóch identyfikatorów korelacji :old i :new, które są specjalnymi zmiennymi powiązanymi, Są one traktowane jako rekord tabeli z którą powiązany jest wyzwalacz, Są one nazywane pseudorekordami, bo są one rekordami tylko w składni, nie można przypisywać ich jako całych rekordów. Instrukcja Stara wartość Nowa wartość INSERT NULL Wstawiane wartości UPDATE Wartości sprzed aktualizacji Wartości po aktualizacji DELETE Wartości sprzed usuwania NULL Odwołania do pól pseudorekordu :new.pole w Oracle mamy jeszcze dodatkowy identyfikator :parent związany z tabelami zagnieżdżonymi. 4 2011-01-20 Identyfikatory - przykład Klauzula REFERENCING CREATE OR REPLACE TRIGGER Id BEFORE INSERT ON employees FOR EACH ROW BEGIN SELECT employees_seq.NEXTVAL INTO :new.employee_id FROM employees; END; Klauzula WHEN WHEN - przykład Używany dla wyzwalacza z poziomu wierszy, Ciało zostanie wykonane tylko dla wierszy, które spełniają warunek, Składnia: WHEN warunek; Warunek to wyrażenie logiczne, można w nim używać identyfikatorów :new i :old, bez dwukropka, Służy do określenia innej nazwy identyfikatorów :old i :new, Po zdarzeniu wyzwalającym należy użyć składni: REFERENCING [OLD AS nazwa] [NEW AS nazwa] Wówczas w ciele wyzwalacza można używać nowych nazw dla pól pseudorekordu, CREATE OR REPLACE TRIGGER Id BEFORE INSERT OR UPDATE OF salary ON employees FOR EACH ROW WHEN (new.salary >20000) BEGIN RAISE_APPLICATION_ERROR(-20202,’Pracownik nie może zarabiać więcej niż 20000’); END; 5 2011-01-20 Predykaty wyzwalaczy Dla wyzwalaczy w których używane są więcej niż jedna instrukcja DML można używać dodatkowych funkcji logicznych: INSERTING, DELETING, UPDATING, Każda z nich zwraca TRUE jeśli instrukcja wyzwalająca to ta która jest z nim powiązania, w przeciwnym przypadku zwraca FALSE, Status wyzwalacza Od wersji Oracle 11g wyzwalacz może być w dwóch stanach: aktywny i nieaktywny, Wcześniej błąd w ciele wyzwalacza powodował niepowodzenie w wykonaniu instrukcji DML na tabeli, Można ustalić stan wyzwalacza na nieaktywny i przełączyć go tylko wtedy, gdy mamy pewność że wyzwalacz wykona się prawidłowo, Predykaty - przykład CREATE OR REPLACE TRIGGER pred BEFORE INSERT OR DELETE OR UPDATE ON employees BEGIN IF (TO_CHAR(SYSDATE,’DY’) IN (’SO’,’ N’)) THEN IF INSERTING THEN RAISE_APPLICATION_ERROR(-20500,’Nie wstawiaj do tabeli w weekend’); END IF; IF DELETING THEN RAISE_APPLICATION_ERROR(-20500,’Nie usuwaj z tabeli w weekend’); END IF; IF UPDATING THEN RAISE_APPLICATION_ERROR(-20500,’Nie modyfikuj tabeli w weekend’); END IF; END IF; END; Status wyzwalacza Można także tymczasowo anulować aktywność wyzwalacza w przypadku gdy obiekt do którego się odnosi jest niedostępny, jeśli chcemy przetworzyć dużą porcję danych i nie chcemy tego poprzedzać działaniem wyzwalacza lub przetworzyć dane ponownie, Aby utworzyć nieaktywny wyzwalacz należy dodać w jego definicji przed słowem kluczowym BEGIN słowo DISABLE, 6 2011-01-20 Status wyzwalacza Polecenia związane z wyzwalaczami User_triggers – dane na temat wyzwalaczy: nazwa, tabela powiązana, czas kompilacji, itd., atrybuty dostępne po wywołaniu polecenia DESCRIBE user_triggers; SELECT trigger_name, trigger_body FROM user_triggers; User_errors – informacje na temat błędów które nastąpiły w czasie kompilacji wyzwalacza, Zmiana statusu wyzwalacza ALTER TRIGGER nazwa ENABLE | DISABLE; Zmiana statusu wyzwalaczy dla danej tabeli ALTER TABLE nazwa DISABLE | ENABLE ALL TRIGGERS; Ponowna kompilacja wyzwalacza ALTER TRIGGER nazwa COMPILE; Usunięcie wyzwalacza DROP TRIGGER nazwa; Wyzwalacz zastępujący Wyzwalacz zastępujący - przykład Wyzwalacza typu INSTEAD OF, Używany zamiast instrukcji DML i tylko dla widoków, Używamy w dwóch przypadkach: W celu dokonywania zmian w widoku, którego nie możemy w inny sposób modyfikować, W celu modyfikowania kolumn tabeli zagnieżdżonej w widoku, Wyzwalacze te działają na poziomie wierszy, CREATE OR REPLACE VIEW dzial AS SELECT department_name, COUNT(*) FROM employees NATURAL JOIN departments GROUP BY department_name; widok CREATE OR REPLACE TRIGGER widok INSTEAD OF INSERT ON dzial FOR EACH ROW BEGIN INSERT INTO departments (department_id, department_name) VALUES (dzialyseq.nextval, :new.department_name); END; 7 2011-01-20 Wyzwalacze systemowe Wywoływane dla zdarzeń DDL (CREATE, ALTER, DROP) oraz zdarzeń bazy danych (uruchomienie i zamknięcie serwera, logowanie i wylogowanie użytkownika, błędy serwera), Tworzenie wyzwalaczy systemowych Wyzwalacze systemowe są powiązane jedynie z czasem wyzwalania BEFORE lub AFTER, Można je definiować z poziomu bazy danych lub schematu, te zdefiniowane z poziomu bazy są wykonywane przy każdym wystąpieniu zdarzenia, zaś te z poziomu schematu tylko wtedy gdy zdarzenie wystąpi w konkretnym schemacie, Domyślnie jest przyjmowany schemat do którego należy dany wyzwalacz, Tworzenie wyzwalaczy systemowych CREATE [OR REPLACE] TRIGGER {BEFORE | AFTER} {zdarzenia_DDL | zdarzenia_bazy_danych} ON {DATABASE | [schemat.]SCHEMA} [WHEN warunek] [DECLARE] BEGIN Ciało; [EXCEPTION … ] END; Zdarzenia DDL i bazy danych STARTUP – AFTER – wykonywane przy uruchamianiu egzemplarza bazy, SHUTDOWN – BEFORE – przy zamykaniu, z wyjątkiem nietypowego zamknięcia, SERVERERROR – AFTER – przy każdym wystąpieniu błędu, LOGON – AFTER – po zalogowaniu użytkownika, LOGOFF – BEFORE – przy wylogowywaniu użytkownika, 8 2011-01-20 Zdarzenia DDL i bazy danych CREATE, DROP, ALTER, RENAME, DDL – AFTER, BEFORE – po lub przed utworzeniem, usunięciem, modyfikacją, zmianą nazwy obiektu schematu i po lub przed zgłoszeniem większości instrukcji DDL, Wyzwalacz systemowy - przykład CREATE OR REPLACE TRIGGER logow AFTER LOGON ON SCHEMA BEGIN INSERT INTO logowania (user_id, log_date, dzialanie) VALUES (USER, SYSDATE,’Logowanie’); END; Funkcje-atrybuty zdarzeń Funkcje-atrybuty zdarzeń Pozwalają na pobieranie w ciele wyzwalacza informacji o zdarzeniu wyzwalającym. ORA_DICT_OBJ_TYPE zwraca VARCHAR2(20), związane z ALTER, CREATE, DDL, DROP, GRANT, RENAME, zwraca typ obiektu słownika dla którego zaszła operacja DDL ORA_IS_CREATING_NESTED_TABLE zwraca BOOLEAN, związane z CREATE, zwraca true jeśli zdarzenie tworzy tabelę zagnieżdżoną, ORA_IS_DROP_COLUMN (nazwa kolumny IN VARCHAR2) zwraca BOOLEAN, związane z DROP, zwraca true jeśli kolumna została usunięta, ORA_IS_ALTER_COLUMN (nazwa kolumny IN VARCHAR2) zwraca BOOLEAN, związane z ALTER, zwraca true jeśli kolumna została zmodyfikowana przez zdarzenie, ORA_LOGIN_USER Zwraca VARCHAR2(20), związane ze wszystkimi zdarzeniami, zwraca nazwę zalogowanego użytkownika, ORA_SYSEVENT Zwraca VARCHAR2, związane ze wszystkimi zdarzeniami, zwraca nazwę zdarzenia systemowego uruchamiającego dany wyzwalacz, 9 2011-01-20 Klauzula WHEN a wyzwalacze systemowe W wyzwalaczach systemowych można używać klauzuli WHEN uwzględniając pewne ograniczenia warunku: STARTUP i SHUTDOWN nie mogą mieć żadnych warunków, W SERVERERROR można sprawdzać wartość ERRNO, by uruchamiać wyzwalacze przy wystąpieniu określonych błędów, W LOGON i LOGOFF można sprawdzać nazwę i identyfikator użytkownika, Wyzwalacze DDL mogą sprawdzać typ i nazwę modyfikowanego obiektu oraz identyfikator i nazwę użytkownika. Wyzwalacze - informacje Przestrzeń nazw wyzwalaczy jest inna niż pozostałych podprogramów, Wyzwalacz (ani jego funkcje czy procedury) nie może wywoływać instrukcji kontrolnych (COMMIT, SAVEPOINT, etc.), nie można w nim także deklarować zmiennych typu LONG i LONG RAW, Ciało wyzwalacza nie może modyfikować wartości kolumn typu LOB, CALL w wyzwalaczach CALL w wyzwalaczach Od wersji Oracle 8i ciałem wyzwalacza może być instrukcja CALL, Wywołujemy procedurę, która jest napisana w PL/SQL, C lub Javie, Kod wywołania (brak średnika na końcu): CALL nazwa_procedury Jako parametry procedury można używać identyfikatory :new i :old, CREATE OR REPLACE TRIGGER pensja BEFORE UPDATE ON employees FOR EACH ROW CALL sprawdz_pensje(:new.salary) / 10 2011-01-20 Wyzwalacze a uprawnienia CREATE TRIGGER – pozwala na tworzenie wyzwalacza w swoim schemacie, CREATE ANY TRIGGER – j.w., we wszystkich schematach, oprócz SYS, ALTER ANY TRIGGER – pozwala włączać, wyłączać oraz kompilować wyzwalacze w dowolnym schemacie, DROP ANY TRIGGER – pozwala na usuwanie wyzwalaczy z dowolnego schematu, ADMINISTER DATABASE TRIGGER – pozwala na tworzenie i modyfikację wyzwalaczy systemowych bazy danych, Tabele mutujące Instrukcje SQL w ciele wyzwalacza nie mogą: Pobierać i modyfikować danych z tabel mutujących, które są używane w instrukcjach wyzwalacza, także z samej tabeli wyzwalającej, Pobierać danych z kolumn z kluczem głównym, unikalnym ani zewnętrznym tabel ograniczających tabeli wyzwalającej, pozostałe kolumny można modyfikować, Odnosi się to do wyzwalaczy z poziomu wierszy, do wyzwalaczy z poziomu instrukcji tylko wtedy gdy wyzwalacz jest uruchomiony w wyniki instrukcji DELETE CASCADE, Tabele mutujące Tabela mutująca – tabela aktualnie modyfikowana przez instrukcje DML oraz tabela wymagająca aktualizacji ze względu na ograniczenia integralnościowe (DELETE CASCADE), Tabela ograniczająca – należy ja wczytać ze względu na ograniczenie spójności odwołań, Tabele mutujące - przykład CREATE OR REPLACE TRIGGER pensja BEFORE INSERT OR UPDATE ON employees FOR EACH ROW DECLARE v_max employees.salary%type; BEGIN BŁAD SELECT MAX(salary) INTO v_max ORA-4091, table … is mutating FROM employees WHERE department_id=:new.department_id; IF :new.salary>v_max THEN RAISE_APPLICATION_ERROR(…); END IF; END; 11 2011-01-20 Tabele mutujące - rozwiązanie Należy utworzyć dwa wyzwalacze z poziomu wierszy i poziomu instrukcji, W pierwszym można używać potrzebnych identyfikatorów korelacji (:new, :old), zaś w drugim można kierować zapytania do tabeli wyzwalającej, Należy jednak przekazać wartość identyfikatora z jednego wyzwalacza do drugiego, Wyzwalacze złożone Pojawiły się w wersji Oracle 11g, Pozwalają na utworzenie jednego wyzwalacza dla czerech różnych momentów i poziomów wykonania, Mają sekcję deklaracji oraz sekcje dla każdego z czterech momentów i poziomów wykonania, Są rozwiązaniem problemu tabel mutujących, dużo bardziej wydajnym niż wykorzystywanie pakietów i tabel PL/SQL, Tabele mutujące - rozwiązanie Jedno z rozwiązań polega na utworzeniu pakietu wraz z tabelą lub tabelami PL/SQL, W pakiecie zmienne, kolekcje są globalne, W tabelach można zapisać wiele wartości, Wartości są widziane w obu wyzwalaczach, które są zawarte w pakiecie jako jego podprogramy, Wyzwalacze złożone - sekcje Sekcje wyzwalacza złożonego to (w odpowiedniej kolejności): BEFORE STATEMENT AFTER STATEMENT BEFORE EACH ROW AFTER EACH ROW 12 2011-01-20 Wyzwalacze złożone - schemat CREATE OR REPLACE TRIGGER nazwa FOR zdarzenie ON tabela COMPOUND TRIGGER sekcja deklaracji, podprogramów BEFORE STATEMENT IS …; AFTER STATEMENT IS …; BEFORE EACH ROW IS …; AFTER EACH ROW IS …; END; FOLLOWS Ograniczenia wyzwalaczy złożonych Dotyczą wyzwalaczy DML na tabelach lub widokach, Ciało wyzwalacza to blok PL/SQL, Ciało nie ma sekcji wyjątków, Identyfikatorów korelacji nie można używać w części deklaracyjnej i sekcjach AFTER i BEFORE STATEMENT, Tworzenie wyzwalaczy w SQL Developer Nowość w Oracle 11g, Pozwala na ustalenie kolejności wykonywania wyzwalaczy, Składnia: CREATE OR REPLACE TRIGGER nazwa BEFORE INSERT ON tabela FOR EACH ROW FOLLOWS nazwa1 wówczas wyzwalacz nazwa zostanie poprzedzony przez nazwa1 Okno programu SQL Developer 13 2011-01-20 Obsługa wyzwalaczy w SQL Developer WYKORZYSTANA LITERATURA J. Price, Oracle Database 11g i SQL. Programowanie. Helion, 2009. S. Urman, R. Hardman, M. McLaughlin, Oracle Database 10g. Programowanie w języku PL/SQL. Helion, 2008. www.oracle.com Okno programu SQL Developer 14