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