Tratarea excepțiilor în Oracle PL/SQL (Exemple)
⚡ Rezumat inteligent
Tratarea excepțiilor în Oracle PL/SQL capturează erorile de execuție care opresc execuția unui bloc, permițând motorului să transfere controlul către o secțiune EXCEPTION unde rutine predefinite, definite de utilizator și OTHERS răspund, generează sau propagă erori în siguranță.
Ce este gestionarea excepțiilor în PL/SQL?
O excepție apare atunci când motorul PL/SQL întâlnește o instrucțiune pe care nu o poate executa din cauza unei erori care apare la momentul execuției. Aceste erori nu sunt detectate la momentul compilării și, prin urmare, trebuie gestionate doar la momentul execuției.
De exemplu, dacă motorul PL/SQL primește o instrucțiune de împărțire a unui număr la zero, acesta generează eroarea ca excepție. Excepția este generată doar în timpul execuției de către motorul PL/SQL.
O excepție oprește executarea ulterioară a programului, așa că, pentru a evita o astfel de condiție, eroarea trebuie capturată și tratată separat. Acest proces se numește tratarea excepțiilor, în care programatorul gestionează eroarea care poate apărea în timpul execuției.
Sintaxa de gestionare a excepțiilor
Excepțiile sunt gestionate la nivel de bloc. Odată ce apare o excepție într-un bloc, controlul părăsește partea de execuție a acelui bloc, iar excepția este apoi gestionată în partea de gestionare a excepțiilor a blocului. După ce excepția este gestionată, controlul nu se poate întoarce la secțiunea de execuție a aceluiași bloc.
Ilustrația de mai jos arată cum secțiunea de execuție și secțiunea de gestionare a excepțiilor se află într-un singur bloc PL/SQL:
Sintaxa de mai jos explică cum se prinde și se gestionează o excepție.
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;
Explicația sintaxei:
- În sintaxa de mai sus, blocul de tratare a excepțiilor conține o serie de condiții WHEN pentru a gestiona excepțiile.
- Fiecare condiție WHEN este urmată de un nume de excepție care se așteaptă să fie generată la momentul execuției.
- Când o excepție este generată în timpul execuției, motorul PL/SQL caută în partea de tratare a excepțiilor acea excepție specifică, începând de la prima clauză WHEN și continuând secvențial.
- Dacă găsește un handler pentru excepția ridicată, execută codul respectiv.
- Dacă nicio clauză WHEN nu corespunde excepției generate, motorul PL/SQL execută partea WHEN OTHERS, dacă este prezentă. Acest handler este comun tuturor excepțiilor.
- După ce handler-ul rulează, controlul părăsește blocul curent.
- Doar un singur handler de excepții poate fi executat pentru un bloc în timpul execuției. După ce rulează, motorul sare peste handlerele rămase și părăsește blocul curent.
Notă: Funcția WHEN OTHERS ar trebui plasată întotdeauna ultima în secvență. Orice handler scris după WHEN OTHERS nu rulează niciodată, deoarece controlul părăsește blocul odată ce funcția WHEN OTHERS a fost executată.
Tipuri de excepție
Există două tipuri de excepții în PL / SQL.
- Excepții predefinite
- Excepții definite de utilizator
Excepții predefinite
Oracle are predefinite câteva excepții comune. Fiecare excepție predefinită are un nume unic și un număr de eroare, iar toate sunt declarate în pachetul STANDARD din OracleÎn cod, puteți utiliza aceste nume de excepții predefinite direct pentru a gestiona erorile corespunzătoare. Multe dintre ele se mapează direct la erori comune SQL greșeli pe care le întâlnești zi de zi.
Mai jos sunt câteva excepții predefinite:
| Excepție | Eroare Code | Motivul excepției |
|---|---|---|
| ACCESS_INTO_NULL | ORA-06530 | Atribuirea unei valori atributelor unui obiect neinițializat |
| CASE_NOT_FOUND | ORA-06592 | Niciuna dintre clauzele WHEN dintr-o instrucțiune CASE nu este satisfăcută și nu este specificată nicio clauză ELSE. |
| COLLECTION_IS_NULL | ORA-06531 | Utilizarea metodelor de colecție (cu excepția EXISTS) sau accesarea atributelor colecției pe o colecție neinițializată |
| CURSOR_DEJA_DESCHIS | ORA-06511 | Încercarea de a deschide a cursor care este deja deschis |
| DUP_VAL_ON_INDEX | ORA-00001 | Stocarea unei valori duplicate într-o coloană a bazei de date care este constrânsă de un index unic |
| INVALID_CURSOR | ORA-01001 | Operațiuni ilegale cu cursorul, cum ar fi închiderea unui cursor nedeschis |
| NUMAR INVALID | ORA-01722 | Conversia unui caracter într-un număr a eșuat din cauza unui caracter numeric nevalid |
| NU S-AU GASIT DATE | ORA-01403 | O instrucțiune SELECT care conține o clauză INTO nu preia rânduri |
| ROW_MISMATCH | ORA-06504 | Tipul de date al variabilei cursor este incompatibil cu tipul de date returnat de cursor. |
| SUBSCRIPT_BEYOND_COUNT | ORA-06533 | Referirea la o colecție printr-un număr de index mai mare decât dimensiunea colecției |
| SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | Referirea la o colecție printr-un număr de index în afara intervalului legal (de exemplu, -1) |
| TOO_MANY_ROWS | ORA-01422 | O instrucțiune SELECT cu o clauză INTO returnează mai mult de un rând |
| VALUE_ERROR | ORA-06502 | O eroare aritmetică sau de constrângere de dimensiune (de exemplu, atribuirea unei valori mai mari decât variabila size) |
| ZERO_DIVIDE | ORA-01476 | Împărțirea unui număr la zero |
Excepție definită de utilizator
Pe lângă excepțiile predefinite de mai sus, un programator poate crea excepții personalizate și le poate gestiona. Acestea sunt create la nivel de subprogram în partea de declarație și sunt vizibile numai în interiorul subprogramului respectiv. O excepție definită într-o specificație de pachet este o excepție publică și este vizibilă oriunde poate fi accesat pachetul.
Sintaxă: La nivel de subprogram
DECLARE <exception_name> EXCEPTION; BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> END;
- În sintaxa de mai sus, variabila „name_excepție” este definită ca fiind de tipul EXCEPȚIE.
- Apoi poate fi utilizată în același mod ca o excepție predefinită.
Sintaxă: La nivel de specificație a pachetului
CREATE PACKAGE <package_name> IS <exception_name> EXCEPTION; . . END <package_name>;
- În sintaxa de mai sus, variabila „nume_excepție” este definită ca tipul EXCEPȚIE în specificația pachetului .
- Poate fi utilizat în baza de date oriunde poate fi apelat pachetul „nume_pachet”.
PL/SQL ridică excepție
Toate excepțiile predefinite sunt generate implicit ori de câte ori apare eroarea corespunzătoare. Excepțiile definite de utilizator, însă, trebuie generate explicit folosind cuvântul cheie RAISE. RAISE poate fi utilizat în modurile prezentate mai jos.
Dacă RAISE este utilizată independent în interiorul unui handler, aceasta propagă excepția deja generată către blocul părinte. Poate fi utilizată doar în interiorul unui bloc de excepții, așa cum se arată mai jos.
Captura de ecran de mai jos arată RAISE folosită singură pentru a re-raisi o excepție la blocul inclus:
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> RAISE; END;
Explicația sintaxei:
- În sintaxa de mai sus, cuvântul cheie RAISE este utilizat în interiorul blocului de tratare a excepțiilor.
- Ori de câte ori programul întâlnește excepția „nume_excepție”, excepția este gestionată și se finalizează normal.
- Cuvântul cheie RAISE din handler propagă apoi aceeași excepție către programul părinte.
Notă: Când se ridică o excepție la blocul părinte, excepția ridicată trebuie să fie vizibilă și în blocul părinte; altfel Oracle aruncă o eroare.
De asemenea, puteți utiliza cuvântul cheie RAISE urmat de un nume de excepție pentru a genera acea excepție definită de utilizator sau predefinită. Acest formular poate fi utilizat atât în partea de execuție, cât și în partea de gestionare a excepțiilor.
Captura de ecran de mai jos arată RAISE urmată de un nume de excepție pentru a genera o anumită excepție:
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> RAISE <exception_name> EXCEPTION WHEN <exception_name> THEN <Handler> END;
Explicația sintaxei:
- În sintaxa de mai sus, cuvântul cheie RAISE este utilizat în partea de execuție, urmat de excepția „name_excepție”.
- Aceasta ridică acea excepție particulară în timpul execuției și apoi trebuie gestionată sau ridicată în continuare.
Exemplu 1: În acest exemplu, vom vedea:
- Cum se declară o excepție
- Cum se ridică excepția declarată
- Cum să-l propagă în blocul principal
Captura de ecran de mai jos prezintă blocul complet care declară excepția sample_exception, o generează în interiorul unui bloc imbricat și o propagă în blocul principal:
Următoarea captură de ecran prezintă același exemplu în continuare, unde blocul principal capturează în final excepția propagată:
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 Explicaţie:
- Code linia 2: Declararea variabilei „sample_exception” ca tip EXCEPȚIE.
- Code linia 3: Declararea procedurii nested_block.
- Code linia 6: Afișarea instrucțiunii „În interiorul unui bloc imbricat”.
- Code linia 7: Afișarea instrucțiunii „Găsirea excepției_exemplarului dintr-un bloc imbricat”.
- Code linia 8: Ridicarea excepției folosind „RAISE sample_exception”.
- Code linia 10: Tratament de excepții pentru excepția sample_exception din blocul imbricat.
- Code linia 11: Afișarea instrucțiunii „Excepție capturată în blocul imbricat. Se ridică la blocul principal”.
- Code linia 12: Ridicarea excepției la blocul principal (propagarea acesteia).
- Code linia 15: Afișarea instrucțiunii „În interiorul blocului principal”.
- Code linia 16: Tipărirea instrucțiunii „Apelarea blocului imbricat”.
- Code linia 17: Apelarea procedurii nested_block.
- Code linia 19: Managerul de excepții pentru sample_exception în blocul principal.
- Code linia 20: Afișarea instrucțiunii „Excepție capturată în blocul principal”.
Puncte importante de remarcat în Excepție
- Într-o funcție, o excepție ar trebui întotdeauna fie să returneze o valoare, fie să ridice excepția în continuare; altfel Oracle generează o eroare de tip „Funcție returnată fără valoare” la momentul execuției.
- Declarații de control al tranzacțiilor poate fi emisă în interiorul blocului de tratare a excepțiilor.
- SQLERRM și SQLCODE sunt funcții încorporate care returnează mesajul de excepție, respectiv codul de excepție.
- Dacă o excepție nu este gestionată, atunci, în mod implicit, toate tranzacțiile active din sesiunea respectivă sunt anulate.
- RAISE_APPLICATION_ERROR (- , ) poate fi folosit în loc de RAISE pentru a genera o eroare cu un cod și un mesaj personalizate. Codul de eroare trebuie să fie între -20000 și -20999.






