COMPUTERWORLD
pod kapotou
Trigger

Dnešní díl databázové abecedy je věnován databázovým objektům, které umožňují vyjádřit procedurálně integritní omezení (IO). Jak již je patrné z názvu, nebudeme se pokoušet o žádné české přijatelné vyjádření tohoto dnes populárního databázového pojmu, třebaže se lze setkat s výrazy jako spouštěč, spoušť apod. Co je to však trigger? Jak často zdůrazňuji, nejde opět o nic příliš nového. Již v roce 1976 byla koncepce triggeru popsána ve výzkumné zprávě IBM Specifications and Interactions of Trigger Subsystem in an Integrated Database System od K.P.Eswarena. Trigger byl popsán jako “předdefinovaná databázová procedura, která podmíněně nebo nepodmíněně automaticky následuje nebo předchází jinou databázovou operaci”. Definice vycházející spíše z připravovaného standardu SQL3 považuje trigger spíše za pojmenovaný databázový objekt, který

  • je implicitně aktivován, jestliže nastane událost podmiňující jeho spuštění,
  • je-li aktivován, vyvolá akci, je-li splněna daná podmínka.

Podstatné je pojmenování triggeru. Je možné se na něj odkazovat v hlášeních o chybách, lze jej zrušit příkazem DROP, v řadě implementací lze trigger dočasně “umrtvit” a později “oživit”. Za zdůraznění stojí i automatická aktivace odrážející pouze výskyt jistých událostí evokovaných uživatelem či aplikačními programy.

Událostí se myslí specifická situace vyskytující se v databázovém systému, např. vstup (INSERT) řádku x do tabulky PŘEDSTAVENÍ(NÁZEV, JMÉNO_F). Je-li např. splněna podmínka, že x.JMÉNO_F neodpovídá žádnému řádku z tabulky FILM, lze operaci INSERT vhodnou akcí odmítnout. Uvedený příklad zřejmě znamená kontrolu referenční integrity mezi tabulkou PŘEDSTAVENÍ a FILM. Je patrné, že triggerem lze implementovat mnohem obecnější IO, zřejmě i taková, která nejdou vyjádřit neprocedurálně na úrovni konstruktů definice databáze podle standardu SQL92. Výhodou navíc je, že je současně k dispozici možnost definovat akci. Akce je procedura nebo posloupnost procedurálních operací, která implementuje potenciálně netriviální procesní logiku, požadovanou aplikací. Jestliže současnou možnosti referenční integrity je např. kaskádového odstranění řádků, pak akcí v triggerech lze implementovat složitější procesy. Např. zvýšení rozpočtu oddělení (tabulka ODDĚLENÍ) může triggerem spustit akci, která procentuálně zvýší odměny jeho zaměstnanců (tabulka ZAMĚSTNANEC). Tento příklad odpovídá zajištění spíše nějakého pravidla specifikovaného aplikací (často se hovoří o business rules).

Trigger představuje procedurální řešení jistých problémů, které nebylo možné jednoduše řešit neprocedurálním způsobem. Jde zvláště o to, jak reagovat při narušení IO, kde zatím SQL92 nabízí spíše chybové hlášení nebo jednoduchou akci (např. dosazení NULL nebo implicitní hodnoty). Složitější akce se stává součástí aplikačního programu, na rozdíl od řešení s triggerem, který ji naopak přenese k definici databáze. Navíc, vyvolání triggeru nastává jindy než při narušení neprocedurálních IO ve stávajícím SQL.

Použití triggerů

Kontrola integrity databáze či zajišťování aplikačních požadavků pomocí triggerů tedy zvyšuje možnosti dané neprocedurálními konstrukty. Použití triggerů je ovšem širší. Lze jimi mimo jiné zjišťovat:

  • ochranu dat, tj. trigger může kontrolovat, zdali uživatel má právo provést operaci. V databázovém serveru PROGRESS lze pomocí triggeru dokonce omezovat data viditelná pro uživatele, tj. trigger může být spuštěn při operaci SELECT.
  • auditní záznamy, tj. triggerem lze udržovat speciální soubory (žurnály) se záznamy jistých operací např. na citlivých datech,
  • aktualizaci pohledů, které nemusí být aktualizovatelné na úrovni standardu SQL92. Tento prvek v sobě má např. InterBase. Správce databáze naprogramuje vlastně “ručně” aktualizaci pohledu přímým vstupem dat do zdrojových tabulek.
  • replikaci, kde trigger zajišťuje vytvoření bufferů změn replikovaných tabulek, které posléze replikační server propaguje do cílových databází.

Výhody triggerů zahrnují:

  • rychlejší vývoj aplikace (akce prováděné triggery jsou vytvořeny a umístěny jednou, nemusí být kódovány pro každou aplikaci),
  • globální provádění aplikačních pravidel (trigger je definován jednou a lze ho použít pro jakoukoli aplikaci, která mění tabulku),
  • jednodušší údržba aplikačních pravidel (změna ve světě aplikace vyžaduje pouze změnu triggeru, nikoliv více aplikačních programů),
  • centrální aktivace triggerů vyhovuje dobře architektuře klient/server, tj. data a operace se zbytečně “neprotahují” sítí.

