Facultatea de Cibernetică, Statistică şi Informatică Economică SGBD Oracle – seminarul 6

TRATAREA EXCEPŢIILOR
O excepţie este un identificator PL/SQL asociat unei condiţii anormale apărute în timpul execuţiei unui bloc PL/SQL. Invocarea unei excepţii are ca efect terminarea blocului, deci ieşirea din blocul PL/SQL. Pentru evitarea unor situaţii de întrerupere anormală, excepţia poate fi captată si poate fi specificată o rutină de tratare a acesteia. O excepţie poate fi invocata in doua moduri: a. Apare o eroare Oracle si excepţia asociata ei este automat invocată b. Excepţia poate fi invocată în mod explicit prin instrucţiunea RAISE in cadrul blocului. Captarea unei excepţii Daca excepţia este invocată în secţiunea executabilă a unui bloc se caută în cadrul secţiunii de tratare a excepţiilor o rutină de tratare asociata. Daca PL/SQL poate trata excepţia, ea nu este propagată în blocul exterior sau în mediul apelant, caz în care se consideră că execuţia blocului s-a desfăşurat cu succes. Propagarea unei excepţii Daca nu există o rutină pentru tratarea ei, excepţia este propagată în mediul apelant, caz în care execuţia blocului se termină cu eşec. Tipuri de excepţii Sunt trei tipuri de excepţii: Tipul Excepţii pre-definite asociate erorilor care apar cel mai frecvent în blocurile PL/SQL (de exemplu NO_DATA_ FOUND, TOO_MANY_ROWS, INVALID_CURSOR, ZERO_DIVIDE) Excepţii non-predefine recunoscute de Oracle dar tratate de utilizator cu ajutorul codului de eroare returnat (de exemplu ORA- 01400). Mod de manipulare Nu trebuie declarate, serverul Oracle le invocă în mod automat, dar trebuie tratate în secţiune EXCEPTION.

Trebuie declarate în secţiunea declarativă. Serverul Oracle le invocă în mod automat, dar trebuie tratate în secţiune EXCEPTION. Excepţii definite de utilizator, asociate unor condiţii Trebuie declarate în secţiunea specifice de prelucrare (de exemplu cazul în care declarativă, invocate de către utilizator valoarea stocului unui anumit produs este zero) şi tratate în secţiunea EXCEPTION. Tratarea tuturor excepţiilor se realizează în secţiunea EXCEPTION a blocurilor PL/SQL astfel: EXCEPTION WHEN exception1 [OR exception2 …] THEN statement1 ; statement2 ; … [WHEN exception3 [OR exception4 …] THEN
1

put_line('Nu exista angajatul cu acest ID!'). / Să se afişeze salariul angajatului cu prenumele John. …] [WHEN OTHERS THEN statement1 . EXCEPTION WHEN NO_DATA_FOUND THEN dbms_output. …] 1. capitolul 10. Statistică şi Informatică Economică SGBD Oracle – seminarul 6 statement1 . Lista completă a excepţiilor predefinite Oracle va fi consultată din PL/SQL Reference. Câteva exemple de excepţii predefinite sunt prezentate mai jos: Numele NO_DATA_FOUND TOO_MANY_ROWS INVALID_CURSOR şi CURSOR_ALREADY_ OPEN Numărul erorii ORA-01403 ORA-01422 ORA-01001 Descriere O instrucţiune SELECT care ar fi trebuit sa întoarcă o singura linie nu a returnat nici o linie. Tratarea excepţiilor predefinite ale Serverului Oracle Acestea nu trebuie declarate. fiind definite de către Oracle Server si invocate implicit. Să se trateze eroare apărută în cazul în care există mai mulţi angajaţi cu acelaşi nume (interogarea SQL din bloc întoarce mai multe înregistrări).put_line(v_nume). pagina 10-4. O instrucţiune SELECT care ar fi trebuit sa întoarcă o singura linie a returnat mai multe linii. BEGIN SELECT nume INTO v_nume FROM angajati WHERE id_angajat=10. statement2 . END. Să se trateze eroarea apărută în cazul în care nu există nici un angajat cu acest cod. Apariţia unei operaţii ilegale asupra unui cursor (de exemplu încercarea de a deschide un cursor deja deschis). SET SERVEROUTPUT ON 2 . Exemple: Să se afişeze angajatul cu codul 10. dbms_output. statement2 . set serveroutput on DECLARE v_nume VARCHAR2(20).Facultatea de Cibernetică.

