Adatbázis-kezelés (PL/SQL) Kivételkezelés Adatbázis-kezelés (PL/SQL)
Jelölések Az SQL, PL/SQL utasítások, nevek stb. (terminálisok) nagybetűvel szerepelnek, pl.: SELECT. A nemterminálisok kisbetűvel, pl.: eredmeny. Az alternatívákat függőleges vonal választja el egymástól ( | ). Az opcionális elemek szögletes zárójelben állnak ( [ ] ), pl.: [NOT NULL]. A kötelezően megadandó alternatívákat kapcsos zárójelek fogják közre ( { } ), pl.: {kifejezes | feltetel}. Az iteráció jelölésére három pont szolgál (...), pl.: utasitas [utasitas]...
Alapok A kivételek rendszere a PL/SQL-ben a futás közben bekövetkező események (hibák) kezelését teszi lehetővé. A kivételek lehetnek beépítettek, amelyeket általában a rendszer vált ki, illetve felhasználói kivételek. A beépített kivételeknek lehet nevük, a felhasználói kivételeknek mindig van nevük. Egy kivételhez a PL/SQL-ben egy kód és egy üzenet tartozik. A beépített kivételek kódja negatív szám, a felhasználói kivételeké pozitív. A beépített kivételeket a STANDARD csomag definiálja. A kivételek kezelésére kivételkezelőt építhetünk be a programunkba.
Fontosabb beépített kivételek CASE_NOT_FOUND -6592 CURSOR_ALREADY_OPEN -6511 INVALID_CURSOR -1001 INVALID_NUMBER -1722 (pl. ha egy sztring konverziója sikertelen) NO_DATA_FOUND 100 (SELECT INTO utasítás nem adott vissza sort) ROWTYPE_MISMATCH -6504 TOO_MANY_ROWS -1422 (pl. SELECT INTO utasítás túl sok sort adott vissza) VALUE_ERROR -6502 (pl. ha egy változó a lehetségesnél nagyobb értéket kap) ZERO_DIVIDE -1476
Utasítások I. Felhasználói kivételeket az EXCEPTION alapszóval deklarálhatunk: DECLARE magan_kivetel EXCEPTION; Egy olyan beépített kivételhez, melynek nincs neve, egy pragma segítségével magunk rendelhetünk hozzá nevet. Az utasítás alakja: PRAGMA EXCEPTION_INIT (kivetel_nev, kod); Bármely kivétel kiváltható a következő utasítással: RAISE kivetel_nev; Megjegyzés: az utasítás bárhol elhelyezhető, ahol utasítás szerepelhet.
Utasítások II. Kivételkezelő bármely programegység végén az EXCEPTION alapszó után helyezhető el. Felépítése: WHEN kivetel_nev [OR kivetelnev]... THEN utasitas [utasitas]... [WHEN kivetel_nev [OR kivetelnev]... THEN utasitas [utasitas]...] [WHEN OTHERS THEN utasitas [utasitas]...] Megjegyzés: ha egy programrészben kivétel váltódik ki, az adott programegység kivételkezelője kapja meg a vezérlést, s a fenti programrészbe nem térhetünk vissza. Ha a kivétel itt nem kerül kezelésre, továbbadódik. Ha kivételkezelőben váltódik ki kivétel, szintén továbbadódik.
Példa DECLARE a NUMBER NOT NULL:=1; b NUMBER; BEGIN a := b; EXCEPTION WHEN VALUE_ERROR THEN DBMS_OUTPUT.PUT_LINE ('Hoppa!!'); END; Megjegyzés: a hiba azért keletkezett, mert b-t nem inicializáltuk, s így az értéke NULL maradt. Lásd még a 2. példát a Kivetel_pelda.html fájlban!
RAISE, SQLCODE, SQLERRM A kivételkezelőben a bekövetkezett kivétel újra kiváltható, hogy azt majd egy külső programegység kivételkezelője dolgozza fel ismét. Erre szolgál a RAISE utasítás „üres” alakja: RAISE; Az SQLCODE beépített függvény a bekövetkezett hiba kódját, az SQLERRM pedig a hozzárendelt üzenetet adja vissza. A függvények nem csak a kivételkezelőben használhatók. Az SQLERRM meghívható paraméterrel is, a paraméternek egy kivétel kódjának kell lennie. Ekkor a függvény az adott kivételhez rendelt üzenetet adja vissza.
RAISE_APPLICATION_ERROR A STANDARD csomag tartalmaz egy RAISE_APPLICATION_ERROR eljárást három paraméterrel: az első egy kivétel kód -20000 és -20999 között; a második egy maximum 2048 bájt hosszúságú sztring (hibaüzenet); a harmadik opcionális paraméter: TRUE érték esetén (ez az alapértelmezés) a hibaveremben az első paraméter által megadott kód felülírja a legutolsónak bekövetkezett kivétel kódját, FALSE esetén pedig kiürül a hibaverem és csak a most megadott kód kerül bele. Lásd 3. példa a Kivetel_pelda.html fájlban! A példához a függvények ismerete szükséges lehet (lásd: Alprog.ppt bemutató), bár valószínűleg enélkül is érthető.
Feladat Írassuk ki azt a legnagyobb faktoriálist, ami még túlcsordulás nélkül kiszámítható. Mi a keletkező kivétel kódja és mi a kivételhez tartozó üzenet? Írjunk olyan kurzort, amelynek paramétere egy természetes szám n és egy dátum, s azon ügyfelek nevét és azonosítóját adja vissza, akik végrehajtottak egy n összegű tranzakciót az adott napon. Hívjuk meg ezt a kurzort különböző értékekkel. Ha nem hajtottak végre olyan összegű tranzakciót az adott napon, akkor adjon hibaüzenetet. Különben írassuk ki az ügyfelek nevét, azonosítóját és a dátumot.