Kivételek kezelése Oracle PL/SQL (példák)
⚡ Okos összefoglaló
Kivételkezelés Oracle A PL/SQL rögzíti a futásidejű hibákat, amelyek megakadályozzák egy blokk végrehajtását, lehetővé téve a motor számára, hogy a vezérlést egy EXCEPTION szakaszba vigye át, ahol az előre definiált, a felhasználó által definiált és OTHERS kezelők biztonságosan válaszolnak, hibát generálnak vagy terjesztenek.

Mi az a kivételkezelés a PL/SQL-ben?
Kivétel történik, amikor a PL/SQL motor olyan utasítást talál, amelyet futási időben felmerülő hiba miatt nem tud végrehajtani. Ezeket a hibákat a rendszer nem észleli fordítási időben, ezért csak futási időben kell kezelni őket.
Például, ha a PL/SQL motor egy utasítást kap egy szám nullával való osztására, akkor kivételként hibát jelez. A kivételt a PL/SQL motor csak futásidőben generálja.
Egy kivétel megakadályozza a program további végrehajtását, ezért az ilyen helyzet elkerülése érdekében a hibát külön kell rögzíteni és kezelni. Ezt a folyamatot kivételkezelésnek nevezik, amelynek során a programozó kezeli a futásidőben előforduló hibát.
Kivételkezelési szintaxis
A kivételek kezelése blokkszinten történik. Amint egy kivétel történik egy blokkban, a vezérlés elhagyja a blokk végrehajtási részét, és a kivétel kezelése a blokk kivételkezelő részében történik. A kivétel kezelése után a vezérlés nem térhet vissza ugyanazon blokk végrehajtási szakaszába.
Az alábbi ábra azt mutatja, hogyan helyezkedik el a végrehajtási szakasz és a kivételkezelési szakasz egyetlen PL/SQL blokkon belül:
Az alábbi szintaxis elmagyarázza, hogyan lehet kivételeket elkapni és kezelni.
BEGIN <execution block> . . EXCEPTION WHEN <exceptionl_name> THEN <Exception handling code for the “exception 1 _name’' > WHEN OTHERS THEN <Default exception handling code for all exceptions > END;
Szintaxis magyarázata:
- A fenti szintaxisban a kivételkezelő blokk egy sor WHEN feltételt tartalmaz a kivételek kezelésére.
- Minden WHEN feltételt egy kivétel neve követ, amelynek futási időben kell bekövetkeznie.
- Amikor futásidőben kivétel keletkezik, a PL/SQL motor a kivételkezelő részben keresi az adott kivételt, az első WHEN záradéktól kezdve, és szekvenciálisan haladva.
- Ha talál egy kezelőt a felmerült kivételhez, akkor végrehajtja az adott kezelő kódot.
- Ha egyetlen WHEN záradék sem felel meg a felmerült kivételnek, a PL/SQL motor végrehajtja a WHEN OTHERS részt, ha van ilyen. Ez a kezelő minden kivételre közös.
- A kezelő lefutása után a vezérlés elhagyja az aktuális blokkot.
- Futásidőben egy blokkhoz csak egy kivételkezelő hajtható végre. A futás után a motor kihagyja a fennmaradó kezelőket, és kilép az aktuális blokkból.
Jegyzet: A WHEN OTHERS függvényt mindig a szekvenciában utoljára kell helyezni. A WHEN OTHERS után írt kezelők soha nem futnak le, mivel a vezérlés a WHEN OTHERS végrehajtása után kilép a blokkból.
A kivételek típusai
Kétféle kivétel létezik a PL / SQL.
- Előre definiált kivételek
- Felhasználó által definiált kivételek
Előre meghatározott kivételek
Oracle előre definiált néhány gyakori kivételt. Minden előre definiált kivétel egyedi névvel és hibaszámmal rendelkezik, és mindegyik deklarálva van a STANDARD csomagban a OracleKódban ezeket az előre definiált kivételneveket közvetlenül használhatod a megfelelő hibák kezelésére. Sokuk közvetlenül a gyakori hibákra vonatkozik. SQL hibák, amikkel nap mint nap találkozol.
Az alábbiakban néhány előre definiált kivételt láthat:
| kivétel | hiba Code | Kivétel oka |
|---|---|---|
| ACCESS_INTO_NULL | ORA-06530 | Érték hozzárendelése egy nem inicializált objektum attribútumaihoz |
| CASE_NOT_FOUND | ORA-06592 | A CASE utasításban egyik WHEN záradék sem teljesül, és nincs megadva ELSE záradék. |
| COLLECTION_IS_NULL | ORA-06531 | Gyűjtési metódusok használata (az EXISTS kivételével) vagy gyűjteményattribútumok elérése egy nem inicializált gyűjteményen |
| CURSOR_ALREADY_OPEN | ORA-06511 | Megpróbálja megnyitni a kurzor ami már nyitva van |
| DUP_VAL_ON_INDEX | ORA-00001 | Ismétlődő érték tárolása egy egyedi index által korlátozott adatbázisoszlopban |
| INVALID_CURSOR | ORA-01001 | Érvénytelen kurzorműveletek, például egy megnyitatlan kurzor bezárása |
| ÉRVÉNYTELEN SZÁM | ORA-01722 | Egy karakter számmá alakítása sikertelen volt érvénytelen numerikus karakter miatt. |
| NEM TALÁLHATÓ ADAT | ORA-01403 | Egy INTO záradékot tartalmazó SELECT utasítás nem ad vissza sorokat. |
| ROW_MISMATCH | ORA-06504 | A kurzorváltozó adattípusa nem kompatibilis a tényleges kurzor visszatérési típusával. |
| SUBSCRIPT_BEYOND_COUNT | ORA-06533 | Egy gyűjteményre való hivatkozás egy olyan indexszámmal, amely nagyobb, mint a gyűjtemény mérete |
| SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | Gyűjteményre való hivatkozás a megengedett tartományon kívül eső indexszámmal (például -1) |
| TOO_MANY_ROWS | ORA-01422 | Egy INTO záradékkal ellátott SELECT utasítás egynél több sort ad vissza |
| VALUE_ERROR | ORA-06502 | Számtani vagy méretkorlátozási hiba (például a változó méreténél nagyobb érték hozzárendelése) |
| ZERO_DIVIDE | ORA-01476 | Szám osztása nullával |
Felhasználó által meghatározott kivétel
A fenti előre definiált kivételeken kívül a programozó létrehozhat egyéni kivételeket és kezelheti azokat. Ezek az alprogram szintjén jönnek létre a deklarációs részben, és csak az adott alprogramon belül láthatók. A csomagspecifikációban definiált kivétel nyilvános kivétel, és bárhol látható, ahol a csomag elérhető.
Szintaxis: Alprogram szinten
DECLARE <exception_name> EXCEPTION; BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> END;
- A fenti szintaxisban az „exception_name” változó EXCEPTION típusként van definiálva.
- Ezután ugyanúgy használható, mint egy előre definiált kivétel.
Szintaxis: Csomagspecifikáció szintjén
CREATE PACKAGE <package_name> IS <exception_name> EXCEPTION; . . END <package_name>;
- A fenti szintaxisban az „exception_name” változó EXCEPTION típusként van definiálva a következő csomag specifikációjában: .
- Az adatbázisban bárhol használható, ahol a 'package_name' csomag meghívható.
PL/SQL emelés kivétel
Minden előre definiált kivétel implicit módon keletkezik, amikor a megfelelő hiba előfordul. A felhasználó által definiált kivételeket azonban explicit módon kell létrehozni a RAISE kulcsszó használatával. A RAISE kulcsszó az alább látható módon használható.
Ha a RAISE metódust önmagában használjuk egy kezelőn belül, akkor a már felmerült kivételt továbbküldi a szülő blokknak. Csak egy kivételblokkon belül használható, ahogy az alább látható.
Az alábbi képernyőképen a RAISE önmagában történő használata látható egy kivétel újbóli kiváltására a befoglaló blokkban:
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> RAISE; END;
Szintaxis magyarázata:
- A fenti szintaxisban a RAISE kulcsszó a kivételkezelő blokkon belül szerepel.
- Amikor a program a(z) „kivétel_neve” kivétellel találkozik, a kivétel kezelése és futása normál módon fejeződik be.
- A kezelőben található RAISE kulcsszó ezután ugyanazt a kivételt továbbítja a szülőprogramnak.
Jegyzet: Amikor kivételt generálunk a szülőblokkra, a kiváltott kivételnek a szülőblokkban is láthatónak kell lennie; egyébként Oracle hibát dob.
Használhatod a RAISE kulcsszót, majd egy kivétel nevét az adott felhasználó által definiált vagy előre definiált kivétel előidézéséhez. Ez az űrlap mind a végrehajtási, mind a kivételkezelési részben használható.
Az alábbi képernyőképen a RAISE (RÁZÁS) parancsot egy kivételnév követi, amely egy adott kivételt generál.
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> RAISE <exception_name> EXCEPTION WHEN <exception_name> THEN <Handler> END;
Szintaxis magyarázata:
- A fenti szintaxisban a RAISE kulcsszót a végrehajtási részben használjuk, amelyet a „kivétel_neve” kivétel követ.
- Ez futásidőben előidézi az adott kivételt, amit aztán tovább kell kezelni vagy kiváltani.
Példa 1: Ebben a példában a következőket fogjuk látni:
- Hogyan deklaráljunk kivételt
- Hogyan lehet felidézni a deklarált kivételt?
- Hogyan terjesztjük a főblokkba
Az alábbi képernyőkép a teljes blokkot mutatja, amely deklarálja a sample_exception kivételt, egy beágyazott blokkon belül aktiválja azt, és továbbadja a fő blokknak:
A következő képernyőképen ugyanaz a példa folytatódik, ahol a fő blokk végül rögzíti a továbbadott kivételt:
DECLARE Sample_exception EXCEPTION; PROCEDURE nested_block IS BEGIN Dbms_output.put_line('Inside nested block'); Dbms_output.put_line('Raising sample_exception from nested block'); RAISE sample_exception; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line ('Exception captured in nested block. Raising to main block'); RAISE; END; BEGIN Dbms_output.put_line('Inside main block'); Dbms_output.put_line('Calling nested block'); Nested_block; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line ('Exception captured in main block'); END; /
Code Magyarázat:
- Code 2. sor: A „sample_exception” változó deklarálása EXCEPTION típusként.
- Code 3. sor: A nested_block eljárás deklarálása.
- Code 6. sor: A „Beágyazott blokkon belül” utasítás kinyomtatása.
- Code 7. sor: A „sample_exception generálása beágyazott blokkból” utasítás kinyomtatása.
- Code 8. sor: A kivétel emelése a 'RAISE sample_exception' használatával.
- Code 10. sor: Kivételkezelő a beágyazott blokkban található sample_exception kivételhez.
- Code 11. sor: A „Kivételt rögzítettek a beágyazott blokkban. Feliratkozás a fő blokkra” utasítás kinyomtatása.
- Code 12. sor: A kivétel felvetése a fő blokkra (terjesztése).
- Code 15. sor: A „Fő blokkon belül” utasítás kinyomtatása.
- Code 16. sor: A „Beágyazott blokk hívása” utasítás kinyomtatása.
- Code 17. sor: A nested_block eljárás meghívása.
- Code 19. sor: A minta_exception kivételkezelője a fő blokkban.
- Code 20. sor: A „Kivételt rögzítettek a fő blokkban” utasítás kinyomtatása.
Fontos tudnivalók a Kivételnél
- Egy függvényben egy kivételnek mindig vagy értéket kell visszaadnia, vagy tovább kell emelnie a kivétel hatókörét; egyébként Oracle futásidőben „A függvény érték nélkül tért vissza” hibát dob.
- Tranzakcióvezérlő utasítások a kivételkezelő blokkon belül adható ki.
- Az SQLERRM és az SQLCODE beépített függvények, amelyek rendre a kivételüzenetet, illetve a kivételkódot adják vissza.
- Ha egy kivételt nem kezel a rendszer, akkor alapértelmezés szerint az adott munkamenetben lévő összes aktív tranzakció visszavonásra kerül.
- RAISE_APPLICATION_ERROR (-) , ) használható a RAISE helyett egyéni kóddal és üzenettel ellátott hibaüzenet esetén. A hibakódnak -20000 és -20999 között kell lennie.





