Download presentation
Presentation is loading. Please wait.
1
Trigeriai 10 Paskaita
2
Santrauka Įvairių tipų trigeriai DB trigeriai ir jų naudojimas
DB trigerių kūrimas DB trigerių veikimo taisyklės DB trigerių šalinimas
3
Duomenų bazės trigeriai
Kas yra trigeris? Trigeris tai aibė veiksmų, kurie automatiškai atliekami vykdant: lentelės eilučių šalinimą (vykdant SQL sakinį DELETE), keitimą (UPDATE), naujų eilučių įterpimą (INSERT).
4
Trigerių tipai Trigeris tai:
Pl/SQL blokas ar PL/SQL procedūra susieta su lentele, vaizdu (view), schema, duomenų baze. Vykdomas neatvirai, kai vyksta tam tikri įvykiai. Gali būti: Aplikacijos trigeris: vykdomas, kai įvykis iškyla tam tikroje aplikacijoje. Duomenų bazės trigeris: vykdomas, kai duomenų (DML) ar sistemos įvykis (logon ar shutdown) iškyla schemoje ar D.B. Aplikacijos su trigeriais pavyzdys yra formos sukurtos su :Oracle Developer Forms” įrankiu. DB trigeris vykdomas neatvirai, kai iškyla duomenų įvykis, pvz. DML veiksmai ant lentelės, INSTEAD OF trigeris ant vaizdo (vew), ar duomenų apibrėžimo sakinys (DDL komanda) , pvz. vykdant CREATE ir ALTER, neatsižvelgiant į tai kokiu vartotoju prisijungta ar kokia aplikacija yra naudojama. DB trigeris neatvirai vykdomas ir kai iškyla tam tikri vartotojo ar duomenų bazės sistemos veiksmai, pvz. Kai vartotojas prisijungia (logon), ar DBA išjungia duomenų bazę (shut down). Pastaba: DB trigeriai g.b. sukurti ant lentelių ir vaizdų (view). Jei DML operacija vykdoma ant vaizdo (view), INSTEAD OF trigeris nustato ,kurį veiksmą atlikti. Jei šie veiksmai yra DML operacijos ant lentelių, tai suveikia visi trigeriai ant d.b. Lentelių. DB trigeriai g.b. sistemos trigeriai ant DB ar schemos. Duomenų bazės trigeris šauna kiekvienam vartotojo įvykiui. Shemos trigeris šauna kiekvienam įvykiui konkrečiam vartotojui. Trigerių tipai: · DML trigeriai, rašomi lentelėse; · INSTEAD OF trigeriai, rašomi rodiniuose (views); · Sisteminiai trigeriai, rašomi duomenų bazėse (iškviečiami esant veiksmams, aktyvuotiems bet kurio tos bazės vartotojo) ir schemose (iškviečiami esant veiksmams, aktyvuotiems tam tikro tos bazės vartotojo).
5
DB trigerių paskirtis Palaikyti duomenų neprieštaringumą;
Atlikti operacijas lentelėse, nedalyvaujančiose operacijos metu; Veiksmai, kuriuos reikia atlikti įvykus konkrečiam įvykiui, apibrėžiami SQL sakiniais. Trigeriai, kaip ir deklaratyvūs apribojimai yra naudojami duomenų neprieštaringumui palaikyti. Trigeriai gali būti naudojami ir kitų, tiesiogiai nedalyvaujančių operacijoje, lentelių modifikavimui priklausomai nuo atliekamos operacijos pagrindinėje lentelėje, pvz., renkant statistiką apie kiekvieną duomenų modifikavimą lentelėje (pakeitus bet kurią eilutę lentelėje, kitoje lentelėje įtraukiama nauja eilutė).
6
DB trigerių kūrimo gairės
Trigeriai kuriami norint: Atlikti susijusius veiksmus. Centralizuoti globalias operacijas (DB trigeriai veikiantys nepriklausomai nuo to kuris vartotojas ar aplikacija vykdo sakinį). Trigerių nereikia kurti: Kai funkcionalumas jau įgyvendintas Oracle serveryje Dubliuojamas kitas Trigeris Kuriamos DB procedūros ir iškviečiamos trigeryje, jei PL/SQL kodas yra labai ilgas. Per didelis trigerių naudojimas gali sukelti sudėtingas priklausomybes ir pasunkinti didelių aplikacijų palaikymą Trigerių nereikia kurti pvz., kai norima įgyventinti duomenų vientisumo taisykles. Jas galima palaikyti su apribojimais (constraint). Verslo taisyklės kūrimo tvarka yra: Oracle serverio apribojimų (constraints) naudojimas (primarey key, foreign key ir t.t.). Duomenų bazės trigerio kūrimas. Oracle formų kūrimas ir pan., jei negalima panaudoti taisyklių išvardintų aukščiau. Trigeriai t.b. Naudojami tik tada, kai reikia, reikia vengti rekursinių kaskadinių priklausomybių. DB trigeriai šauna kiekvieną kartą kai iškyla įvykis, kuriam (ant kurio) trigeris sukurtas.
7
DB trigerio pavyzdys Aplikacija INSERT INTO EMPLOYEES...;
EMPLOYEES table employee_id last_name job_id salary CHECK_SAL trigeris Trigeris CHECK_SAL tikrina algos reikšmes kai aplikacija įterpinėja įrašus į EMPLOYEES lentelę. Reikšmės, kurios nepriklauso nurodytam pareigybės intervalui yra atmetamos, arba g.b. Priimamos ir įrašomos į auditinę lentelę.
8
DB trigerių kūrimas Trigeriai kuriami sakiniu CREATE TRIGGER,
kuriame nurodoma: Kurį SQL duomenų modifikavimo sakinį vykdant: (INSERT, UPDATE ar DELETE), kviesti trigerį. Kokiu momentu trigerį aktyvuoti: Lentelėse prieš vykdant modifikavimo operaciją (BEFORE), Lentelėse po (AFTER) Vaizduose (view) vietoj (INSTEAD OF), Lentelės vardas: lentelė ar vaizdas (view) Trigerio tipas: aktyvuojamas kiekvieną kartą vykdant SQL sakinį (STATEMEN), aktyvuojamas kiekvienai operacijoje dalyvaujančiai eilutei (ROW). trigerio kūnas - vienas ar keli SQL sakiniai, kuriuos reikia įvykdyti, kai trigeris iškviečiamas; trigerio kūno vykdymo sąlyga: iškviesto kūno sakinius vykdyti besąlygiškai ar tik tuomet, kai patenkinta konkreti sąlyga Dalis trigerio veikimo momentas Aprašymas kada trigeris šauna įvykus susijusiam įvykiui Galimos reikšmės BEFORE,AFTER,INSTEAD OF. Dalis trigerį iššaukiantis įvykis Aprašymas kuri DML operacija ant lentelės ar vaizdo iššaukia trigerį Galimos reikšmės INSERT, UPDATE, DELETE. Dalis trigerio tipas Aprašymas kiek kartų bus vykdomas trigeris Galimos reikšmės STATEMENT, ROW. Dalis trigerio kūnas Aprašymas kokį veiksmą atlieka trigeris Galimos reikšmės Pilnas PL/SQL blokas. Jei lentelei sukurti keli trigeriai, reikia žinoti kad tvarka, kuria jie vykdomi yra atsitiktinė. Norint užtikrinti to paties tipo trigerių veikimo tvarką, reikia sukurti vieną trigerį, kuris kviečia skirtingas procedūras norima tvarka.
9
DML trigerio komponentai
Trigerio veikimo momentas: BEFORE: trigerio kūnas vykdomas prieš iškviečiantį DML įvykį ant lentelės. AFTER: trigerio kūnas vykdomas po iškviečiančio DML įvykio ant lentelės. INSTEAD OF: trigerio kūnas vykdomas vietoj iškviečiančio įvykio. Šis tipas naudojamas vaizudose (view), kurie nėra kitaip keičiami. BEFORE trigeris dažnai naudojamas: Norint apibrėžti ar trigerį kviečiantis sakinys gali būti įvykdytas (šioje situacijoje galima išvengti trigerį kviečiančio įvykio vykdymo ir sukelti trigerį iškvietusio įvykio atšaukimą “rollback”,trigerio veiksmams sukėlus išimtį). Norint apskaičiuoti stulpelių reikšmes prieš įvykdant INSERT ar UPDATE sakinius. Norint inicializuoti globalius kintamuosius ir vėliavėles, arba validuoti (įgyvenditin) kompleksines verslo taisykles AFTER trigeris dažnai naudojamas: Norint užbaigti trigerį iškvietusį sakinį prieš trigerio vykdant trigerio veiksmus. Norint atlikti įvairius veiksmus tame pačiame trigerį iškvietusiame sakinyje, jei BEFORE trigeris jau yra. BEFORE ir AFTER raktai kontroliuoja, kada reikia pradėti trigerio aktyvavimą. Šie raktai rašomi CREATE TRIGGER sakinyje. Praktikoje daugiau efektyvesni yra AFTER eilės trigeriai. Su BEFORE raktu paveiktas duomenų blokas nuskaitomas du kartus: vieną kartą prieš, o kitą kartą po trigerio. Pirmą kartą siunčiami į lenteles duomenys pereina per kontrolę, leidžiama pakeisti klaidingus duomenis, o po to tik perrašyti keliauja į lenteles. Taip gaištamas laikas, jei duomenų blokas būna nemažas. INSTEAD OF trigeris dažnai naudojamas: Norint užtikrinti skaidrų vaizdų (view) modifikavimą, kurio negalima atlikti tiesiai per SQL DML sakinius, nes view negali būti modifikuojamas. Galima rašyti INSERT, UPDATE ar DELETE sakinius view’ui . INSTEAD OF trigeris veikla nematoma, atliekami veiksmai apibrėžti trigerio kūne tiesiai ant view’ą sudarančių lentelių. INSTEAD OF trigeris yra alternatyvus būdas modifikuojant rodinius, kurių neįmanoma modifikuoti tiesiogiai per UPDATE, INSERT ir DELETE sakinius. Šie trigeriai nustato, kuri operacija buvo numatyta ir tiesiogiai vykdo UPDATE, INSERT ir DELETE operacijas į pažymėtas lenteles. INSTEAD OF trigeriai gali būti aktyvuoti tik atskirai kiekvienai eilutei.
10
DML trigerio komponentai
Trigerį kviečianti vartotojo įvykis: kuris DML sakinys iškviečia trigerį? Galima naudoti: INSERT UPDATE DELETE Kai trigerį iškviečiantis įvykis yra UPDATE sakinys, galima nurodyti stulpelių sąrašą, kuriems keičiantis bus kviečiamas trigeris. Negalima nurodyti stulpelio sąrašo INSERT ir DELETE sakiniuose, nes jie visuomet veikia visą eilutę. ....UPDATE OF salary... 2. Trigerį kviečiantis įvykis gali būti sudarytas iš 1, 2 ar 3 DML operacijų: ... INSERT or UPDATE or DELETE ....INSERY or UPDATE OF job_id...
11
DML trigerio komponentai
Trigerio tipas: ar trigerio kūnas t.b. vykdomas kiekvienai eilutei, kurią paveikia sakinys, ar tik 1 kartą? STATEMENT: Trigerio kūnas vykdomas tik 1 kartą trigerį sukėlusiam įvykiui. Šis tipas yra parenkamas pagal nutylėjimą. STATEMENT trigeris suveikia tik 1 kartą, net jei nė viena eilutė nerą paveikta. ROW: Trigerio kūnas vykdomas vieną kartą kiekvienai trigerį sukėlusio įvykio paveiktai eilutei. ROW trigeris nevykdomas jei jį sukėlęs įvykis nepaveikia nė vienos eilutės. STATEMENT trigeris: Toks trigeris naudingas, kai trigerio veiksmai nepriklauso nuo paveiktų eilučių duomenų ar nuo duomenų gaunamų iš trigerį sukėlusio veiksmo: pvz.: trigeris, kuris atlieka sudėtingą dabartinio vartotojo saugumo tikrinimą. ROW trigeris: Toks trigeris naudingas, kai trigerio veiksmai priklauso nuo paveiktų eilučių duomenų ar nuo duomenų gaunamų iš pačio, trigerį sukėlusio, veiksmo.
12
DML trigerio komponentai
Trigerio kūnas: kokį veiksmą trigeris turi atlikti? Trigerio kūnas yra PL/SQL blokas ar procedūros kvietimas. PL/SQL blokas gali būti sudarytas iš SQL ar PL/SQL sakinių ir gali apibrėžti konstrukcijas: kintamuosius, kurosrius, išimtis ir t.t. Iš trigerio kūno galima kviesti PL/SQL ar Java procedūrą. Papildomai, ROW trigeriai naudoja atitinkamus vardus kreipiantis į senas ir naujas stulpelio reikšmes, kurios yra su trigeriu apdorojamos.
13
Trigerių apribojimai Trigerio dydis negali viršyti 32K bitų
Trigerio kūnas gali susidėti iš SQL DML sakinių, tačiau privalo būti SELECT... INTO... sakiniai Trigerio kūne neleidžiama rašyti DDL sakinių Negalima naudoti ROLLBACK, COMMIT ir SAVEPOINT Sisteminiams trigeriams {CREATE/ALTER/DROP} TABLE sakiniai ir ALTER...COMPILE yra leidžiami
14
Veikimo tvarka Lentelės trigerių, kai keičiama viena eilutė, vykdymo seka: DML sakinys INSERT INTO deparments (department_id, department_name, location_id) VALUES (400, ‘CONSULTING’, 2400) Įterpiama 1 eilutė. Trigerį iškviečiantis veiksmas department_id department_name location_id ...... BEFORE STATEMENT trigeris Sukuriamas sakinio (STATEMENT) ar eilutės (ROW) trigeris, priklausomai ar jis turi šauti 1 kartą kiekvienai trigerį iškvietusio įvykio paveiktai eliutei, ar turi šauti vieną kartą visems iškvietusiems jį sakiniams, neatsižvelgiant į paveiktų eilučių skaičių. Kai trigerį kviečiantis DML sakinys paveikia tik 1 eilutę, abu, STATEMENT (sakinio) ir ROW (eilutės) trigeriai, yra vykdomi tik vieną kartą. Pavyzdyje SQL sakinys neskiria sakinio ir eilučių trigerių, nes tik viena eilutė įterpiama į lentelę. BEFORE ROW trigeris AFTER ROW trigeris AFTER STATEMENT trigeris
15
Veikimo tvarka Lentelės trigerių, kai keičiamos kelios eilutės,vykdymo seka: DML sakinys UPDATE employees SET salary=salary*1.1 WHERE department_id=30; Pakeičiamos 6 eilutės. Trigerį iškviečiantis veiksmas department_id department_name location_id …………….. BEFORE STATEMENT trigeris BEFORE ROW trigeris AFTER ROW trigeris Kai trgerį kviečaintis DML sakinys paveikia keletą eilučių, STATEMENT (sakinio) trigeris suveikia tik vieną kartą, o eilutės trigeris suveikia vieną kartą kiekvienai sakinio pakeistais eilutei. Pavyzdyje SQL sakinys iškviečia eilutės lygio trigerį vykdymui tiek kartų kiek eilučių, atitinkančių WHERE sąlygą, t.y. darbuotojų skaičius atitinkantis departamentą 30. BEFORE ROW trigeris AFTER ROW trigeris AFTER STATEMENT trigeris
16
DML STATEMENT trigerių kūrimo sintaksė
CREATE [OR REPLACE] TRIGGER trigger_name timing event1 [OR event2 OR event3] ON table_name trigger_body Pastaba: trigerio vardai t.b. schemos viduje uninkalūs Trigger_name – trigerio vardas. Timing – kada trigeris šaus (BEFORE, AFTER). Event – DML operacija, kuri sukelia trigerį (INSERT, UPDATE [OF column], DELETE). Table/view_name – nustato su trigeriu susijusią lentelę. Trigger body – trigerio kūnas, kuriame aprašytas trigerio atliekamas veiksmas. Pradedamas su DECLARE arba BEGIN, pabaigiamas su END. Trigerio vardas t.b. unikalus tarp trigerių schemos viduje, t.y. Gali būti toks kaip lentelės ar kt. Schemos objekto vardas. Naudojant trigeryje stulpelių vardus su UPDATE sakiniu, pagerinamas programos vykdymas, nes trigeris iškviečiamas tik kai keičiamas tam tikras stulpelis ir neveikia, kai keičiami kt. stulpeliai.
17
Pvz. Lentelei Emp_tab sukuriamas trigeris:
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; / Trigeris aktyvuojamas, kai lentelėje atliekamos DML operacijos (INSERT, UPDATE ir DELETE sakiniai). Šiame pavyzdyje naudojamas BEFORE raktas, kuriuo trigeris kviečiamas prieš atnaujinant duomenis. Jei įvesti duomenys klaidingi, tai jie dar gali būti taisytini. BEFORE raktą būtų galima pakeisti į AFTER. Tuomet trigeris bus aktyvuojamas po duomenų atnaujinimo. Pavyzdžiui, trigeris gali užtikrinti, kad kai tik pasikeis vienos lentelės kurios nors eilutės atributo reikšmė, visuomet tas pakeitimas atsispindės ir kitoje lentelėje. Pavyzdyje yra naudojama FOR EACH ROW išlyga. Su ja trigeris bus kviečiamas kiekvienai atnaujinamai eilutei. Kuomet trigeris sukurtas, įvedame SQL sakinį: UPDATE Emp_tab SET sal = sal WHERE deptno = 10; Trigeris aktyvuosis kiekvienoje eilutėje, kuri yra atnaujinama ir kiekvieną kartą atspausdins naują, ankstesnę algą ir jų skirtumą.
18
Dar vienas DB trigerio pavyzdys
CREATE OR REPLACE TRIGGER secure_emp BEFORE INSERT ON employees BEGIN IF (TO_CHAR (SYSDATE,’DY’) IN (‘SAT’)) THEN RAISE_APPLICATION_ERROR (-20500, ‘You may insert into EMPLOYEES table only during business hours.’); END IF; END; / Galima sukurti BEFORE STATEMENT trigerį, kad uždrausti trigerį sukelusio įvykio vykdymą, kai pažeidžiama tam tikra sąlyga. Pavyzdyje sukuriamas trigersi ,kuris neleidžia keisti EMPLOYEES lentelės savaitgalį, vartotojui išmetamas atitinkamas pranešimas. Atminkite, kad RAISE_APPLICATION_ERROR yra serverio pusės procedūra, kuri grąžina vartotojui klaidą ir sukelia PL/SQL bloko žlugimą (fail). Kai DB trigeris žlunga, trigerį sukėlęs sakinys automatiškai atšaukiamas (rolled back) Oracle serveryje. Testavimo metu matyti, kad neleidžiama įterpti naujos eilutės į EMPLOYEES lentelę nedarbo dienomis. Testavimas INSERT INTO employees (employee_id, last_name, first_name, , hire_date, job_id, salary, department_id) VALUES (300,’Smith’, ‘Rob’, ‘RSMITH’, SYSDATE, ’IT_PROG’, 4500, 60); ERROr at line 1. ORA You may insert into EMPLOYEES table onnlyduring business hours ORA at PLSQL.SEQURE_EMP ORA error during execution trigger PLSQL.SECURE_EMP
19
Sąlyginių predikatų naudojimas
CREATE OR REPLACE TRIGGER secure_emp BEFORE INSERT OR UPDATE OR DELETE ON employees BEGIN IF (TO_CHAR (SYSDATE,’DY’) IN (‘SAT’)) THEN IF DELETING THEN RAISE_APPLICATION_EROR (-20502,’You may delete from EMPLOYEES table only during business hours.’); IF INSERTNG THEN RAISE_APPLICATION_EROR (-20500,’You may insert into EMPLOYEES table only during business hours.’); IF UPDATING (‘SALARY’) THEN RAISE_APPLICATION_EROR (-20503,’You may update SALARY only during business hours.’); ELSE RAISE_APPLICATION_EROR (-20504, ’You may update EMPLOYEES table only during normal hours.’);\ END IF; END; Galima sujungti keletą trigerį iššaukiančių įvykių, naudojant predikatus INSERTING, UPDATINT IR DELETING trigerio kūne. Pavyzdyje sukurtas trigeris neleidžia atlikti DML sakinių ant EMPLOYEES lentelės tam tikromis valandomis.
20
DML ROW trigerio kūrimas
CREATE [OR REPLACE] TRIGGER trigger_name timing event1 [or event2 OR event3] ON table_name [REFERENCING OLD AS old / NEW AS new] FOR EACH ROW [WHEN (condition)] trigger_body Trigger_name – trigerio vardas. Timing – kada trigeris šaus (BEFORE, AFTER). Event – DML operacija, kuri sukelia trigerį (INSERT, UPDATE [OF column], DELETE). Table_name – nustato su trigeriu susijusią lentelę. REFERENCING – nustato atitinkamus vardus senoms ir naujoms reikšmėms dabartinės eilutės (Pagal nutylėjimą reikšmės OLD ir NEW). FOR EACH ROW – nustato, kad trigeris yra eilutės trigeris. Trigger body – trigerio kūnas, kuriame aprašytas trigerio atliekamas veiksmas. Pradedamas su DECLARE arba BEGIN, pabaigiamas su END. Trigerio vardas t.b. unikalus tarp trigerių schemos viduje, t.y. Gali būti toks kaip lentelės ar kt. Schemos objekto vardas. Naudojant trigeryje stulpelių vardus su UPDATE sakiniu, pagerinamas programos vykdymas, nes trigeris iškviečiamas tik kai keičiamas tam tikras stulpelis ir neveikia, kai keičiami kt. stulpeliai.
21
DML ROW trigerio kūrimo pavyzdys
CREATE [OR REPLACE] TRIGGER restrict_salary BEFORE INSERT OR UPDATE OF salary ON employees FOR EACH ROW BEGIN IF NOT (:NEW.job_id IN (‘AD_PRES’,’AD_VP’)) AND :NEW.salary>15000 THEN RAISE_APPLICATION_ERROR (-20202, ‘Employee cannot earn this amount.’); END IF; END; / Galima sukurti BEFORE ROW trigerį, kuris uždraus atlikti jį iššaukiančias operacijas, jei pažeista tam tikra sąlyga. Pavyzdyje sukuriamas trigeris, kuris leidžia tik tam tikriems darbuotojams uždirbti daugiau nei Testavimas UPDATE employees SET salary=15000 WHERE last_name=‘Russell’; UPDATE EMPLOYEES * ERROR at line1: ORA EMPLOYEE cannot earn this amount ORA at PLSQL.RESTRICT_SALARY ORA error during execution trigger PLSQL.RESTRICT_SALARY
22
OLD ir NEW charakteristikos
PL/SQL kodas ir SQL sakiniai gali prieiti prie senų (old) ir naujų (new) stulpelio tam tikros eilutės reikšmių. Old ir New egzistuoja kiekviename modifikuojame stulpelyje: pirmasis skirtas senai stulpelio reikšmei saugoti, antrasis – naujai. Trigerio sakinių būna įvairių tipų, todėl pasitaiko, kad tie koreliacijos vardai gali ir visai jokių reikšmių neturėti.
23
Trigerių priėjimo būdai prie OLD ir NEW charakteristikų
Trigeris, iškviestas INSERT sakiniu, turi prasmingą priėjimą tik prie naujų stulpelio reikšmių. Kadangi su INSERT sukurtos eilutės sena reikšmė yra lygi NULL Trigeris, iškviestas UPDATE sakiniu, turi priėjimą prie abiejų stulpelio reikšmių Senos ir naujos reikšmės pasiekiamos BEFORE ir AFTER eilės trigeriais. Nauja stulpelio reikšmė gali būti paskirta tik BEFORE eilės trigeriu. Naujos stulpelio reikšmės yra pažymimos naudojant naują žymę (new qualifier) prieš stulpelio vardą, kol senos stulpelio reikšmės pažymėtos sena žyme (old qualifier) prieš stulpelio vardą. Pavyzdžiui, skleidžiamas sakinys yra susietas su Emp_tab lentele ( su stulpeliais SAL, COMM ir t.t.), tuomet galima įterpti sakinį į trigerio kūną, pvz.: IF :new.Sal > IF :new.Sal < :old.Sal ...
24
OLD ir NEW naudojimo pavyzdys
CREATE OR REPLACE TRIGGER audit_emp_values AFTER DELETE OR INSERT OR UPDATE ON employees FOR EACH ROW BEGIN INSERT INTO audit_emp_table (user_name, timestamp, id, old_last_name,new_last_name, old_title, new_title, old_salary, new_salary) VALUES (USER, SUSDATE, :OLD.employee_id, :OLD.last_name, :NEW.last_name, :OLD.job_id, :NEW.job_id, :OLD.salary, :NEW.salary); END; / ROW trigeryje galima kreiptis į stulpelio reikšmę prieš ir po duomenų keitimo su priešdėliais OLD ir NEW. OLD ir NEW galima naudoti tik ROW trigeriuose. Šie priešdėliai rašomi kartu su dvitataškiu (:). Nereikia rašyti dvitaškio (:) prieš priešdėlius WHEN ribojančioje sąlygoje. Pastaba: ROW trigeriai sumažina vykdymo efektyvumą, jei atliekama daug duomenų keitimų ant didelių lentelių.
25
OLD ir NEW žymėjimai: pvz. su AUDIT_EMP_TABLE lentele
INSERT INTO employees (employee_id, last_name, job_id, salary,...) VALUES (999, ‘Temp emp’, ‘SA_REP’, 1000,…); UPDATE employees SET salary =2000, last_name=‘Smith’ WHERE employee_id=999; 1 row updated 1 row inserted SELECT user_name, timestamp,…FROM audit_emp_table User_name timestamp old_last_name new_last_name … PLSQL 28-SEP-01 Temp emp… PLSQL 28-SEP-01 Temp emp Smith…. Sukuriamas trigeris ant EMPLOYEES lentelės, kuris kuria įrašus vartotojo lentelėje AUDIT_EMP_TABLE . Trigeris įrašo keletos stulpelių senas ir naujas reikšmes, t.y. Prieš ir po pakeitimo, naudojant priešdėlius OLD ir NEW su atitinkamu stulpelio vardu.
26
ROW trigerio apribojimas
CREATE OR REPLACE TRIGGER derive_commision_pct BEFORE INSERT OR UPDATE OF salary ON employees FOR EACH ROW WHEN (NEW.job_id=‘SA_REP’)---nereikia dvitaškio (:) BEGIN IF INSERTING THEN :NEW.commission_pct:=0; ELSIF :OLD. commission_pct IS NULL THEN ELSE :NEW.commission_pct:=:OLD.commission_pct; END IF; END; / Norint apriboti trigerio veikimą eilutėms, kurios atitinka sąlygą įvedamas WHEN sakinys. Sukuriamas trigeris ant EMPLOYEES lentelės, kuris suskaičiuoja darbuotojo komisinius, kai eulutė pridedama į EMPLOYEES lentelę, arba kai keičiama darbuotojo alga. WHEN dalyje prieš priešdėlį NEW dvitaškis (:) nepridedamas, nes WHEN dalis yra PL/SQL bloko išorėje.
27
INSTEAD OF trigeris Aplikacija INSERT INTO my_view ...; INSERT TABLE1
INSTEAD OF trigeriai naudojami duomenų keitimui vaizduose (view), kuriuose bendru tveju to atlikti negalima. Jie vadinami INSTEAD OF trigeriais, nes Oracle serveris vykdo šį trigerį vietoj trigerį iškvietusio veiksmo. Naudojamas INSERT, UPDATE, DELETE operacijų atlikimui tiesiai ant view’ą sudarančių lentų. Galima rašyti INSERT, UPDATE, DELETE sakinius ant view’o, o INSTEAD OF trigeris veiks fone, nematomai ir atliks reikiamus veiksmus. Naudojimas. View’as negali būti keičiamas paprastais DML sakiniais, jei view’o užklausa sudaryta iš aibės operatorių (UNION, MINUS, INTERSECT), grupavimo operatorių (GROUP BY, CONNECT BY, START), DISTINCT operatorių arba sujungimų (joins). Pvz. View’as sudarytas iš kelių lentelių, terpimas į view’ą gali sukelti įterpimą į vieną lentelę ir duomenų keitimą kitoje lentelėje. Taigi rašomas INSTEAD OF trigeris, kuris veikia terpiant duomenis į view’ą. Vietoj normalaus teprimo, vykdomas trigerio kūnas, kurio rezultatas duomenų terpimas į vieną lentelę ir duomenų keitimas kt. Lentelėje. CHECK opcija view’e nevykdoma kai terpimai ar keitimai ant view’o atliekami su INSTEAD OF trigeriais. INSTEAD OF trigeris turi atlikti duomenų tikrinimą. My_view UPDATE TABLE2
28
INSTEAD OF TRIGERIO kūrimas
CREATE [OR REPLACE] TRIGGER trigger_name INSTEAD OF event1 [or event2 OR event3] ON table_name [REFERENCING OLD AS old / NEW AS new] FOR EACH ROW trigger_body Trigger_name – trigerio vardas. INSTEAD OF – nurodo, kad trigeris priklauso view’ui. Event – DML operacija, kuri sukelia trigerį (INSERT, UPDATE [OF column], DELETE). view_name – nustato su trigeriu susijusią lentelę. REFERENCING – nustato atitinkamus vardus senoms ir naujoms reikšmėms dabartinės eilutės (Pagal nutylėjimą reikšmės OLD ir NEW). FOR EACH ROW – nustato, kad trigeris yra eilutės trigeris. Trigger body – trigerio kūnas, kuriame aprašytas trigerio atliekamas veiksmas. Pradedamas su DECLARE arba BEGIN, pabaigiamas su END. INSTEAD OF trigeris g.b. Parašytas tik ant view’o. BEFORE ir AFTER opcijos negalimos.
29
Skirtumai tarp D.B. trigerių ir saugomų procedūrų
Trigeriai Procedūros Apibrėžiami su CREATE TRIGGER Apibrėžiamos su CREATE PROCEDURE Kodas saugomas duomenų žodyno Kodas saugomas duomenų žodyno view’e USER_TRIGERS view’e USER_SOURCE Kviečiamas neatvirai Kviečiamas atvirai COMMIT, SAVEPOINT, COMMIT, SAVEPOINT, ROLLBACK ROLLBACK Neleidžiami leidžiami (galima atlikti kviečiant procedūrą, Tačiau nerekomenduojama dėl Pašalinų efektų) Trigeriai sukompiliuojami įvykdžius CREATE TRIGGER komandą. P kodas išsaugomas duomenų žodyne. Jei kompiliavimo metu aptinkamos klaidos, trigeris sukuriamas ir tuo atveju.
30
Skirtumai tarp D.B. trigerių ir Form Builder trigerių
INSERT INTO employees ...; EMPLOYEES lentelė CHECK_SAL trigeris EMPLOYEE_ID LAST_NAME JOB_ID Skirtumai: Duomenų bazės trigeris Formų trigeris Sukelia bet koks D.B. Vykdomas tik konkrečioje aplikacijoje įrankis ar aplikacijos Visuomet sukeliamas SQL DML, Gali būti sukeltas navigacijos iš vieno lauko DDL ar tam tikro D.B. Veiksmo į kitą metu, atlikus klaivišo paspaudimą ir pan. Skiriami į STATEMENT (sakinio) Skiriami STATEMENT ir ROW trigeriai Ir ROW (eilutės) trigerius Žlugus veikimui, sukeliamas Žlugus trigeriui sukelia trigerio sustingimą rollback (freeze) ir visos tranzakcijos atšaukimą (rollback). Veikia nepriklausomai nuo ir Veikia nepriklausomai nuo ir bendrai su Form Builder bendrai su Form Builder trigeriais trigeriais Veikia trigerio kūrėjo teisėmis Veikia Form Builder vartotojo teisėmis BEFORE INSERT ROW
31
Trigerių valdymas D.B. trigerių išjungimas ir pakartotinas įjungimas: ALTER TRIGGER trigger_name DISABLE | ENABLE Visų lentelės trigerių išjungimas ir pakartotinas įjungimas: ALTER TABLE table_name DISABLE | ENABLE ALL TRIGGERS Lentelės trigerio perkompiliavimas: ALTER TRIGGER trigger_name COMPILE Trigerio šalinimas DROP TRIGGER triger_name; Pvz.: DROP TRIGGER secure_emp; Pastaba: visi trigeriai ištrinami, ištrynus lentelę. Trigerio būsenos: ENABLE ir DISABLE Kai trigeris pirmą kartą sukuriamas, jis įjungiamas automatiškai. Sukurtiems trigeriams Oracle serveris tikrina duomenų vientisumo apribojimus (constraint) ir užtikrina, kad trigeris jiems neprieštarauja. Trigeris išjungiamas su ALTER TRIGGER sakiniu, visi trigeriai išjungiami su ALTER TABLE sakiniu. Trigeris išjungiamas norint pagerint vykdymą (performance) arba išvengti duomenų vientisumo tikrinimo kraunant didelius duomenų kiekius su SQL*Loader. Taip pat trigeriai išjungiami kai jie kreipiasi į šiuo metu neegzistuojantį D.B. Objektą. Trigerio kompiliavimas ALTER TRIGGER komanda naudojama norint atvirai perkompiliuoti trigerį. Parašius ALTER TRIGGER sakinį su COMPILE opcija, trigeris perkompiliuojamas neatsivelgiant ar jis galioja (valid) ar ne (invalid). Trigerio šalinimas Kai trigeris nebereikalingas, naudojamas SQL sakinys DROP trigerio pašalinimui.
32
Trigerio testavimas Reikia patikrinti kiekvieną duomenų operaciją, kuri iškviečia trigerį. Reikia patikrinti kiekvieną WHEN dalį. Reikia patikrinti trigerio veikimą tiesiogiai ant lentos ir netiesiogiai iš procedūros. Reikia patikrinti trigerio poveikį kt. Trigeriams. Reikia patikrinti kt. trigerių poveikį trigeriui. Pastaba: trigeris netiesiogiai gali iškviesti kt. trigerius. Reikia užtikrinti, kad kiekvienu atveju trigeris veikia teisingai. Naudojantis DBMS_OUTPUT.PUT_LINE procedūra trigerių derinimui. Galima naudoti Procedure Builder įrankį trigerių derinimui.
33
Trigerio vykdymo modelis ir apribojimų (constraint) tikrinimas
Įvykdykite visus BEFORE STATEMENT trigerius. Kiekvienai paveiktai eilutei: Įvykdykite visus BEFORE ROW trigerius. Įvykdykite visus AFTER ROW trigerius. Įvykdykite visus DML sakinius ir įvykdykite visus duomenų vientisumo apribojimų (constraint) tikrinimus. Apribojimai tikrinami po ROW lygio trigerių, ne prieš. Pvz. Keisti departamento nr. kai jame yra darbuotojai galima jei trigeriuose pakeisim dep. nr. Vsiems darbuotojams Įvykdykite visus AFTER STATEMENT trigerius. Vienas DML sakinys gali sukelti 4 trigerių tipus: BEFORE ir AFTER STATEMENT ROW trigeriai. Jei trigerį iššaukiantis įvykis ar sakinys yra trigerio viduje, jis gali sukelti vieno ar daugiau vientisumo apribojimų (constraint) tikrinimą. Trigeriai gali iškviesti kitus trigerius (cascading triggers). Visi veiksmai ir tikrinimai, atliekami kaip SQL sakinio rezultatas, turi būti sėkmingi. Jei trigeryje iškyla išimtis ir ji nėra tiesiogiai (explicitly) apdorojama, SQL sakinio, iškvietusio trigerį , veiksmai yra atšaukiami (rollback), atšaukiami ir pačiame trigeryje vykdyti SQL sakiniai. Tokiu būdu užtikrinama, kad vientisumo apribojimai niekada nebus pažeisti. (Su trigeriais negalima pažeisti vientisumo apribojimų). Kai trigeris šauna, lentelės naudojamos trigerio kūne gali būti keičiamos kt. Vartotojų transakcijų. Tačiau visuomet garantuojamas duomenų vaizdas iki comitt ‘o (read-consistent view).
34
Trigerio veikimo modelis ir apribojimų tikrinimas: pvz.
UPDATE employees SET department_id=999 WHERE employee_id=170; --duomenų vientisumo apribojimo pažeidimas CREATE OR REPLACE TRIGGER constr_emp_trig AFTER UPDATE ON employees FOR EACH ROW BEGIN INSERT INTO departments VALUES (999, ‘dept999’, 140, 2400); END; / WHERE employee_id=170; --sėkmingas po trigerio suveikimo Trigerio vykdymo modelis ir apribojimų tikrinimo pavyzdys: Pavyzdyje aprašyta situacija, kurioje galima apsirūpinti duomenų vientisumo apribojimais naudojant trigerį. Lentelė EMPLOYEES turi išorinių raktų apribojimus ant DEPARTMENT_ID stulpelio DEPARMENTS lentelėje. Pirmame SQL sakinyje, darbuotojo turinčio EMPLOYEE_ID=170 departamentas pakeičiamas į DEPARTMENT_ID=999. Kadangi tokio departamento DEPARTMENTS lentelėje nėra, sakinys sukelia išimtį –2292 apie vientisumo apribojimo pažeidimą. Sukuriamas trigeris CONSTR_EMP_TRIG, kuris įterpia naują departamentą 999 į DEPARTMENTS lentelę. Kai UPDATE sakinys, kuris keičia 170 darbuotojo departamentą į 999, vykdomas, šauna trigeris. Tuomet tikrinamas išorinio rakto apribojimas. Kadangi trigeris įterpė naują 999 departamentą į DEPARTMENTS lentelę, tai išorinio rakto apribojimo tikrinimas įvykdomas sėkimingai i r nesukeliama jokia išimtis. Šis modelis veikia nuo 8 Oracle serverio versijos.
35
Santrauka Procedūra Paketas Trigeris Procedūros A deklaracija
Procedūros B apibrėžimas Konstrukcija Procedūra Naudojimas PL/SQL programinis blokas, saugomas D.B. Pakartotinam vykdymui. Konstrukcija Paketas Naudojimas Grupė susijusių procedūrų , funkcijų, kintamūjų, konstantų ir išimčių. Konstrukcija Trigeris Naudojimas PL/SQL programinis blokas, vykdomas netiesiogiai DML sakiniu. Procedūros A apibrėžimas Lokalus kintamasis
36
Sisteminiai įvykiai Trigeriai aktyvuojasi įvykus tam tikrai operacijai: DML sakiniai (DELETE, INSERT, UPDATE) DDL sakiniai (CREATE, ALTER, DROP) Duomenų bazės operacijos (SERVERERROR, LOGON, LOGOFF, STARTUP, SHUTDOWN) Kuriant trigerį duomenų bazėje, jis vykdomas už vartotojo ribų ir yra taikytinas visiems tos bazės vartotojams (pvz. STARTUP ir SHUTDOWN operacijos). O trigeris, sukurtas schemoje, užkrautoje tam tikro vartotojo, veiks tik to vartotojo aplinkoje.
37
Pvz. Trigeris, naudojantis LogOff
CREATE OR REPLACE TRIGGER On_Logoff AFTER LOGOFF ON The_user.Schema BEGIN if (ora_sysevent = 'ASSOCIATE STATISTICS') then number_of_modified_objects := ora_dict_obj_owner_list(owner_list); end if; END; Trigeris aktyvuojamas po vartotojo išsijungimo iš duomenų bazės. Atsijungus į vartotojo schemą įrašomi seanso metu vykdytos operacijos.
38
1.Pvz. Trigeris su parinktimis
CREATE OR REPLACE TRIGGER Log_salary_increase AFTER UPDATE ON Emp_tab FOR EACH ROW WHEN (new.Sal > 1000) BEGIN INSERT INTO Emp_log (Emp_id, Log_date, New_salary, Action) VALUES (:new.Empno, SYSDATE, :new.SAL, 'NEW SAL'); END; Įvedame SQL sakinį: UPDATE Emp_tab SET Sal = Sal WHERE Deptno = 20; Jei yra 5 darbuotojai departamente Nr.20, tuomet trigeris aktyvuosis 5 kartus, kai šis sakinys bus įvestas, kadangi penkios eilutės atitinka sąlygą.
39
2.Pvz. Trigeris su parinktimis
CREATE OR REPLACE TRIGGER Log_emp_update AFTER UPDATE ON Emp_tab BEGIN INSERT INTO Emp_log (Log_date, Action) VALUES (SYSDATE, 'Emp_tab COMMISSIONS CHANGED'); END; Šiame pavyzdyje trigeris aktyvuosis tik vieną kartą su UPDATE parinktimi Emp_tab lentelėje.
40
Trigerio kūnas Trigerio kūnas yra CALL procedūra ar PL/SQL blokas, susidedantis iš vieno ar kelių SQL ir PL/SQL sakinių, kuriuos reikia vykdyti iškvietus trigerį Trigerio kūno vykdymo sąlyga: iškviesto kūno sakinius vykdyti besąlygiškai ar tik tuomet, kai patenkinta konkreti sąlyga CALL procedūra gali būti PL/SQL ar Java procedūra, inkapsuliuota į PL/SQL aplanką. Įsidėmėtina, kad eilučių šalinimas, keitimas ar naujų eilučių įterpimas negali būti naudojamas CALL procedūrose, jis vykdomas tik PL/SQL bloke.
41
Pvz. Trigerio kūnas CREATE OR REPLACE PROCEDURE foo (c VARCHAR2) AS BEGIN INSERT INTO Audit_table (user_at) VALUES(c); END; CREATE OR REPLACE TRIGGER logontrig AFTER LOGON ON DATABASE CALL foo (ora_login_user) / Pavyzdyje kviečiama procedūra, o vykdoma funkcija ORA_LOGIN_USER grąžina informaciją apie įvykį, iškvietusį trigerį.
42
Trigerių apribojimas mutuojančiose lentelėse
Mutuojanti lentelė – tai lentelė, kuri tuo metu yra modifikuojama UPDATE, DELETE ar INSERT sakiniais ar lentele, galinčia atnaujinti apribojimu DELETE CASCADE. Apribojimas taikomas tiems trigeriams, kurie naudoja FOR EACH ROW išlygą ir trigerio sakinį, kurio rezultatas yra DELETE CASCADE. Tuo metu, kai vykdomas trigerio sakinys, neleidžiama užklausti ar modifikuoti mutuojančios lentelės. Šis apribojimas apsaugo trigerį nuo nesuderinamų duomenų “matymo”. Kuomet trigeris aptinka mutuojančią lentelę, įvyksta vykdymo klaida, sakinio vykdymas nutraukiamas, valdymas grąžinamas vartotojui ar aplikacijai.
43
Pvz. Mutuojanti lentelė
CREATE OR REPLACE TRIGGER Emp_count AFTER DELETE ON Emp_tab FOR EACH ROW DECLARE n INTEGER; BEGIN SELECT COUNT(*) INTO n FROM Emp_tab; DBMS_OUTPUT.PUT_LINE(' There are now ' || n || ' employees.'); END; SQL sakinys: DELETE FROM Emp_tab WHERE Empno = 7499; Pranešimas: ORA-04091: table SCOTT.Emp_tab is mutating, trigger/function may not see it Įvesime SQL sakinį. Gausime pranešimą apie klaidą, kadangi ištrynus eilutę lentelė mutavo.
44
Trigerių galimybės Trigeriai gali būti naudojami ir kitų tiesiogiai nedalyvaujančių operacijoje lentelių modifikavimui, priklausomai nuo atliekamos operacijos pagrindinėje lentelėje Tai iliustruosime pavyzdžiu.
45
Pvz. Kitų lentelių modifikavimas trigeriu
CREATE TRIGGER ModifikuotiNr AFTER UPDATE OF Nr ON Tiekėjai REFERENCINGOLD AS OldTiek NEW AS NewTiek FOR EACH ROW MODE DB2SQL UPDATE Tiekimai SET Tiekimai.TiekNr = NewTiek.Nr WHERE TiekNr = OldTiek.Nr; END; Sukuriamas trigeris, kuris užtikrins, kad kai tik pasikeis lentelės Tiekėjai kurios nors eilutės atributo Nr reikšmė, visuomet tas pakeitimas atsispindės ir lentelėje Tiekimai, t.y. pakeitus kurio nors tiekėjo numerį lentelėje Tiekėjai jis bus pakeistas ir lentelėje Tiekimai. Panaudojant frazę REFERECING, trigerio kūne galima operuoti tiek senąja reikšme (pažymėta vardu OldTiek), tiek naująja (NewTiek).
46
Trigerių privalumai Pagrindinis trigerių privalumas - jais apibrėžtos dalykinės taisyklės saugomos duomenų bazėje pagreitina programavimą palengvina dalykinių taisyklių užtikrinimą yra globalūs pagreitina programavimą - jie įsimenami duomenų bazėje ir veiksmų nereikia kartoti kiekvienoje programoje; palengvina dalykinių taisyklių užtikrinimą apibrėžtas trigeris visuomet iškviečiamas reikiamu momentu; yra globalūs - pasikeitus dalykinėms taisyklėms, tereikia pakeisti trigerį viename egzemplioriuje, o ne visas programas, kuriose yra taisyklių užtikrinimo sakiniai.
47
Trigerių trūkumai DB sudėtingumas Paslėpta logika
Paslėpta įtaka našumui DB sudėtingumas. Trigeriams tapus DB dalimi, ši tampa daug sudėtingesne. Kai duomenų bazėje yra daug trigerių, tai netgi paprastos taikomosios programos sukūrimas gali būti sudėtingu uždaviniu dėl sudėtingos trigerių veiksmų logikos. Paslėpta logika. Kai dalykinės taisyklės yra "paslėptos" duomenų bazėje, paprasti duomenų atnaujinimo veiksmai, gali iššaukti sudėtingą duomenų analizę. Taikomosios programos kūrėjas neturi galimybės tvarkyti visus vykstančius duomenų bazėje procesus, kadangi veiksmai gali iššaukti kitus, paslėptus veiksmus. Paslėpta įtaka našumui. Kai bazėje yra trigerių, duomenų atnaujinimas nėra skaidrus. Paprastas reikšmės atnaujinimas gali iššaukti daugelio duomenų apdorojimą, kuriam reikės daug laiko. Gali būti sunku suvokti, kodėl duomenų atnaujinimas vyksta taip lėtai.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.