Specifikace triggerů

Hlavní nevýhodou současných přístupů ke triggerům je v tom, že triggery nebyly nabídnuty standardem SQL92. Autoři standardu zřejmě podcenili rostoucí požadavky na používání triggerů. Přitom v systémech Sybase, Ingres a Interbase se triggery používají již od roku 1989. Volba syntaxe, sémantika i implementace triggerů se tak staly u jednotlivých výrobců SŘBD jistým problémem, ve kterém zřejmě nejvhodnější cestou je možnost využít již řadu let známého návrhu přístupu k triggerům podle připravovaného standardu SQL3.

Podle SQL3 jsou události spouštějící trigger aktualizační operace INSERT, DELETE a UPDATE (buď na vybrané sloupce nebo na celou tabulku). Možnost využívající SELECT (viz zmíněný PROGRESS) je tedy nestandardní. Podmínka může být vyjádřitelná jakoukoliv SQL podmínkou, akce může být jakýkoliv SQL příkaz, tj. využívající dokonce procedurální příkazy, tak jak je nabízí v SQL3 jazyk pro psaní transakcí (SQL/PSM). Další volbou je čas aktivace. Trigger může být aktivován před (BEFORE) nebo po (AFTER) aktualizační operaci. Akce může být provedena pro každý řádek (FOR EACH ROW), který splňuje podmínku, nebo pouze jednou pro celý příkaz triggeru (FOR EACH STATEMENT). Druhá možnost je implicitní. Protože při formulaci podmínky či akce triggeru pro UPDATE je často potřeba odkaz na starou a novou hodnotu, lze použít klauzuli REFERENCING, kde starou hodnotu (OLD) a novou (NEW) lze vhodně přejmenovat s klíčovým slovem AS. Např. chceme-li měnit v tabulce PŘEDSTAVENÍ představení, tj. provádět UPDATE pro jméno filmu, lze v těle CREATE TRIGGER použít

REFERENCING OLD AS PŮVODNÍ

NEW AS NOVÝ

Uvažujme příklad, kdy při změně představení (dvojice název kina spolu s filmem) v tabulce PŘEDSTAVENÍ se hlídá, aby film nebyl od Věry Chytilové (stálí návštěvníci kina ji nemají rádi). Trigger může vypadat následovně:

CREATE TRIGGER NE_CHYTIL

BEFORE UPDATE OF FILM ON PŘEDSTAVENÍ /* událost * /

REFERENCING OLD AS PŮVODNÍ

NEW AS NOVÝ

WHEN ((SELECT REŽISÉR /* podmínka* /

FROM FILM F

WHERE F.JMÉNO_F = NOVÝ. JMÉNO_F) = Chytilová)

CALL_TO_NECHTEJI (“Tento film ne”) /* akce * /

Protože SQL/PSM není doposud k dispozici, provádí se zápis akci v jednotlivých SŘBD různě. Např. v ORACLE se používá PL/SQL, tj. jazyk z rodiny 4GL jazyků. Podobně k problému přistupuje SYBASE či INGRES (spíše CA-OpenIngres). V posledním případě jsou triggery nazývány pravidla (rules). Ta volají uložené procedury provádějící akce. Připomeňme ale, že koncepce těchto pravidel odpovídá pouze možnosti AFTER.

Implementace triggerů

Co se týče implementace, mohlo by se zdát, že trigger je uložená procedura. Vždy tomu tak ale není. Např. SŘBD ORACLE udržuje zdrojové texty triggerů v databázi, přičemž ke kompilaci dochází až po prvním použití triggeru. Naopak, trigger může volat uloženou proceduru. Např. v Microsoft SQL Severu může dokonce jít o volání vzdálené procedury (RPC - Remote Procedure Call).

Implementace triggerů se také liší v množství, kolik jich je dovoleno na jednu tabulku. Např. SQLBase firmy Centura Software Corp. (dříve Gupta Corp.) povoluje 6 triggerů (tři operace x 2 možnosti aktivace), Microsoft SQL Server povoluje 3 triggery. Obecnější přístup v SQL3 ovšem dovoluje definovat i více triggerů na jednu událost a čas aktivace. Pořadí jejich aplikace odpovídá pořadí jejich vytvoření v databázi. Protože trigger může způsobit vyvolání dalšího triggeru, lze hovořit o kaskádách triggerů.

Výhody triggerů jsou nesporné. Bude ovšem zajímavé, jak se databázové firmy vyrovnají se standardem SQL3. Trigger je velmi silný mechanismus, jehož použití výrazně ovlivňuje návrh IS v architektuře klient/server. Znamená opět další přesun logiky z aplikace k databázi.



<seznam dílů seriálu>   <COMPUTERWORLD>