• +100 – excepţia NO_DATA_FOUND.. 3) Tratarea excepţiei în zona EXCEPTION a blocului: EXCEPTION WHEN NUME_EXCEPTIE THEN .PUT_LINE('John are salariul de: '||sal). PRAGMA EXCEPTION_INIT(INSERT_EXCEPT. fără a preciza denumirea acestuia. DBMS_OUTPUT. Exemplu: Să se insereze în tabela departamente un nou departament cu ID-ul 200. department_name) values (200. • 1 – este o excepţie definită de utilizator. Tratarea excepţiilor non-predefinite Oracle Server Se poate capta o eroare a Serverului Oracle ce nu are asociata o excepţie predefinită asociindu-i un nume codului de eroare returnat sau folosind clauza WHEN OTHERS. BEGIN insert into departments (department_id. În acest caz va apare o eroarea cu codul ORA-01400 prin care programatorul este avertizat de încălcarea unei restricţii de integritate.Facultatea de Cibernetică.. directiva EXCEPTION_INIT determină compilatorul sa asocieze un nume de excepţie unui număr (cod) de eroare standard a Serverului Oracle.PUT_LINE('Exista mai multi salariati cu numele John! Utilizati un cursor pentru selectie!').. NULL). 2) Asocierea codului erorii cu excepţia declarată anterior: se realizează tot în zona DECLARE prin utilizarea directivei de compilare EXCEPTION_INIT: PRAGMA EXCEPTION_INIT(NUME_EXCEPTIE. • un număr negativ – o eroare Oracle Server. EXCEPTION WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT..se asociază un nume codului de eroare apărut INSERT_EXCEPT EXCEPTION.. Această excepţie poate fi tratată astfel: SET SERVEROUTPUT ON DECLARE -. BEGIN select salariul into sal from angajati where prenume='John'. -01400). COD_EROARE). Aceste atribute pot fi încărcate în variabile şi inserate într-o tabelă de erori pentru vizualizare şi verificare ulterioară.salariul%type. Se pot utiliza 2 atribute pentru a gestiona erorile apărute: SQLCODE – returnează codul numeric al erorii... END.. Poate avea următoarele valori: • 0 – nu a apărut nici o excepţie. SQLERRM – returnează mesajul asociat erorii. 3 . Statistică şi Informatică Economică SGBD Oracle – seminarul 6 DECLARE sal angajati. Unde COD_EROARE este un cod de eroare standard Oracle. / 2. Tratarea acestor erori se realizează in 3 paşi: 1) Declararea excepţiei: se face în zona DECLARE a blocului NUME_EXCEPTIE EXCEPTION. Aceasta permite referirea erorii standard prin nume şi scrierea unei rutine de tratare a ei. In PL/SQL..

