33
Databázové systémy II Přednáška č. 6 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky [email protected]

Databázové systémy II

Embed Size (px)

DESCRIPTION

Databázové systémy II. Přednáška č. 6 RNDr. David Žák, Ph.D . Fakulta elektrotechniky a informatiky david.zak @ upce.cz. Obsah. Triggery pro DML p říkazy nad tabulkami . Triggery pro databázové a klientské události. Příklady použití triggerů. - PowerPoint PPT Presentation

Citation preview

Page 1: Databázové systémy II

Databázové systémy II

Přednáška č. 6

RNDr. David Žák, Ph.D.Fakulta elektrotechniky a informatiky

[email protected]

Page 2: Databázové systémy II

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í.

Databázové systémy II - př. 6 2

Page 3: Databázové systémy II

TriggeryTrigger 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ě.

Databázové systémy II - př. 6 3

Page 4: Databázové systémy II

Triggery

Databázové systémy II - př. 6 4

Page 5: Databázové systémy II

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í

Databázové systémy II - př. 6 5

Page 6: Databázové systémy II

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.

Databázové systémy II - př. 6 6

Page 7: Databázové systémy II

Triggery – DMLSyntaxe

CREATE [OR REPLACE] TRIGGER <název triggeru> { BEFORE | AFTER } [INSTEAD OF] { INSERT | UPDATE | DELETE } ON <název tabulky> [FOR EACH ROW [WHEN <podmínka provedení triggeru> ]]

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 klazulí OR (např. INSERT OR DELETE)

Databázové systémy II - př. 6 7

Page 8: Databázové systémy II

TriggeryPříklady

CREATE [OR REPLACE] TRIGGER potvrzeni_1AFTER 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_allAFTER UPDATE ON ucitele FOR EACH ROW BEGIN

DBMS_OUTPUT.PUT_LINE(`Záznam byl úspěšně změněn`);

END;

Databázové systémy II - př. 6 8

Page 9: Databázové systémy II

TriggeryPříklad

CREATE [OR REPLACE] TRIGGER zaloha_pracovnikuBEFORE DELETE ON pracovnici FOR EACH ROW BEGIN

INSERT INTO byvali_pracovnici VALUES (:OLD.id_prac, :OLD.jmeno, …);

END;

- :OLD označuje staré hodnoty (použití pro příkazy DELETE, UPDATE)- :NEW označuje nové hodnoty (použití pro příkazy INSERT, UPDATE)

Databázové systémy II - př. 6 9

Page 10: Databázové systémy II

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);

Databázové systémy II - př. 6 10

Page 11: Databázové systémy II

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 :newpřed provedením vlastní akce

:new.id := 1000 + :new.id

Databázové systémy II - př. 6 11

Page 12: Databázové systémy II

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 ROWBEGIN :new.Uppername := UPPER(:new.Ename);END;

Databázové systémy II - př. 6 12

Page 13: Databázové systémy II

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.

Databázové systémy II - př. 6 13

Page 14: Databázové systémy II

Triggery - INSTEAD OF INSTEAD OF triggery umožní provést změny do tabulek, na které se pohledy odkazují.

CREATE VIEW emp_locations ASSELECT e.employee_id, e.last_name || ', ' || e.first_name name, d.department_name department, l.city city, c.country_name countryFROM employees e, departments d, locations l, countries cWHERE e.department_id = d.department_id AND d.location_id = l.location_id

AND l.country_id = c.country_idORDER 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_triggerINSTEAD OF UPDATE ON emp_locationsBEGIN-- 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;

Databázové systémy II - př. 6 14

Page 15: Databázové systémy II

Triggery - modifikace

CREATE OR REPLACE TRIGGER new_evaluation_trigger BEFORE INSERT ON evaluations FOR EACH ROWBEGIN :NEW.evaluation_id := evaluations_seq.NEXTVAL;END;

Databázové systémy II - př. 6 15

Page 16: Databázové systémy II

Triggery - odstranění

Pro odstranění triggeru použijte příkaz DROP

DROP TRIGGER triggername;

Databázové systémy II - př. 6 16

Page 17: Databázové systémy II

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;

Databázové systémy II - př. 6 17

Page 18: Databázové systémy II

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

Databázové systémy II - př. 6 18

Page 19: Databázové systémy II

Triggery – pohled USER_TRIGGERSPří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;

Databázové systémy II - př. 6 19

Page 20: Databázové systémy II

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

Databázové systémy II - př. 6 20

Page 21: Databázové systémy II

Triggery pro databázové událostiDatabázové události

