Databázové triggery Aktivní pravidla Jan Plonka
Přehled Co jsou to triggery? Historie Pojmy a členění triggerů Jednotlivé realizace + příklady Známé problémy
Co je to trigger? Příkaz (příp. procedura), kterou db systém automaticky vykoná při výskytu specifikované události. Významné rozšíření kontroly integritních omezení poskytovaných SŘBD. Řešení je v současnosti spojeno s operacemi INSERT, DELETE, UPDATE. Svázán s definicí tabulky. V architektuře klient-server je vykonáván na serveru.
Historie konec 80. let – snaha o standardizaci ’92 standard SQL92 je neobsahuje Mnoho otevřených otázek Zvláště oblast předcházení vzájemného vyvolávání triggerů Snaha výrobců zachovávat standard x mnoho nejasností => rozdíly v implementacích Standardizace v SQL:1999 (příkaz CREATE TRIGGER)
Pojmy Události – primitiva ve změně stavu db Některé systémy navíc monitorují: Výběry dat Časově závislé události (např. 17hod každý Pátek) Externí události explicitně vyvolané jinou aplikací Podmínka – buď db predikát nebo dotaz Vrací pravdivostní hodnotu. V případě dotazu: TRUE = výsledek dotazu je neprázdný, FALSE jinak.
Pojmy(2) Akce – libovolný program manipulující s daty. Může dále obsahovat: Transakční příkazy (např. ROLLBACK WORK) Příkazy manipulující s triggery (aktivace, deaktivace jednoho či skupiny triggerů. Může aktivovat i externě definované procedury.
Stavy pravidla (triggeru) Pravidlo je: Spuštěno (triggered) – pokud dojde k relevantní události Vyhodnoceno (considered) – po vyhodnocení podmínky Vykonáno (executed) – po provedení akce
Poté, co příkazy definované uživatelem spustí zpracování pravidel (rule processing) Samostatné V kontextu oddělené transakce, která je vytvořena původní transakcí poté, co nastane sledovaná událost. Členění Okamžité – vyhodnocení akce: Před tím, než je událost monitorována Poté, co událost nastane Namísto události Odložené Na konci transakce Na konci uživatelsky definovaných příkazů Podle vyhodnocení triggeru monitorované události:
Členění(2) Podle vykonání akce vzhledem k vyhodnocení: Okamžité – akce se vykoná okamžitě po vyhodnocení podmínky – nejčastější případ Odložené – odloží vykonání akce na konec transakce nebo uživatelem definovaného příkazu zpracování pravidel Samostatné – v kontextu oddělené transakce vytvořené z původní po vyhodnocení podmínky
Členění(3) Podle úrovně granularity sledovaných změn: Na úrovni instance – tj. změny ovlivňující jednotlivé řádky v tabulce (příp. objekty tříd) Na úrovni příkazů – příkazy manipulující s daty jsou považovány za události. Pozn. Úroveň granularity ovlivňuje obsah transakčních hodnot – dočasných dat popisujících změny stavu provedených transakcí.
Členění (4) Podle priority výběru triggerů z konfliktní množiny: Konfliktní množina – množina triggerů, které mohou být spuštěny současně. Úplné uspořádání – každý z triggerů má jednoznačnou číselnou prioritu Částečné uspořádání – priority jsou specifikovány číselně nebo relativně. Systém vytvoří úplné uspořádání konzistentní s částečným Triggery jsou vybírány nedeterministicky Systém neobsahuje prioritní mechanismus Systém používá vnitřní úplné uspořádání Triggery jsou vybírány nedeterministicky
Další rysy a vlastnosti Opakovatelnost vykonávání V prostředí se systémově definovanými prioritami Za stejných podmínek a stavu db je posloupnost vykonávání triggerů vždy stejná. Aktivace / deaktivace triggerů podléhá autorizaci (možné porušení kontroly IO) Sdružování do skupin Hromadné zpracování, aktivace, deaktivace
Některé relační systémy podporující triggery Starburst (IBM) Oracle DB2 Informix Sybase Illustra Reach – základ Open OODB Ode NAOS – rozšíření O2 Chimera
Starburst Triggery založeny na schématu Událost-Podmínka-Akce (ECA) Událost – příkaz SQL pro manipulaci s daty (INSERT, DELETE, UPDATE) Podmínka – predikát nad stavem databáze, vyjádřen příkazy SQL Akce – libovolný SQL dotaz ( včetně SELECT, INSERT, DELETE, UPDATE); navíc mohou obsahovat příkazy pro manipulaci s triggery a transakční instrukci ROLLBACK WORK Intuitivní sémantika – když událost nastane, pokud je podmínka platná, proveď akci.
Triggery jsou přidány do schématu a sdíleny všemi aplikacemi Transakce mohou dynamicky aktivovat/deaktivovat existující triggery Triggery mohou být seskupovány Vlastnosti triggeru Starburst
Příklad CREATE RULE KontrolaMezd ON Zam WHEN INSERTED, DELETED, UPDATED (Mzda) IF (SELECT AVG(Mzda) FROM Zam) > 100 THEN UPDATE Zam SET Mzda =.9 * Mzda Starburst Trigger kontroluje modifikace v platech zaměstnanců. Pokud průměrný plat překročí danou hodnotu (100), jsou všechny platy příslušně redukovány.
Vytvoření triggeru := CREATE RULE ON WHEN [ IF ] THEN [ PRECEDES ] [ FOLLOWS ] := INSERTED | DELETED | UPDATED [( )] Starburst
Sémantika triggerů Odložené vykonávání triggery jsou prováděny v kontextu dané transakce implicitní inicializace probíhá po provedení COMMIT WORK provádění triggerů lze explicitně vyvolat příkazem PROCESS RULES. Stavy triggeru Nespuštěn (untriggered) – na začátku transakce Spuštěn – objeví-li se spouštějící událost (triggering event) Konfliktní množina - tvořena aktuálně spuštěnými triggery Starburst
Algoritmus provádění pravidel z konfliktní množiny WHILE ( konfliktní množina ≠ Ø ) { 1. Vyber nějaký trigger T z konfliktní množiny z triggerů s nejvyšší prioritou; změn stav T na „nespuštěn“. 2. Vyhodnoť podmínku v T. 3. Pokud je podmínka v T splněna, proveď akci danou T. } Opakovatelnost vykonání – systém vytváří úplné uspořádání kompatibilní s uživatelským částečným pomocí údaje o čase vytvoření triggeru. Starburst
Další příkazy triggeru Aktivace triggeru := ACTIVATE RULE ON Deaktivace triggeru := DEACTIVATE RULE ON Smazání triggeru:= DROP RULE ON Starburst
Příkazy skupiny triggerů Vytvoření skupiny := CREATE RULESET Modifikace skupiny := ALTER RULESET [ ADDRULES ] [ DELRULES ] Smazání skupiny := DROP RULESET Starburst
Uvažujme transakci, která přidá n-tice (Rick, 150) a (John, 200). Vložení spustí trigger KontrolaMezd, proběhne vyhodnocení podmínky, tato je splněna (AVG(Mzda) = 112) a akce je vykonána. Nový stav vypadá takto: Příklad – provedení triggeru CREATE RULE KontrolaMezd ON Zam WHEN INSERTED, DELETED, UPDATED (Mzda) IF (SELECT AVG(Mzda) FROM Zam) > 100 THEN UPDATE Zam SET Mzda =.9 * Mzda Původní tabulka: ZaměstnanecMzda Stefano81 Patrick81 Michael99 Rick135 John108 Starburst ZaměstnanecMzda Stefano90 Patrick90 Michael110
Příklad(2) Operace UPDATE znovu spustí trigger Podmínka je vyhodnocena, splněna (AVG(Mzda) = 101) a akce je znovu provedena: Starburst ZaměstnanecMzda Stefano73 Patrick73 Michael89 Rick121 John97 Trigger je UPDATEm znovu spuštěn Podmínka je vyhodnocena, nyní vrací FALSE Provádění je ukončeno klidovým stavem (quiescent state). Provádění akce triggeru tedy konverguje ke klidovému stavu. Správný návrh konvergujících akcí je obvykle zodpovědností autora triggeru
Příklad (3) CREATE RULE DobřePlacení ON Zam WHEN INSERTED IF EXISTS (SELECT * FROM INSERTED WHERE Mzda > 100) THEN INSERT INTO DobřePlaceníZam (SELECT * FROM INSERTED WHERE Mzda > 100) FOLLOWS PrumernaMzda Starburst
Oracle Podpora obecně použitelných triggerů dle předběžné specifikace k SQL:1999 Akce mohou obsahovat libovolný PL/SQL kód Události jsou operace manipulující s daty (INSERT, DELETE, UPDATE) na dané cílové tabulce Podpora dvou granularit: Řádková – spouštění triggeru se projeví na každém řádku, který byl ovlivněn operací Příkazová – podobná jako u Starburst.
Vlastnosti a typy triggerů Triggery jsou okamžité – vyhodnocení je úzce spjato s provedením spouštěcí operace – srovnej Starburst (opožděné spouštění) Triggery mohou být vyhodnoceny a vykonány před a po spouštěcí operaci. Kombinací granularit a časů vyvolání dostáváme tyto možnosti: 1. Řádková granularita a spouštění před operací 2. Příkazová granularita a spouštění před operací 3. Řádková granularita, spouštění po operaci 4. Příkazová granularita, spouštění po operaci
Syntaxe :=CREATE TRIGGER { BEFORE | AFTER } ON [ [ REFERENCING ] FOR EACH ROW [ WHEN ( ) ] ] := INSERT | DELETE | UPDATE [ OF ] := OLD AS | Nový AS
Příklad CREATE TRIGGER Přeobjednej AFTER UPDATE OF DílPoRuce ON Sklad WHEN (Nový.DílPoRuce < Nový.HraniceNovéObjednávky) FOR EACH ROW DECLARE NUMBER X BEGIN SELECT COUNT(*) INTO X FROM NevyřízenéObjednávky WHERE Díl = Nový.Díl; IF X = 0 THEN INSERT INTO NevyřízenéObjednávky VALUES(Nový.Díl, Nový.ObjednávanéMnožství, SYSDATE) END IF; END;
Stav tabulky Sklad: Předpokládejme, že tabulka NevyřízenéObjednávky je na počátku prázdná. Příklad (2) DílDílPoRuceHraniceNovéObjed návky PřeobjednávanéMnožství
Příklad (3) Vezměme následující transakci (provedenou 10. října 1996) T1: UPDATE Sklad SET DílPoRuce = DílPoRuce – 70 WHERE Díl = 1 Způsobí vykonání triggeru Přeobjednej, který do tabulky NevyřízenéObjednávky zapíše n-tici (1, 100, ). Dále předpokládejme následující transakci provedenou týž den: T2:UPDATE Sklad SET DílPoRuce = DílPoRuce – 60 WHERE Díl >= 1 Zde je trigger vykonán nad všemi n-ticemi a podmínka je splněna pro části 1 a 3. Zapsána je však jen n-tice (3, 120, ), neboť n- tice s částí 1 již v tabulce je. Pozn. Přestože T1 a T2 jsou potvrzeny odděleně, výsledky T1 jsou v T2 viditelné.