cod. INSERT INTO erori VALUES(USER. / SELECT * FROM erori. reprezentând încălcarea restricţiei referenţiale. BEGIN DELETE FROM produse.PUT_LINE(SQLERRM).Facultatea de Cibernetică. CREATE TABLE erori (utilizator VARCHAR2(40).PUT_LINE('Nu ati precizat informatii suficiente pentru departament'). ATENTIE! Aceste variabile nu se pot utiliza direct într-o comandă SQL. PRAGMA EXCEPTION_INIT(del_exception. -2292). --se afişează mesajul erorii DBMS_OUTPUT. Ele trebuie declarate în secţiunea declarativa a blocului şi invocate explicit prin instrucţiunea RAISE. / Să se şteargă toate înregistrările din tabela PRODUSE. mesaj:=SQLERRM. Statistică şi Informatică Economică SGBD Oracle – seminarul 6 EXCEPTION --se tratează eroarea prin numele său WHEN insert_except THEN DBMS_OUTPUT. dbms_output. mesaj VARCHAR2(255). Tratarea excepţiilor definite de utilizator In PL/SQL se pot defini excepţii ale utilizatorului. 4 . END. EXCEPTION WHEN del_exception THEN dbms_output. 3. mesaj). Acest lucru va duce la apariţia erorii cu codul –2292. END. cod_eroare NUMBER(10). data DATE.put_line('Exista comenzi asignate lui'). del_exception EXCEPTION. SYSDATE. mesaj_eroare VARCHAR2(255) ). Valorile SQLCODE şi SQLERRM vor fi inserate în tabela ERORI. DECLARE cod NUMBER. drept pentru care vor fi încărcate mai întâi in variabile PL/SQL şi apoi utilizate în instrucţiuni SQL. cod:=SQLCODE.put_line('Nu puteti sterge produsul').

BEGIN IF TO_NUMBER(TO_CHAR(SYSDATE.PUT_LINE('Nu exista produsul cu acest ID'). 'HH24'))..put_line('Este ora '||TO_CHAR(SYSDATE. DECLARE e_exc1 EXCEPTION. IF SQL%NOTFOUND THEN RAISE invalid_prod. Exemple: Să se invoce o eroare în cazul în care utilizatorul încearcă să execute blocul PL/SQL după ora 17.put_line('Operatiune permisa doar '||' in timpul programului'). END IF. EXCEPTION WHEN e_exc1 THEN dbms_output. WHEN OTHERS THEN DBMS_OUTPUT.Facultatea de Cibernetică. END IF.. 3. Se declara excepţia în secţiunea declarativă: nume_exceptie EXCEPTION. în cadrul secţiunii executabile: RAISE nume_exceptie. EXCEPTION WHEN invalid_prod THEN DBMS_OUTPUT. Dacă nu se produce nici o actualizare (valoarea atributului SQL%ROWCOUNT este 0) sau dacă apare o altă eroare (OTHERS) atunci să se declanşeze o excepţie prin care să fie avertizat utilizatorul: DECLARE invalid_prod EXCEPTION. dbms_output.PUT_LINE('A aparut o eroare! Nu se poate actualiza denumirea produsului!').. END.. Prin instrucţiunea RAISE se invocă în mod explicit. Se tratează în rutina corespunzătoare din secţiunea de tratare a excepţiilor: WHEN nume_exceptie THEN. END.. / Să se modifice denumirea produsului cu id-ul 3. BEGIN UPDATE produse SET denumire_produs='Laptop ABC' WHERE id_produs=3. / 5 . 2. 'HH24'))>=17 THEN RAISE e_exc1. Statistică şi Informatică Economică SGBD Oracle – seminarul 6 Etape: 1.