STARTUPSHUTDOWNDB_ROLE_CHANGESERVERERROR

Databázové systémy II - př. 6 21

Page 22: Databázové systémy II

Triggery pro klientské událostiKlientské události

BEFORE / AFTER ALTERBEFORE / AFTER DROPBEFORE / AFTER ANALYZEBEFORE / AFTER ASSOCIATE STATISTICSBEFORE / AFTER AUDITBEFORE / AFTER NOAUDITBEFORE / AFTER COMMENTBEFORE / AFTER CREATE BEFORE / AFTER DDLBEFORE / AFTER DISASSOCIATE STATISTICSBEFORE / AFTER GRANTAFTER LOGON / BEFORE LOGOFFBEFORE / AFTER RENAMEBEFORE / AFTER REVOKEAFTER SUSPENDBEFORE / AFTER TRUNCATE

Příklad

CREATE OR REPLACE TRIGGER On_Logon AFTER LOGON ON The_user.Schema BEGIN Do_Something; END;

Databázové systémy II - př. 6 22

Page 23: Databázové systémy II

TTriggery - riggery - LOGON a LOGOFFLOGON a LOGOFFVytvář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.SCHEMABEGIN INSERT INTO hr_users_log VALUES (USER, 'LOGON', SYSDATE);END;

CREATE OR REPLACE TRIGGER note_hr_logoff_trigger BEFORE LOGOFF ON HR.SCHEMABEGIN INSERT INTO hr_users_log VALUES (USER, 'LOGOFF', SYSDATE);END;

Databázové systémy II - př. 6 23

Page 24: Databázové systémy II

ROLLBACK in PL/SQLROLLBACK in PL/SQLNá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;

Databázové systémy II - př. 6 24

Page 25: Databázové systémy II

Triggery – vyvolání chybyTriggery – vyvolání chybyPří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 ROWDECLARE

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;

Databázové systémy II - př. 6 25

Page 26: Databázové systémy II

Triggery - příkladPříklad

CREATE OR REPLACE TRIGGER Print_salary_changes BEFORE DELETE OR INSERT OR UPDATE ON Emp_tab FOR EACH ROWWHEN (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 ... ;

Databázové systémy II - př. 6 26

Page 27: Databázové systémy II

Triggery - kaskádování

Databázové systémy II - př. 6 27

Page 28: Databázové systémy II

FOREIGN KEY – DML operacezajištěné omezeními

DML příkaz V 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ý řádekvždy OK

DELETE Cascade vždy OK , ovlivněné řádky se automaticky odstraní vždy OK

DELETE Set Nullvždy OK , hodnota cizího klíče v ovlivněných řádcích se změní na

NULLvždy OK

Databázové systémy II - př. 6 28

Page 29: Databázové systémy II

FOREIGN KEY – DML operaces nutností zajištění triggery

DML příkaz V tabulce rodičů V tabulce potomků

UPDATE CASCADE vždy OKDovoleno, pokud nová

hodnota cizího klíče existuje v tabulce rodičů (nebo je NULL)

UPDATE Set NullVž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 DefaultVž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 Defaultvždy OK , hodnota cizího klíče v ovlivněných řádcích se změní na

default hodnotuvždy OK

Databázové systémy II - př. 6 29

Page 30: Databázové systémy II

TriggeryPříklad

create or replace Trigger Dodavatele_update_cascadeafter update of dodavatel_id on dodavatele for each rowbegin-- Změní hodnoty cizího klíče pokud hodnota v rodičovské tabulce byla změněnaif (:old.dodavatel_id != :new.dodavatel_id) then

beginupdate Produkty

set dodavatel_id = :new.dodavatel_idwhere dodavatel_id = :old.dodavatel_id;

end;end if;end;

Databázové systémy II - př. 6 30

Page 31: Databázové systémy II

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 ALTER TABLE tablename tablename DISABLE CONSTRAINT constraint_nameDISABLE CONSTRAINT constraint_name;;

ALTER TABLE ALTER TABLE tablename tablename ENABLE CONSTRAINT constraint_name;ENABLE CONSTRAINT constraint_name;

Databázové systémy II - př. 6 31

Page 32: Databázové systémy II

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

Databázové systémy II - př. 6 32

Page 33: Databázové systémy II

Triggery

Vytvoření triggeru v SQL developeruVytvoření triggeru v SQL developeru

http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28843/tdddg_triggers.htm#BABECIAEhttp://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#i1007097http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/triggers.htm#i1007097

Databázové systémy II - př. 6 33