Előadást letölteni
Az előadás letöltése folymat van. Kérjük, várjon
1
Adatbázisok 8. előadás Tikk Domonkos
2
Mai menü Tárolt rutinok Triggerek
3
Tárolt rutinok
4
Tárolt rutin szerepe A szerveren tárolódik és hajtódik végre
Újrafelhasználható Gyorsan végrehajtódik, mivel a szerveren fut Két típus: normál alprogram (PL/SQL nyelven) Adatbázis-objektumként tárol alprogram (nagyon hasonló szintaktika)
5
Alprogram (PL/SQL)
6
Eljárás létrehozása PROCEDURE procedúranév [paraméterek] IS
lokális változók deklarációja BEGIN végrehajtandó utasítások [EXCEPTION kivételkezelés;] END [procedúranév];
7
Függvény létrehozása FUNCTION függvénynév [paraméterek] RETURN adattípus IS lokális változók deklarációja BEGIN végrehajtandó utasítások [EXCEPTION kivételkezelés]; END [függvénynév];
8
Paraméterek paraméternév [IN | OUT | IN OUT] adattípus [{:=| DEFAULT}]
nem adható meg NOT NULL kényszer a paraméterre nem adható meg kényszer az adattípusra (azon_szam IN NUMBER(4)) -- szintaktikai hiba (azon_szam IN NUMBER) -- helyes
9
Tárolt rutin hívása procedúranév(paraméterek);
FUNCTION esetén kifejezésben visszatérési érték helyettesítődik be változónév = függvénynév(paraméterek);
10
Procedúrák törzse
11
Törzs szintaktikája Deklarációs szegmens Végrehajtási szegmens
Kivételkezelő szegmens
12
Példa PROCEDURE dolgozo_kilep(dnum NUMBER) IS BEGIN DELETE FROM EMP
WHERE empno = dnum; END; dolgozo_kilep(7758); dnum: formális paraméter 7758: aktuális paraméter
13
SQL utasítás az alprogramban
SELECT oszlopnevek INTO változónevek FROM táblanév [WHERE feltétel]; pontosan 1 sort kell visszaadniuk! ugyanannyi oszlopnak és változónak kell lenni
14
Vezérlési szerkezetek utasításokban
Szekvencia Szelekció Iteráció
15
Szelekció (elágazás) IF … THEN … END IF; IF … THEN … ELSE … END IF;
IF … THEN … [ELSIF … THEN …] ELSE … END IF; feltételek és utasítás párosok ELSIF-ek száma nincs korlátozva
16
Példa PROCEDURE szam_jegy(a INTEGER) IS b VARCHAR2(40); BEGIN IF a > 999 THEN b := 'a szám négyjegyű vagy nagyobb'; ELSIF a > 500 THEN b:= ' félezernél több'; ELSIF (a > 99) AND (a < 499) THEN b:= 'háromjegyű, de kisebb mint félezer' ; ELSIF a > 9 THEN b:= 'a szám kétjegyű' ; ELSE b:= 'a szám egyjegyű'; END IF; ... END;
17
Iteráció – LOOP ciklus LOOP ciklusmag [EXIT;] [EXIT WHEN feltétel;] END LOOP;
18
Példa LOOP ciklusra CREATE TABLE rendel (rendelszám NUMBER(4), sorszám NUMBER(2), kód VARCHAR2(6)) PROCEDURE feltölt (v_rszám IN NUMBER); v_sorszám NUMBER(2); BEGIN v_sorszám :=1; LOOP INSERT INTO rendel (rendelszám, sorszám) VALUES (v_rszám, v_sorszám); v_sorszám := v_sorszám +1; EXIT WHEN v_sorszám > 5; -- kilépési feltétel END LOOP; END;
19
Iteráció – FOR ciklus FOR ciklusváltozó IN [REVERSE] alsó_határ felső_határ LOOP utasítás; [utasítás;] END LOOP;
20
FOR ciklus elemei ciklusváltozó: REVERSE: a ciklus irányát módosítja
kezdetben felveszi az alsó (normál) vagy a felső (REVERSE) határt, majd értéke automatikusan nő (normál) vagy csökken (REVERSE) amíg a felső (normál), vagy alsó (REVERSE) határt el nem éri REVERSE: a ciklus irányát módosítja alsó_határ: a ciklusváltozó legkisebb értéke felső_határ: a ciklusváltozó legnagyobb értéke
21
Példa FOR ciklusra CREATE TABLE proba (szam NUMBER(3) ); PROCEDURE feltölt_próba IS BEGIN FOR ind IN Ciklusváltozó szám LOOP INSERT INTO proba (szam) VALUES (ind); END LOOP; END;
22
Példa FOR ciklusra (2) PROCEDURE feltölt_próba (also_hatar NUMBER, felso_hatar NUMBER) IS BEGIN FOR ind IN also_hatar .. felso_hatar LOOP INSERT INTO proba (szam) VALUES (ind*2); END LOOP; END;
23
Iteráció – WHILE ciklus
WHILE feltétel LOOP utasítás; [utasítás;] END LOOP; addig hajtódik végre, amíg a feltétel igaz
24
Példa WHILE ciklusra PROCEDURE beszúr(g_rendelszam NUMBER, g_darab NUMBER) IS sorszam NUMBER(2):= 1; BEGIN WHILE sorszam <= g_darab LOOP INSERT INTO rendel (rendelszám, sorszám) VALUES (g_rendelszam, sorszam); sorszam := sorszam + 1; END LOOP; END; beszúr(123, 5); as rendelészámra 5 tételt beszúr
25
Paramétertípusok
26
Paramétertípusok: IN IN: csak bemenő paraméter, a tárolt eljárás nem változtathatja meg az értékét konstans kifejezés értékkel rendelkező változó
27
Példa IN helytelen használatára
PROCEDURE tartoz_szamla(szlasz IN INTEGER, menny IN INTEGER) IS min_emeles CONSTANT REAL; szolgaltatas CONSTANT REAL; BEGIN … IF menny<min_emeles THEN menny:=menny+szolgaltatas; -- szintaktikai hiba END IF END
28
Példa alapértelmezett mezőkre
PROCEDURE new_dept (new_dname CHAR DEFAULT ’MARKETING’, new_loc CHAR DEFAULT ’SAN FRANCISCO’) AS BEGIN INSERT INTO dept VALUES(50, new_dname, new_loc); … END; new_dept(); new_dept(’LOGISTIC’); new_dept(’LOGISTIC’,’DENVER’);
29
Paramétertípusok: OUT
OUT: kimenő változó csak értéket kaphat (utasítás bal oldalán szerepelhet) értéket nem adhat másnak híváskor csak változóval lehet meghívni, kifejezéssel nem
30
Példa OUT helytelen használatára
PROCEDURE jut_szam(azon IN INTEGER, jutalek OUT REAL) IS belepes DATE; BEGIN SELECT sal*0.1, hiredate INTO jutalek, belepes FROM emp WHERE empno=azon; IF MONTH_BETWEEN(sysdate, belepes)>60 THEN jutalek:=jutalek+5000; -- szintaktikai hiba END IF; END jut_szam(111, fiz+előleg); -- szintaktikai hiba
31
Paramétertípusok: IN OUT
IN OUT: híváskor átadja a bemenő paraméter értékét, és visszatéréskor a megváltoztatott értékkel tér vissza PROCEDURE jut_szam(azon IN INTEGER, jutalek IN OUT REAL) IS belepes DATE; BEGIN SELECT sal*0.1, hiredate INTO jutalek, belepes FROM emp WHERE empno=azon; IF MONTH_BETWEEN(sysdate,belepes)>60 THEN jutalek:=jutalek+5000; END IF; END
32
Paramétertípusok: összefoglalás
IN OUT IN OUT alapértelmezett nem kötelező kiírni kötelező kiírni átadja az értékét az alprogramnak értékkel tér vissza a hívóhoz értéket ad át, és a megváltoztatottal tér vissza viselkedés: konstans viselkedés: inicializálatlan változó viselkedés: inicializált változó alprogramban nem kaphat értéket alprogramban értéket kell kapnia, de az ott nem használható fel felhasználható korábbi értéke, és értéket is kaphat aktuális paraméterként: konstans, inicializált változó, vagy kifejezés aktuális paraméterként: csak változó
33
Adatbázisban tárolt alprogam
34
Különbségek Létrehozás: más szintaktika Lokális változók deklarálása
IS helyett AS CREATE kulcsszó használata Lokális változók deklarálása
35
Tárolt rutin létrehozása
CREATE PROCEDURE procedúranév AS (paraméternév [IN|OUT|IN OUT] paramétertípus) procedúra törzse CREATE FUNCTION függvénynév AS RETURNS visszatérésiérték-típus
36
Triggerek
37
Trigger – definíció A trigger olyan tevékenységet definiál, amely automatikusan végbemegy, ha egy tábla vagy nézet módosul egyéb felhasználói vagy, rendszeresemények következnek be. Adatbázis-objektum Megírható PL/SQL, Java vagy C nyelven Működése a felhasználó számára átlátszó módon történik
38
Kiváltó események egy táblán vagy nézeten végrehajtott INSERT, DELETE vagy UPDATE utasítás egyes DDL utasítások (CREATE, ALTER, DROP) szerverhibák felhasználói be- és kijelentkezés adatbázis elindítása és leállítása
39
Mire jók a triggerek származtatott oszlopértékek generálása
érvénytelen tranzakciók megelőzése védelem hivatkozási integritási megszorítások definiálása komplex üzleti szabályok kezelése eseménynaplózás követés táblastatisztikák gyűjtése adattöbbszörözés
40
Triggerek típusai Sor szintű trigger Utasítás szintű trigger
BEFORE és AFTER trigger INSTEAD OF trigger Rendszertrigger
41
Sor szintű trigger Egy sor szintű trigger mindannyiszor lefut, ahányszor a tábla adatai módosulnak. Például egy DELETE utasítás esetén minden törölt sor újból aktiválja a triggert. Ha egyetlen sor sem módosul, a trigger egyszer sem fut le.
42
Utasítás szintű trigger
Az utasítás szintű trigger egyszer fut le, függetlenül a kezelt sorok számától. Ez a trigger akkor is lefut, ha egyetlen sort sem kezeltünk.
43
BEFORE és AFTER triggerek
Egyaránt lehetnek sor és utasítás szintűek Csak táblához kapcsoltan hozhatók létre, nézetre nem DDL (CREATE, ALTER, DROP) utasításhoz kapcsolt trigger is létrehozható, de csak adatbázison és sémán, táblán nem. A BEFORE trigger azelőtt fut le, mielőtt a hozzákapcsolt utasítás lefutna. Az AFTER trigger a hozzákapcsolt utasítás lefutása után fut le.
44
INSTEAD OF trigger Ez a triggerfajta a hozzákapcsolt utasítás helyett fut le Csak sor szintű lehet és csak nézeteken definiálható Akkor használjuk, ha egy nézetet módosítani akarunk, de azt nem tehetjük meg közvetlenül DML utasítások segítségével
45
Rendszertriggerek A triggerek felhasználhatók arra is, hogy adatbázis- eseményekről információkat adjunk az „előfizetőknek”. Az alkalmazások feliratkozhatnak az adatbázis- események, illetve más alkalmazások üzeneteinek előfizetői listájára, és akkor ezeket automatikusan megkapják. rendszeresemények (AB elindítása, leállítása, szerverhiba) felhasználói események (be- és kijelentkezés, DML/DDL utasítások)
46
Trigger létrehozása: szintaktika
CREATE [OR REPLACE] TRIGGER [séma.]triggernév idő esemény ON {DATABASE|[séma].SCHEMA} [WHEN (feltétel)] utasítás idő: BEFORE | AFTER | INSTEAD OF esemény: DDL-esemény: adatbázishoz vagy sémához AB-esemény: adatbázishoz vagy sémához DML-TRIGGER: {INSERT |DELETE | UPDATE OF [oszlop, {…}] … ON [séma].tábla | [séma].nézet } [REFERENCING {OLD [AS] régi | NEW [AS] új | PARENT [AS] szülő} … [FOR EACH ROW]
47
DML-esemény INSERT, DELETE, UPDATE – az SQL-utasítás, aminek hatására a trigger lefut UPDATE OF oszlop(ok) – csak az adott oszlop frissítésére fut le ON: tábla/séma – az AB-objektum, amin a triggert létrehozzuk REFERENCING – itt adjuk meg, hogyan hivatkozunk a módosítás előtti (OLD), utáni (NEW) sorokat jelenti, beágyazott tábla esetén a szülő (PARENT) FOR EACH ROW – előírja, hogy sorszintű trigger legyen (ez csak a INSTEAD OF-nál alapértelmezés, különben utasításszintű)
48
DDL-trigger Kiváltó: AB v. séma-esemény
(ON {DATABASE|[séma].SCHEMA} például: ALTER, CREATE, DROP, GRANT, RENAME, REVOKE, TRUNCATE
49
AB-esemény Kiváltó esemény, valamilyen adatbázissal kapcsolatos esemény SERVERERROR: egy szerverhiba bekövetkezte aktiválja a triggert. LOGON: egy kliensalkalmazás bejelentkezik az adatbázisba. LOGOFF: egy kliensalkalmazás kilép az adatbázisból. STARTUP: az adatbázis megnyitásra kerül. SHUTDOWN: az adatbázis leállításra kerül. SUSPEND: szerverhiba miatt egy tranzakció működése felfüggesztődik.
50
Példákhoz felhasznált táblák
CREATE TABLE Konyv ( id NUMBER, ISBN VARCHAR2(30) NOT NULL, … Keszlet NUMBER NOT NULL, Szabad NUMBER NOT NULL, CONSTRAINT konyv_pk PRIMARY KEY (id), CONSTRAINT konyv_szabad CHECK (Szabad >= 0)) CREATE TABLE Ugyfel ( Nev VARCHAR2(100) NOT NULL, Max_konyv NUMBER DEFAULT 10, CONSTRAINT ugyfel_pk PRIMARY KEY (id) ) CREATE TABLE Kolcsonzes ( Kolcsonzo NUMBER NOT NULL, Konyv NUMBER NOT NULL, Datum DATE NOT NULL, … CONSTRAINT kolcsonzes_fk1 FOREIGN KEY (Kolcsonzo) REFERENCES Ugyfel(Id), CONSTRAINT kolcsonzes_fk2 FOREIGN KEY (Konyv) REFERENCES Konyv(Id) ) CREATE TABLE Kolcsonzes_naplo ( Konyv_isbn VARCHAR2(30) NOT NULL, Konyv_cim VARCHAR2(100) NOT NULL, Ugyfel_nev VARCHAR2(100) NOT NULL, Elvitte DATE NOT NULL, Visszahozta DATE NOT NULL
51
Példa CREATE OR REPLACE TRIGGER tr_insert_kolcsonzes AFTER INSERT ON kolcsonzes FOR EACH ROW DECLARE v_Ugyfel ugyfel%ROWTYPE; BEGIN SELECT * INTO v_Ugyfel FROM ugyfel WHERE id = :NEW.kolcsonzo; IF v_Ugyfel.max_konyv = v_Ugyfel.konyvek.COUNT THEN RAISE_APPLICATION_ERROR(-20010, v_Ugyfel.nev || ' ügyfél nem kölcsönözhet több könyvet.'); END IF; INSERT INTO TABLE (SELECT konyvek FROM ugyfel WHERE id = :NEW.kolcsonzo) VALUES (:NEW.konyv, :NEW.datum); UPDATE konyv SET szabad = szabad -1 WHERE id = :NEW.konyv; EXCEPTION WHEN OTHERS THEN RAISE_APPLICATION_ERROR(-20020, 'Nincs a könyvből több példány.'); END; END tr_insert_kolcsonzes; A trigger segítségével a kölcsönzés adminisztrácója automatizálható. Egyetlen sor beszúrása a kolcsonzes táblába maga után vonja az ugyfel és a konyv táblák megfelelő bejegyzéseinek változtatását. A trigger sor szintű. Ha nem lehet a kölcsönzést végrehajtani, kivételt dobunk.
52
Példa (2) CREATE OR REPLACE TRIGGER tr_kolcsonzes_naploz AFTER DELETE ON kolcsonzes REFERENCING OLD AS kolcsonzes FOR EACH ROW DECLARE v_Konyv konyv%ROWTYPE; v_Ugyfel ugyfel%ROWTYPE; BEGIN SELECT * INTO v_Ugyfel FROM ugyfel WHERE id = :kolcsonzes.kolcsonzo; SELECT * INTO v_Konyv FROM konyv WHERE id = :kolcsonzes.konyv; INSERT INTO kolcsonzes_naplo VALUES( v_Konyv.ISBN, v_Konyv.cim, v_Ugyfel.nev, v_Ugyfel.anyja_neve, :kolcsonzes.datum, SYSDATE, :kolcsonzes.megjegyzes); END tr_kolcsonzes_naploz; A trigger segítségével naplózzuk a törölt kölcsönzéseket a kolcsonzes_naplo táblában.
53
Példa (3) CREATE OR REPLACE TRIGGER tr_kolcsonzes_hosszabbit BEFORE INSERT OR UPDATE ON kolcsonzes FOR EACH ROW WHEN (NEW.hosszabbitva > 2 OR NEW.hosszabbitva < 0) BEGIN RAISE_APPLICATION_ERROR( , 'Nem megengedett a hosszabbítások száma'); END tr_kolcsonzes_hosszabbit; WHEN-ben nem kell kettőspont a placeholderek elé (OLD, NEW, PARENT) mindez megvalósítható egy CHECK vagy ASSERTION utasítással is
54
Példa (4) CREATE OR REPLACE TRIGGER tr_kolcsonzes_naplo_del_upd BEFORE DELETE OR UPDATE ON kolcsonzes_naplo BEGIN RAISE_APPLICATION_ERROR( , 'Nem megengedett művelet a kolcsonzes_naplo táblán'); END tr_kolcsonzes_naplo_del_upd; Megakadályozzuk, hogy a kolcsonzes_naplo fájlból töröljön valaki Utasítás szintű trigger, nincs FOR EACH ROW
55
Példa (5) CREATE TABLE szam_tabla(a NUMBER); CREATE OR REPLACE TRIGGER tr_duplaz BEFORE INSERT ON szam_tabla FOR EACH ROW BEGIN :NEW.a := :NEW.a * 2; END tr_duplaz; INSERT INTO szam_tabla VALUES(5); SELECT * FROM szam_tabla; Beszúrás előtt megduplázzuk a beszúrt értéket :NEW pszeudóváltozónak értéket is lehet adni
56
Példa (6) CREATE OR REPLACE TRIGGER tr_konyv_id BEFORE UPDATE OF id ON konyv FOR EACH ROW BEGIN -- Módosítjuk a kolcsonzes táblát UPDATE kolcsonzes SET konyv = :NEW.id WHERE konyv = :OLD.id; END tr_konyv_id; Az integritási megszorítás kikényszerítése: a kolcsonzes-ben konyv idegen kulcs Ezért a konyv azonosítójának módosítása előtt frissítjük a kolcsonzes-ben is az értékét
57
Példa (7) CREATE OR REPLACE TRIGGER tr_ugyfel_konyv_mod INSTEAD OF UPDATE ON ugyfel_konyv FOR EACH ROW BEGIN IF :NEW.ugyfel <> :OLD.ugyfel THEN UPDATE ugyfel SET nev = :NEW.ugyfel WHERE id = :OLD.ugyfel_id; END IF; IF :NEW.konyv <> :OLD.konyv THEN UPDATE konyv SET cim = :NEW.konyv WHERE id = :OLD.konyv_id; END tr_ugyfel_konyv_mod; Ügyfél nevét vagy könyv címét módosítjuk az ugyfel_konyv nézettáblán keresztül CREATE OR REPLACE VIEW client_book AS SELECT clients.id AS client_id, clients.name AS client, book.id AS book_id, book.title AS book FROM borrow,book,clients WHERE borrow.book=book.id AND clients.id=borrow.client;
58
Trigger törlése DROP TRIGGER táblanév.triggernév További információk a triggerekről az érdeklődőknek amozas/book.xml.html#id493442
Hasonló előadás
© 2024 SlidePlayer.hu Inc.
All rights reserved.