Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Databázové systémy II Přednáška č. VII Ing. Tomáš Váňa, Ing. Jiří Zechmeister Fakulta elektrotechniky a informatiky

Podobné prezentace


Prezentace na téma: "Databázové systémy II Přednáška č. VII Ing. Tomáš Váňa, Ing. Jiří Zechmeister Fakulta elektrotechniky a informatiky"— Transkript prezentace:

1 Databázové systémy II Přednáška č. VII Ing. Tomáš Váňa, Ing. Jiří Zechmeister Fakulta elektrotechniky a informatiky tomas.vana@upce.cz, jiri.zechmeister@upce.cz

2 Obsah Triggery pro DML příkazy nad tabulkami. Triggery pro databázové a klientské události Příklady použití triggerů. Příklady využití triggerů a omezení pro dodržení integritních omezení. Triggery pro databázové a klientské události. Příklady použití triggerů. Příklady využití triggerů a omezení pro dodržení integritních omezení IDAS2 - Přednáška VII 2

3 Triggery Trigger je uložená procedura, která se spouští za přesně definovaných událostí. Můžeme tedy říci, že trigger je množina příkazů, které se automaticky provedou v případě předem definované operace (INSERT, DELETE, UPDATE) s daty (a to buď před či po vlastní operaci). Použití: -kontrola zadaných dat, -zajištění referenční integrity. Procedury, triggery, funkce jsou uložené přímo v databázi spolu s dalšími databázovými strukturami jako jsou tabulky, pohledy, sekvence, indexy, … To znamená, že do databáze se umísťují nejenom data, ale i aplikační logika pro jejich zpracování. To umožňuje jednodušší distribuci, přispívá ke spolehlivosti. Procedury jsou uloženy v databázi v předkompilované podobě. IDAS2 - Přednáška VII 3

4 Triggery IDAS2 - Přednáška VII 4

5 Triggery Použití: -kontrola zadaných dat -zajištění komplexní referenční integrity v databázi -automatické generování odvozené hodnoty hodnot sloupců -zamezení invalidním transakcím -zajištění komplexní bezpečnostní autorizace -implementace business pravidel -zajištění logování událostí -poskytování auditů -zajištění synchronní replikace tabulek -generování statistik přístupu k tabulkám -modifikace dat v tabulce, když DML příkaz používá pohled -publikace informací o událostech a příkazech do jiných aplikací IDAS2 - Přednáška VII 5

6 Triggery Zajištění integrity Triggery by se měly využít pouze v případě, kdy: -není možné použít následujících integritních omezení: -NOT NULL, UNIQUE -PRIMARY KEY -FOREIGN KEY -CHECK -DELETE CASCADE -DELETE SET NULL -tabulky nejsou v jedné databázi atd. IDAS2 - Přednáška VII 6

7 Triggery – DML Syntaxe CREATE [OR REPLACE] TRIGGER { BEFORE | AFTER } [INSTEAD OF] { INSERT | UPDATE | DELETE } ON [FOR EACH ROW [WHEN ]] BEGIN … výkonná sekce …………………………. END; Musíme určit: -akci, která trigger aktivuje, -kdy se trigger aktivuje - před či po, -zda se trigger spouští pro každý zpracovávaný řádek FOR EACH ROW nebo jen jednou, -případně, zda trigger nahrazuje operaci, která jej spustila INSTEAD OF (pouze pro pohledy) -více spouštěcích příkazů lze oddělit klauzulí OR (např. INSERT OR DELETE) IDAS2 - Přednáška VII 7

8 Triggery Typy aktivačních událostí – Aktivační událost na úrovni řádků - Pro každý řádek, který je ovlivněn příkazem DML se trigger spustí jednou. Trigger se vytváří s klauzulí FOR EACH. Využití: Dodatečná úprava modifikovaných dat (generování unikátních klíčů pro nové řádky, ověření neměnitelnosti primárního klíče). Tento typ triggeru má přístup k hodnotám (původním/novým) sloupců aktuálně zpracovávaného řádku. – Aktivační událost na úrovni příkazu - V rámci jednoho DML příkazu se spustí trigger jen jednou, bez ohledu na to, kolik řádků příkaz ovlivní. Využití: Audit DML operací -> zaznamenávání jednotlivých DML operací jako celků. IDAS2 - Přednáška VII 8

