Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

Adatbázisok 8. előadás Tikk Domonkos.

Hasonló előadás


Az előadások a következő témára: "Adatbázisok 8. előadás Tikk Domonkos."— Előadás másolata:

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


Letölteni ppt "Adatbázisok 8. előadás Tikk Domonkos."

Hasonló előadás


Google Hirdetések