Erandi käsitlemine Oracle PL/SQL (näited)
⚡ Nutikas kokkuvõte
Erandi käsitlemine Oracle PL/SQL jäädvustab käitusaja vigu, mis peatavad ploki täitmise, võimaldades mootoril juhtimise üle anda EXCEPTION sektsioonile, kus eelnevalt määratletud, kasutaja määratletud ja OTHERS käitlejad vastavad, tekitavad või levitavad vigu ohutult.

Mis on erandite käsitlemine PL/SQL-is?
Erand tekib siis, kui PL/SQL-mootor kohtab käsku, mida ta ei saa käitusajal tekkinud vea tõttu täita. Neid vigu kompileerimise ajal ei tuvastata ja seetõttu tuleb neid käsitleda ainult käitusajal.
Näiteks kui PL/SQL-mootor saab käsu jagada arv nulliga, tekitab see vea erandina. Erandi tekitab PL/SQL-mootor ainult käitusajal.
Erand peatab programmi edasise täitmise, seega sellise tingimuse vältimiseks tuleb viga jäädvustada ja eraldi käsitleda. Seda protsessi nimetatakse erandite käsitlemiseks, mille käigus programmeerija käsitleb viga, mis võib käitusajal ilmneda.
Erandi käsitlemise süntaks
Erandeid käsitletakse ploki tasandil. Kui plokis tekib erand, lahkub juhtimine selle ploki täitmisosast ja erandit käsitletakse seejärel ploki erandite käsitlemise osas. Pärast erandi käsitlemist ei saa juhtimine enam sama ploki täitmisosasse naasta.
Allolev joonis näitab, kuidas teostusosa ja erandite käsitlemise osa paiknevad ühes PL/SQL-plokis:
Allolev süntaks selgitab, kuidas erandit püüda ja käsitleda.
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;
Süntaksi selgitus:
- Ülaltoodud süntaksis sisaldab erandite käsitlemise plokk rida WHEN-tingimusi erandite käsitlemiseks.
- Igale WHEN tingimusele järgneb erandi nimi, mis peaks käitusajal tekkima.
- Kui käitusajal tekib erand, otsib PL/SQL-mootor erandite käsitlemise osast seda konkreetset erandit, alustades esimesest WHEN-klauslist ja liikudes järjestikku edasi.
- Kui see leiab tekitatud erandi jaoks käitleja, käivitab see selle konkreetse käitleja koodi.
- Kui ükski WHEN-klausel ei vasta tekkinud erandile, käivitab PL/SQL-mootor WHEN OTHERS osa, kui see on olemas. See käitleja on kõigi erandite puhul ühine.
- Pärast käitleja käivitamist lahkub juhtimine praegusest plokist.
- Käitusajal saab ploki jaoks käivitada ainult ühe erandikäsitleja. Pärast selle käivitamist jätab mootor ülejäänud käsitlejad vahele ja lahkub praegusest plokist.
Märge: WHEN OTHERS peaks alati olema järjestuses viimasena. Ükski pärast WHEN OTHERS kirjutatud käitleja ei käivitu kunagi, sest juhtimine väljub plokist pärast WHEN OTHERS käivitamist.
Erandi tüübid
Erandeid on kahte tüüpi PL / SQL.
- Eelmääratletud erandid
- Kasutaja määratletud erandid
Eelmääratletud erandid
Oracle on eelnevalt defineerinud mõned levinud erandid. Igal eelnevalt defineeritud erandil on unikaalne nimi ja veanumber ning need kõik on deklareeritud STANDARD-paketis OracleKoodis saate neid eelnevalt määratletud erandite nimesid otse kasutada vastavate vigade käsitlemiseks. Paljud neist on otseselt seotud tavaliste vigadega. SQL vead, millega iga päev kokku puutud.
Allpool on toodud mõned eelnevalt määratletud erandid:
| Erand | viga Code | Erandi põhjus |
|---|---|---|
| ACCESS_INTO_NULL | ORA-06530 | Initsialiseerimata objekti atribuutidele väärtuse määramine |
| CASE_NOT_FOUND | ORA-06592 | Ükski CASE-lause WHEN-klauslitest pole täidetud ja ELSE-klauslit pole täpsustatud. |
| COLLECTION_IS_NULL | ORA-06531 | Kogumismeetodite (välja arvatud EXISTS) kasutamine või kogumisatribuutidele juurdepääs initsialiseerimata kogumis |
| CURSOR_ALREADY_OPEN | ORA-06511 | Proovin avada a kursor mis on juba avatud |
| DUP_VAL_ON_INDEX | ORA-00001 | Duplikaatväärtuse salvestamine andmebaasi veergu, mis on piiratud unikaalse indeksiga |
| INVALID_CURSOR | ORA-01001 | Lubamatud kursoritoimingud, näiteks avamata kursori sulgemine |
| INVALID_NUMBER | ORA-01722 | Tähemärgi numbriks teisendamine ebaõnnestus sobimatu numbrimärgi tõttu |
| EI_DATA_LEITUD | ORA-01403 | SELECT-lause, mis sisaldab INTO-klauslit, ei too ühtegi rida. |
| ROW_MISMATCH | ORA-06504 | Kursori muutuja andmetüüp ei ühildu kursori tegeliku tagastustüübiga |
| SUBSCRIPT_BEYOND_COUNT | ORA-06533 | Viitamine kollektsioonile indeksinumbriga, mis on suurem kui kollektsiooni suurus |
| SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | Kollektsioonile viitamine indeksinumbriga, mis jääb lubatud vahemikust väljapoole (näiteks -1) |
| TOO_MANY_ROWS | ORA-01422 | SELECT-lause koos INTO-klausliga tagastab rohkem kui ühe rea |
| VALUE_ERROR | ORA-06502 | Aritmeetiline või suuruspiirangu viga (näiteks muutujale „suurus” suurema väärtuse määramine) |
| ZERO_DIVIDE | ORA-01476 | Arvu jagamine nulliga |
Kasutaja määratud erand
Lisaks ülaltoodud eelnevalt määratletud eranditele saab programmeerija luua kohandatud erandeid ja neid hallata. Need luuakse alamprogrammi tasandil deklaratsiooniosas ja on nähtavad ainult selle alamprogrammi sees. Paketi spetsifikatsioonis määratletud erand on avalik erand ja on nähtav kõikjal, kus paketile juurde pääseb.
Süntaks: Alamprogrammi tasandil
DECLARE <exception_name> EXCEPTION; BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> END;
- Ülaltoodud süntaksis on muutuja 'exception_name' defineeritud tüübina EXCEPTION.
- Seejärel saab seda kasutada samamoodi nagu eelnevalt määratletud erandit.
Süntaks: Paketi spetsifikatsiooni tasemel
CREATE PACKAGE <package_name> IS <exception_name> EXCEPTION; . . END <package_name>;
- Ülaltoodud süntaksis on muutuja 'exception_name' defineeritud paketi spetsifikatsioonis tüübina EXCEPTION. .
- Seda saab kasutada kogu andmebaasis kõikjal, kus paketti 'paketi_nimi' saab kutsuda.
PL/SQL tõstmise erand
Kõik eelnevalt määratletud erandid käivitatakse kaudselt alati, kui ilmneb vastav tõrge. Kasutaja määratletud erandid tuleb aga käivitada selgesõnaliselt, kasutades märksõna RAISE. RAISE'i saab kasutada allpool näidatud viisidel.
Kui RAISE-funktsiooni kasutatakse käitleja sees iseseisvalt, edastab see juba tekitatud erandi ülemplokki. Seda saab kasutada ainult erandploki sees, nagu allpool näidatud.
Allolev ekraanipilt näitab RAISE funktsiooni kasutamist üksi, et uuesti esile kutsuda erand ümbritsevale plokile:
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> RAISE; END;
Süntaksi selgitus:
- Ülaltoodud süntaksis kasutatakse märksõna RAISE erandite käsitlemise plokis.
- Alati, kui programm kohtab erandit 'exception_name', käsitletakse erandit ja see lõpeb tavapäraselt.
- Seejärel levitab käitleja märksõna RAISE sama erandi ülemprogrammile.
Märge: Emaplokile erandi tegemisel peab tekitatav erand olema nähtav ka vanemplokis; vastasel juhul Oracle viskab vea.
Kasutaja määratletud või eelnevalt määratletud erandi käivitamiseks võite kasutada ka märksõna RAISE, millele järgneb erandi nimi. Seda vormi saab kasutada nii täitmis- kui ka erandite käsitlemise osas.
Allolev ekraanipilt näitab RAISE käsku, millele järgneb erandi nimi konkreetse erandi tekitamiseks:
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> RAISE <exception_name> EXCEPTION WHEN <exception_name> THEN <Handler> END;
Süntaksi selgitus:
- Ülaltoodud süntaksis kasutatakse täitmisosas märksõna RAISE, millele järgneb erand 'exception_name'.
- See tekitab käitusajal selle konkreetse erandi ja seejärel tuleb seda edasi käsitleda või tõstatada.
Näide 1: Selles näites näeme järgmist:
- Kuidas erandit deklareerida
- Kuidas deklareeritud erandit esile kutsuda
- Kuidas seda põhiplokki levitada
Allolev ekraanipilt näitab täielikku plokki, mis deklareerib sample_exceptioni, tekitab selle pesastatud ploki sees ja levitab selle põhiplokki:
Järgmisel ekraanipildil on sama näide jätkumas, kus põhiplokk lõpuks levitatud erandi tabab:
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 Selgitus:
- Code rida 2: Muutuja 'sample_exception' deklareerimine EXCEPTION tüübina.
- Code rida 3: Protseduuri nested_block deklareerimine.
- Code rida 6: Lause „Pesastatud ploki sees” printimine.
- Code rida 7: Lause „Pesastatud plokist näidise_erandi tekitamine” printimine.
- Code rida 8: Erandi tõstmine 'RAISE sample_exception' abil.
- Code rida 10: Pesastatud ploki erandi sample_exception erandikäitleja.
- Code rida 11: Prinditakse lause „Pesastatud plokis on püütud kinni erand. Tõstes põhiplokki“.
- Code rida 12: Erandi tegemine põhiplokile (selle levitamine).
- Code rida 15: Lause „Põhiploki sees“ printimine.
- Code rida 16: Lause “Pesastatud ploki kutsumine” printimine.
- Code rida 17: Nested_block protseduuri kutsumine.
- Code rida 19: Erandi töötleja näidis_erandi jaoks põhiplokis.
- Code rida 20: Lause „Põhiplokis on püütud erandit” printimine.
Olulised punktid, millele tuleb tähelepanu pöörata jaotises Erand
- Funktsioonis peaks erand alati kas tagastama väärtuse või erandit veelgi tõstma; vastasel juhul Oracle viskab käitusajal vea „Funktsioon tagastas ilma väärtuseta”.
- Tehingute kontrolli avaldused saab väljastada erandite käsitlemise ploki sees.
- SQLERRM ja SQLCODE on sisseehitatud funktsioonid, mis tagastavad vastavalt eranditeate ja erandikoodi.
- Kui erandit ei käsitleta, siis vaikimisi tühistatakse kõik selle seansi aktiivsed tehingud.
- RAISE_APPLICATION_ERROR (- , ) saab kasutada funktsiooni RAISE asemel, et kuvada kohandatud koodi ja teatega tõrge. Veakood peab olema vahemikus -20000 kuni -20999.