9 Triggery Příklady CREATE [OR REPLACE] TRIGGER potvrzeni_1 AFTER UPDATE ON ucitele BEGIN DBMS_OUTPUT.PUT_LINE(`Záznam(y) byl(y) úspěšně změněn(y)`); END; CREATE [OR REPLACE] TRIGGER potvrzeni_all AFTER UPDATE ON ucitele FOR EACH ROW BEGIN DBMS_OUTPUT.PUT_LINE(`Záznam byl úspěšně změněn`); END; IDAS2 - Přednáška VII 9

10 Triggery Příklad CREATE [OR REPLACE] TRIGGER zaloha_pracovniku BEFORE DELETE ON pracovnici FOR EACH ROW BEGIN INSERT INTO byvali_pracovnici VALUES (:OLD.id_prac, :OLD.jmeno, …); END; -:OLDoznačuje staré hodnoty (použití pro příkazy DELETE, UPDATE) -:NEWoznačuje nové hodnoty (použití pro příkazy INSERT, UPDATE) IDAS2 - Přednáška VII 10

11 Triggery IDAS2 - Přednáška VII 11

12 Triggery – poznámky k použití Upřesnění: -INSTEAD OF triggery jsou jen pro pohledy a mají implicitně nastaveno FOR EACH ROW -AFTER a BEFORE triggery nelze pro pohledy použít -pro akci UPDATE je možné specifikovat sloupce, při jejichž změně bude trigger aktivován pomocí klauzule UPDATE OF seznam sloupců BEFORE DELETE OR INSERT OR UPDATE OF ename ON Emp_tab -příklad volání procedury v těle triggeru: CREATE TRIGGER hr.salary_check BEFORE INSERT OR UPDATE OF salary, job_id ON hr.employees FOR EACH ROW WHEN (new.job_id <> 'AD_VP') CALL check_sal(:new.job_id, :new.salary, :new.last_name); IDAS2 - Přednáška VII 12

13 Triggery - doporučení Doporučení pro použití BEFORE a AFTER triggerů: -použijte BEFORE row triggery pro modifikování řádku před zápisem dat na disk -použijte AFTER row triggery k získání a zajištění operací používajících ROWID -BEFORE triggery jsou více efektivní, protože nevyžadují dvojí čtení dat -BEFORE triggery umožňují změnit hodnotu :new před provedením vlastní akce :new.id := 1000 + :new.id IDAS2 - Přednáška VII 13

14 Vlastnosti triggerů VlastnostChování INSERTINGTRUE, jestliže se jedná o příkaz INSERT, jinak FALSE UPDATINGTRUE, jestliže se jedná o příkaz UPDATE, jinak FALSE DELETINGTRUE, jestliže se jedná o příkaz DELETE, jinak FALSE IDAS2 - Přednáška VII 14 Uvnitř triggeru můžeme používat tři logické funkce (INSERTING, UPDATING, DELETING), které umožní identifikovat, který příkaz inicioval spuštění triggeru.

15 Příklad využití: IDAS2 - Přednáška VII 15 Vlastnosti triggerů

16 Triggery – odvozené hodnoty sloupců Triggery mohou odvozovat hodnoty sloupců automaticky na základě hodnot zadaných v příkazech INSERT nebo UPDATE. Tento typ triggerů je vhodný pro případ, kdy odvozené hodnoty jsou vkládány do stejných řádků jako hodnoty uvedené v příkazech INSERT nebo UPDATE. Pro toto řešení je nezbytné použít BEFORE row triggery. Příklad: CREATE OR REPLACE TRIGGER Derived BEFORE INSERT OR UPDATE OF Ename ON Emp99 /* Před změnou sloupce ENAME urči hodnotu UPPERNAME Omezte uživatele ke změnám tohoto sloupce přímo: */ FOR EACH ROW BEGIN :new.Uppername := UPPER(:new.Ename); END; IDAS2 - Přednáška VII 16