Propagarea excepţiilor Odată excepţia declanşată în secţiunea executabilă a unui bloc. mesaj VARCHAR2(255). execuţia blocului se termina cu eşec. IF SQL%NOTFOUND THEN RAISE_APPLICATION_ERROR (-20999. / SELECT * FROM ERORI.'Cod produs invalid!'). INSERT INTO ERORI VALUES(USER. DECLARE cod NUMBER. cod:=SQLCODE. PRAGMA EXCEPTION_INIT(invalid_prod. cod. unde NR_EROARE poate fi un număr negativ cuprins între -20000 si -20999. 6 . END IF. Statistică şi Informatică Economică SGBD Oracle – seminarul 6 Erorile definite de utilizator pot fi tratate la nivelul aplicaţiilor ca şi erorile Oracle Server prin atribuirea de coduri cu ajutorul funcţiei: RAISE_APPLICATION_ERROR (NR_EROARE. Atunci când un sub-bloc tratează o excepţie. Daca nu se găseşte nici una. SYSDATE. se termină normal iar execuţia se reia în blocul ce-l cuprinde imediat după instrucţiunea END a sub-blocului. END. ea nu este propagată în blocul exterior sau în mediul apelant.Facultatea de Cibernetică. mesaj:=SQLERRM. BEGIN UPDATE produse SET denumire_produs='Laptop ABC' WHERE id_produs=3. se caută în cadrul secţiunii de tratare a excepţiilor (EXCEPTION) o rutină de tratare asociată. In acest caz tratarea se realizează asemănător cu erorile non-predefinite Oracle Server. Daca apare o excepţie iar în blocul curent nu există o rutină pentru tratarea sa.-20999). invalid_prod EXCEPTION. MESAJ).PUT_LINE('Nu exista produsul cu acest ID'). EXCEPTION WHEN invalid_prod THEN DBMS_OUTPUT. Daca PL/SQL poate trata excepţia. în mediul apelant apare o situaţie de excepţie nerezolvată. mesaj). Exemplu: Să se atribuie excepţiei din exemplul anterior un cod şi un mesaj de eroare şi să se insereze aceste valori în tabela ERORI. caz în care se consideră că execuţia blocului s-a desfăşurat cu succes. utilizator putând observa mesajul de eroare care a întrerupt execuţia normală. iar excepţia se propagă succesiv în blocurile exterioare până este găsită într-unul din ele o rutină pentru tratarea ei.

a. others—This is a catchall. login_denied—Login to Oracle failed because of invalid username and password. Trataţi orice altă excepţie cu o rutină de tratare corespunzătoare şi inseraţi în tabela MESAJE mesajul “A apărut o altă eroare!”. not_logged_on—A database call was made without being logged into Oracle. Dacă interogarea returnează mai mult de o valoare pentru numărul comenzii. Statistică şi Informatică Economică SGBD Oracle – seminarul 6 Exemple de exceptii predefinite: • • • • • • • • • • • • • • • • no_data_found—Single row SELECT returned no data.Facultatea de Cibernetică. conversion. zero_divide—Attempted to divide by zero. conversion. 2. the error will be trapped by this statement Exerciţii propuse: 1. If the error was not trapped in the previous exception traps. introduceţi în tabela Mesaje numărul comenzii. 7 . storage_error—Raised if PL/SQL runs out of memory or if memory is corrupted. truncation. trataţi excepţia cu o rutină de tratare corespunzătoare şi inseraţi în tabela MESAJE mesajul “Atenţie! In anul 2000 s-au încheiat mai multe comenzi!”. Dacă se returnează o singura linie. value_error—Arithmetic. or constraint error occurred. program_error—Raised if PL/SQL encounters an internal problem. invalid_number—Conversion of a number to a character string failed. invalid_cursor—Illegal cursor operation was attempted. cursor_already_open—Attempted to open a cursor that was previously opened. truncation. value_error—Arithmetic. transaction_backed_out—Usually raised when a remote portion of a transaction is rolled back. or constraint error occurred. c. timeout_on_resource—Timeout occurred while Oracle was waiting for a resource. având un câmp unic. Creaţi o tabela numita Mesaje. b. too_many_rows—Single row SELECT returned more than one row. d. Dacă interogarea nu returnează nici o valoare pentru numărul comenzii. de tip Varchar2. trataţi excepţia cu o rutină de tratare corespunzătoare şi inseraţi în tabela Mesaje mesajul “Atenţie! In anul 2000 nu sau încheiat comenzi!”. Scrieţi un bloc PL/SQL pentru a selecta codul comenzilor încheiate în anul 2000. dup_val_on_index—Attempted to insert a duplicate value into a column that has a unique index.

Sign up to vote on this title
UsefulNot useful