17 Triggery – poznámky k použití Přílišné využití triggerů může způsobit nepřehlednost aplikace (jejich přehlížení) Nepoužívejte rekursivní triggery Pozor při použití kaskádních triggerů Nepoužívejte triggery tam, kde si můžete pomoci například omezeními (CHECK na vkládané hodnoty). Nedělejte kód triggerů delší než 32KB. Pokud by měl být delší, použijte procedur a funkcí. Není možné použít příkazy COMMIT, ROLLBACK nebo SAVEPOINT v těle triggeru. Protože DDL příkazy způsobují implicitní COMMIT, nemohou být také proto použity v triggerech, s výjimkou příkazů CREATE, ALTER, DROP TABLE a ALTER...COMPILE pro systémové triggery. IDAS2 - Přednáška VII 17

18 Triggery - INSTEAD OF INSTEAD OF triggery umožní provést změny do tabulek, na které se pohledy odkazují. CREATE VIEW emp_locations AS SELECT e.employee_id, e.last_name || ', ' || e.first_name name, d.department_name department, l.city city, c.country_name country FROM employees e, departments d, locations l, countries c WHERE e.department_id = d.department_id AND d.location_id = l.location_id AND l.country_id = c.country_id ORDER BY last_name; Příklad INSTEAD OF triggeru update_name_view_trigger pro změnu jména zaměstnance. CREATE OR REPLACE TRIGGER update_name_view_trigger INSTEAD OF UPDATE ON emp_locations BEGIN -- allow only the following update(s) UPDATE employees SET first_name = substr( :NEW.name, instr( :new.name, ',' )+2), last_name = substr( :NEW.name, 1, instr( :new.name, ',')-1) WHERE employee_id = :OLD.employee_id; END; IDAS2 - Přednáška VII 18

19 Triggery s podmínkou WHEN IDAS2 - Přednáška VII 19

20 Složené triggery Od verze 11g lze vytvářet triggery, které mají pro každý z následujících okamžiků časování samostatný oddíl: – BEFORE, BEFORE EACH ROW, AFTER, AFTER EACH ROW Složená aktivační událost má pro každou oblast časování vlastní oddíl. – Všechny oddíly mohou přistupovat ke sdíleným stavovým informacím. IDAS2 - Přednáška VII 20

21 Složené triggery IDAS2 - Přednáška VII 21 Klíčové slovo FOR a COMPOUND TRIGGER Každý typ aktivační události má svůj vlastní blok. Každý blok je nutné ukončit názvem typu aktivační události.

22 Složené triggery Pravidla: – Složený trigger musí být typu DML, a musí být definován nad tabulkou nebo pohledem. – Když se v oddílu vyskytne výjimka, je třeba ji vyřešit právě v onom oddíle. Není možné ji přenést do jiného oddílu. – Klíčová slova :OLD a :NEW se nemohou nacházet v oddíle deklarací, v oddíle BEFORE STATEMENT ani v oddíle AFTER STATEMENT. – Hodnotu proměnné :NEW může měnit pouze oddíl BEFORE EACH ROW. – Pořadí spouštění není u složeného triggeru zaručeno. Spuštění triggeru může být prokládáno spouštěním jednoduchých aktivačních událostí. IDAS2 - Přednáška VII 22

23 Triggery -> výjimky Pokud trigger spustí příkaz, který vyvolá výjimku a tato výjimka není ošetřena, databáze odroluje (ROLLBACK) jak data modifikovaná triggerem tak data modifikovaná dotazem, který trigger spustil. IDAS2 - Přednáška VII 23

24 Triggery - modifikace CREATE OR REPLACE TRIGGER new_evaluation_trigger BEFORE INSERT ON evaluations FOR EACH ROW BEGIN :NEW.evaluation_id := evaluations_seq.NEXTVAL; END; IDAS2 - Přednáška VII 24

25 Triggery - odstranění Pro odstranění triggeru použijte příkaz DROP DROP TRIGGER triggername; IDAS2 - Přednáška VII 25

26 Triggery – deaktivace a aktivace (blokování a povolení) V určitých případech může být vhodné/požadované dočasně deaktivovat funkci triggeru, například při vkládání řádků odkazujících na neexistující objekty, importu větších objemů dat (obnova dat ze zálohy atd.) bez prodlevy. Pro konkrétní trigger: ALTER TRIGGER triggername DISABLE; ALTER TRIGGER triggername ENABLE; Pro všechny triggery svázané s konkrétní tabulkou: ALTER TABLE tablename DISABLE ALL TRIGGERS; ALTER TABLE tablename ENABLE ALL TRIGGERS; IDAS2 - Přednáška VII 26

27 Triggery – pohled USER_TRIGGERS Příkaz pro zjištění triggerů v uživatelově schématu: SELECT Trigger_type, Triggering_event, Table_name FROM USER_TRIGGERS WHERE Trigger_name = 'REORDER'; TYPE TRIGGERING_STATEMENT TABLE_NAME ---------------- -------------------------- ------------ AFTER EACH ROW UPDATE INVENTORY IDAS2 - Přednáška VII 27

28 Triggery – pohled USER_TRIGGERS Příkazy pro zjištění triggerů a jejich obsahu v uživatelově schématu: SELECT Trigger_body FROM USER_TRIGGERS WHERE Trigger_name = 'REORDER'; TRIGGER_BODY -------------------------------------------- DECLARE x NUMBER; BEGIN SELECT COUNT(*) INTO x FROM Pending_orders WHERE Part_no = :new.Part_no; IF x = 0 THEN INSERT INTO Pending_orders VALUES (:new.Part_no, :new.Reorder_quantity, sysdate); END IF; END; IDAS2 - Přednáška VII 28

29 Triggery - auditování Triggery jsou obvykle použity k doplnění vestavěných auditovacích funkcí Oracle databáze. Ačkoli triggery mohou ukládat informace obdobně těm ukládaným příkazem AUDIT, používejte triggery jenom v případě, kdy jsou potřeba více podrobné auditovací informace - například pro value-based audit pro každý řádek. Občas se používaní příkazu AUDIT považuje za bezpečnostní audit, kdežto používání triggerů za finanční audit. DML a DDL audit: Standardní auditovací vlastnosti umožňují audit DML a DDL příkazů v souvislosti se všemi objekty a strukturami schématu Triggery umožňují audit DML příkazů nad tabulkami a audit DDL příkazů na úrovni SCHEMA nebo DATABASE. Více lze najít na: http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/triggers.htm http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/triggers.htm IDAS2 - Přednáška VII 29

30 Triggery pro databázové události Databázové události STARTUP SHUTDOWN DB_ROLE_CHANGE SERVERERROR IDAS2 - Přednáška VII 30

31 Triggery pro klientské události Klientské události BEFORE / AFTER ALTER BEFORE / AFTER DROP BEFORE / AFTER ANALYZE BEFORE / AFTER ASSOCIATE STATISTICS BEFORE / AFTER AUDIT BEFORE / AFTER NOAUDIT BEFORE / AFTER COMMENT BEFORE / AFTER CREATE BEFORE / AFTER DDL BEFORE / AFTER DISASSOCIATE STATISTICS BEFORE / AFTER GRANT AFTER LOGON / BEFORE LOGOFF BEFORE / AFTER RENAME BEFORE / AFTER REVOKE AFTER SUSPEND BEFORE / AFTER TRUNCATE Příklad CREATE OR REPLACE TRIGGER On_Logon AFTER LOGON ON The_user.Schema BEGIN Do_Something; END; IDAS2 - Přednáška VII 31

32 Triggery - LOGON a LOGOFF Vytváření LOGON a LOGOFF Triggerů, které monitorují uživatele databáze do logovací tabulky. Vytvořme tabulku hr_users_log pro ukládání informací o událostech LOGON a LOGOFF. Následně vytvoříme triggery note_hr_logon_trigger a note_hr_logoff_trigger pro zápis informací o těchto událostech do tabulky. CREATE TABLE hr_users_log (user_name VARCHAR2(30), activity VARCHAR2(20), event_date DATE); CREATE OR REPLACE TRIGGER note_hr_logon_trigger AFTER LOGON ON HR.SCHEMA BEGIN INSERT INTO hr_users_log VALUES (USER, 'LOGON', SYSDATE); END; CREATE OR REPLACE TRIGGER note_hr_logoff_trigger BEFORE LOGOFF ON HR.SCHEMA BEGIN INSERT INTO hr_users_log VALUES (USER, 'LOGOFF', SYSDATE); END; IDAS2 - Přednáška VII 32

33 ROLLBACK in PL/SQL Následující příklad vkládá informace o zaměstnanci do třech různých databázových tabulek. Jestliže nějaký INSERT se pokouší uložit duplicitní číslo zaměstnance, je vyvolána předdefinovaná výjimka DUP_VAL_ON_INDEX. Pro zajištění integrity je třeba zajistit, že v případě vyvolání výjimky jsou změny ve všech tabulkách odvolány, k čemuž je použit příkaz ROLLBACK. NELZE použít v triggeru. CREATE TABLE emp_name AS SELECT employee_id, last_name FROM employees; CREATE UNIQUE INDEX empname_ix ON emp_name (employee_id); CREATE TABLE emp_sal AS SELECT employee_id, salary FROM employees; CREATE UNIQUE INDEX empsal_ix ON emp_sal (employee_id); CREATE TABLE emp_job AS SELECT employee_id, job_id FROM employees; CREATE UNIQUE INDEX empjobid_ix ON emp_job (employee_id); DECLARE emp_id NUMBER(6); emp_lastname VARCHAR2(25); emp_salary NUMBER(8,2); emp_jobid VARCHAR2(10); BEGIN SELECT employee_id, last_name, salary, job_id INTO emp_id, emp_lastname, emp_salary, emp_jobid FROM employees WHERE employee_id = 120; INSERT INTO emp_name VALUES (emp_id, emp_lastname); INSERT INTO emp_sal VALUES (emp_id, emp_salary); INSERT INTO emp_job VALUES (emp_id, emp_jobid); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN ROLLBACK; DBMS_OUTPUT.PUT_LINE('Inserts were rolled back'); END; IDAS2 - Přednáška VII 33

34 Triggery – vyvolání chyby Příklad demonstruje vyvolání chyb, která zamezí vložení trpaslíka do tabulky trpaslíků, pokud jich v této tabulce již bude 7: CREATE OR REPLACE TRIGGER omezeni_trpasliku BEFORE INSERT on TRPASLICI FOR EACH ROW DECLARE v_pocet_trpasliku NUMBER; BEGIN SELECT COUNT(*) INTO v_pocet_trpasliku FROM trpaslici; IF v_pocet_trpasliku >= 7 THEN RAISE_APPLICATION_ERROR(-20005,'Trpaslíků může být maximálně sedm'); END IF; END omezeni_trpasliku; IDAS2 - Přednáška VII 34

35 Triggery - příklad Příklad CREATE OR REPLACE TRIGGER Print_salary_changes BEFORE DELETE OR INSERT OR UPDATE ON Emp_tab FOR EACH ROW WHEN (new.Empno > 0) DECLARE sal_diff number; BEGIN sal_diff := :new.sal - :old.sal; dbms_output.put('Old salary: ' || :old.sal); dbms_output.put(' New salary: ' || :new.sal); dbms_output.put_line(' Difference ' || sal_diff); END; Trigger bude aktivován pro příkazy: DELETE FROM Emp_tab; INSERT INTO Emp_tab VALUES (... ); INSERT INTO Emp_tab SELECT... FROM... ; UPDATE Emp_tab SET... ; IDAS2 - Přednáška VII 35

36 Triggery - kaskádování IDAS2 - Přednáška VII 36

37 FOREIGN KEY – DML operace zajištěné omezeními DML příkazV tabulce rodičůV tabulce potomků INSERT vždy OK, pokud je hodnota klíče unikátní OK pouze v případě, pokud je hodnota cizího klíče existuje v tabulce rodičů nebo je NULL UPDATE No Action (default, občas se označuje jako restrict) Dovoleno v případě, kdy žádná hodnota cizího klíče v tabulce potomků nezůstane bez vazby na tabulku rodičů Dovoleno, pokud nová hodnota cizího klíče existuje v tabulce rodičů (nebo je NULL) DELETE No Action (default, občas se označuje jako restrict) Dovoleno v případě, kdy žádná hodnota v tabulce potomků se neodkazuje na vymazávaný řádek vždy OK DELETE Cascade vždy OK, ovlivněné řádky se automaticky odstraní vždy OK DELETE Set Null vždy OK, hodnota cizího klíče v ovlivněných řádcích se změní na NULL vždy OK IDAS2 - Přednáška VII 37

38 FOREIGN KEY – DML operace s nutností zajištění triggery DML příkazV tabulce rodičůV tabulce potomků UPDATE CASCADE vždy OK Dovoleno, pokud nová hodnota cizího klíče existuje v tabulce rodičů (nebo je NULL) UPDATE Set Null Vždy OK, hodnota cizího klíče v ovlivněných řádcích se změní na NULL, pozor na rozpad referenční integrity Dovoleno, pokud nová hodnota cizího klíče existuje v tabulce rodičů (nebo je NULL) UPDATE Default Vždy OK, hodnota cizího klíče v ovlivněných řádcích se změní na default hodnotu, pozor na rozpad referenční integrity Dovoleno, pokud nová hodnota cizího klíče existuje v tabulce rodičů (nebo je NULL) DELETE Set Default vždy OK, hodnota cizího klíče v ovlivněných řádcích se změní na default hodnotu vždy OK IDAS2 - Přednáška VII 38

39 Triggery Příklad create or replace Trigger Dodavatele_update_cascade after update of dodavatel_id on dodavatele for each row begin -- Změní hodnoty cizího klíče pokud hodnota v rodičovské tabulce byla změněna if (:old.dodavatel_id != :new.dodavatel_id) then begin update Produkty set dodavatel_id = :new.dodavatel_id where dodavatel_id = :old.dodavatel_id; end; end if; end; IDAS2 - Přednáška VII 39

40 Omezení - constraint Při importu dat (většinou z jedné databáze do jiné) mohou nastat problémy s integritními omezeními. Příkladem je nevhodné pořadí vytvářených tabulek a dat do nich vkládaných (tj. například není vložen řádek do nadřízené tabulky, na níž se daný řádek v podřízené tabulce odkazuje). Řešením je vypnutí omezení během importu a poté je opět obnovit. Je třeba mít na paměti, že pokud data nebudou splňovat požadavky omezení, nebude možné již tato omezení obnovit. V takovém případě je nezbytné nejdříve data upravit a teprve poté aktivovat omezení, například: ALTER TABLE tablename DISABLE CONSTRAINT constraint_name; ALTER TABLE tablename ENABLE CONSTRAINT constraint_name; IDAS2 - Přednáška VII 40

41 Omezení - constraint Jakékoli omezení zvyšuje náklady na práci s řádky tabulky (INSERT, UPDATE, DELETE) Zjednodušeně lze říci že nároky rostou v pořadí - NOT NULL - UNIQUE - PRIMARY KEY - FOREIGN KEY - CHECK - TRIGGERY IDAS2 - Přednáška VII 41

42 Typy pro práci s triggers http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/triggers.htm#i1006211 http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/triggers.htm#i1006211 IDAS2 - Přednáška VII 42

43 Triggery Vytvoření triggeru v SQL developeru http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28843/tdddg_triggers.htm#BABECIAE http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/triggers.htm#i1007097 IDAS2 - Přednáška VII 43


Stáhnout ppt "Databázové systémy II Přednáška č. VII Ing. Tomáš Váňa, Ing. Jiří Zechmeister Fakulta elektrotechniky a informatiky"

Podobné prezentace


Reklamy Google