Documente Academic
Documente Profesional
Documente Cultură
CUPRINS
Erori la compilare
Tipuri de erori
Erori la execuie
Excepii externe
Excepiile interne:
o se produc atunci cnd un bloc PL/SQL nu respect o regul Oracle sau depete o
limit a sistemului de operare;
o pot fi independente de structura bazei de date sau pot s apar datorit nerespectrii
constrngerilor statice implementate n structur (PRIMARY KEY, FOREIGN KEY,
NOT NULL, UNIQUE, CHECK);
Atunci cnd apare o eroare Oracle, excepia asociat acesteia se declaneaz implicit.
o De exemplu, dac apare eroarea ORA-01403 (deoarece o comand SELECT nu
ntoarce nicio linie) atunci implicit PL/SQL activeaz excepia NO_DATA_FOUND
(al crui cod este 100).
o Cu toate c fiecare astfel de excepie are asociat un cod specific, ele trebuie referite
prin nume.
Declanare
Da Da Nu
automat
Declanare
Opional Opional Da
explicit
Sintaxa:
EXCEPTION
WHEN nume_excepie1 [OR nume_excepie2 ] THEN
secvena_de_instruciuni_1;
[WHEN nume_excepie3 [OR nume_excepie4 ] THEN
secvena_de_instruciuni_2;]
[WHEN OTHERS THEN
secvena_de_instruciuni_n;]
END;
o Clauza WHEN OTHERS trebuie s fie ultima clauz specificat i trebuie s fie
unic.
Toate excepiile care nu au fost specificate explicit vor fi captate prin aceast
clauz.
Funcia SQLCODE:
o obine codul excepiei;
o ntoarce o valoare de tip numeric;
o codul excepiei este:
- un numr negativ, n cazul unei erori interne;
- numrul +100, n cazul excepiei NO_DATA_FOUND;
- numrul 0, n cazul unei execuii normale (fr excepii);
- numrul 1, n cazul unei excepii definite de utilizator.
Funcia SQLERRM:
o obine mesajul asociat excepiei;
o ntoarce un ir de caractere;
o lungimea maxim a mesajului este de 512 caractere;
o mesajul asociat excepiei declanate poate fi furnizat i de funcia
DBMS_UTILITY.FORMAT_ERROR_STACK.
Dei excepiile interne sunt lansate implicit (automat) de ctre sistem, sunt
cazuri n care utilizatorul le poate invoca explicit.
o trebuie s apar n partea declarativ a unui bloc, pachet sau subprogram, dup
definirea numelui excepiei;
o poate s apar de mai multe ori ntr-un program; de asemenea, pot fi asignate mai
multe nume pentru acelai cod de eroare.
Excepiile externe:
o sunt excepii definite de utilizator;
o sunt declarate n seciunea declarativ a unui bloc, subprogram sau pachet;
o sunt activate explicit n partea executabil a blocului (folosind comanda RAISE
nsoit de numele excepiei);
o pot s apar n toate seciunile unui bloc, subprogram sau pachet;
o nu pot s apar n instruciuni de atribuire sau n comenzi SQL;
o n mod implicit, au asociat acelai cod (+1) i acelai mesaj (User-Defined
Exception).
DECLARE
nume_excepie EXCEPTION; -- declarare excepie
BEGIN
RAISE nume_excepie; -- activare excepie
-- execuia este ntrerupt i se transfer
-- controlul n seciunea EXCEPTION
EXCEPTION
WHEN nume_excepie THEN
-- definire mod de tratare a erorii
END;
EXCEPTION
WHEN exceptie THEN
RAISE_APPLICATION_ERROR(-20002,'info invalida');
END;
o n ambele seciuni:
DECLARE
exceptie EXCEPTION;
PRAGMA EXCEPTION_INIT (exceptie, -20000);
BEGIN
DELETE produse WHERE denumire = 'produs cautat';
IF SQL%NOTFOUND THEN
RAISE_APPLICATION_ERROR(-20000,'Date incorecte');
END IF;
EXCEPTION
WHEN exceptie THEN
DBMS_OUTPUT.PUT_LINE('Mesajul exceptiei: '||SQLERRM);
DBMS_OUTPUT.PUT_LINE('Codul exceptiei: '||SQLCODE);
END;
Exemplul 9.6 -
CREATE OR REPLACE TRIGGER trig
BEFORE UPDATE OF serie ON case
FOR EACH ROW
WHEN (NEW.serie <> OLD.serie)
BEGIN
RAISE_APPLICATION_ERROR (-20145,
'Nu puteti modifica seria casei fiscale!');
END;
/
BEGIN
-- lansare comanda declasatoare
UPDATE case
SET serie = serie||'_';
EXCEPTION
-- tratare exceptie
WHEN exceptie THEN
-- se afiseaza mesajul erorii specificat in trigger
-- in procedura RAISE_APPLICATION_ERROR
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/
BEGIN
comanda_1; -- declanseaza exceptia E
comanda_2; -- nu se mai executa
EXCEPTION
WHEN E THEN
set_comenzi; -- se executa
END;
BEGIN
BEGIN
comanda_1; -- declanseaza exceptia E
EXCEPTION
WHEN E THEN
set_comenzi; -- se executa
END;
comanda_2; -- se executa
EXCEPTION
...
END;
Uneori este dificil de aflat care comand SQL a determinat o anumit eroare, deoarece
exist o singur seciune pentru tratarea erorilor unui bloc.
Variante de rezolvare a acestor situaii:
o utilizarea unui contor care s identifice instruciunea SQL care a declanat excepia.
DECLARE
contor NUMBER(1);
BEGIN
contor :=1;
comanda_SELECT_1;
contor :=2;
comanda_SELECT_2;
contor :=3;
comanda_SELECT_3;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('comanda SELECT '|| contor);
END;
BEGIN
BEGIN
comanda_SELECT_1;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('comanda SELECT 1');
END;
BEGIN
comanda_SELECT_2;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('comanda SELECT 2');
END;
BEGIN
comanda_SELECT_3;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('comanda SELECT 3');
END;
END;
Exemplul 9.7
DECLARE
v_den produse.denumire%TYPE;
v_id produse.id_produs%TYPE := &p_id;
BEGIN
SELECT denumire
INTO v_den
FROM produse
WHERE id_produs = v_id;
<<eticheta>>
DBMS_OUTPUT.PUT_LINE('Denumirea produsului este '||v_den);
EXCEPTION
WHEN NO_DATA_FOUND THEN v_den := ' ';
GOTO eticheta; --salt ilegal in blocul curent
END;
/
Excepia este produs i tratat n subbloc. Dup tratarea excepiei controlul este
transmis blocului exterior.
DECLARE
A EXCEPTION;
BEGIN
BEGIN
RAISE A; -- in subbloc se produse exceptia A
EXCEPTION
WHEN A THEN -- exceptia A este tratata in subbloc
END;
-- aici este reluat controlul
END;
Excepia este produs n subbloc, dar nu este tratat n acesta. Excepia se propag
spre blocul exterior. Regula poate fi aplicat de mai multe ori.
DECLARE
A EXCEPTION;
B EXCEPTION;
BEGIN
BEGIN
RAISE B; -- in subbloc se produse exceptia B
EXCEPTION
WHEN A THEN
--exceptia B nu este tratata in subbloc
END;
EXCEPTION
WHEN B THEN
/*exceptia B s-a propagat spre blocul exterior unde este
tratata, apoi controlul este dat in exteriorul blocului */
END;
Dac n seciunea declarativ este generat o excepie, atunci aceasta se propag ctre
blocul exterior, unde are loc tratarea acesteia. Chiar dac exist un handler pentru
excepie n blocul curent, acesta nu este executat.
Exemplul 9.8
BEGIN
DECLARE
nr_produse NUMBER(10) := ' ';
-- este generata eroarea VALUE_ERROR
BEGIN
SELECT COUNT (DISTINCT id_produs)
INTO nr_produse
FROM facturi_produse;
EXCEPTION
WHEN VALUE_ERROR THEN
-- eroarea nu este captata si tratata in blocul intern
DBMS_OUTPUT.PUT_LINE('Eroare bloc intern: ' || SQLERRM);
END;
EXCEPTION
WHEN VALUE_ERROR THEN
-- eroarea este captata si tratata in blocul extern
DBMS_OUTPUT.PUT_LINE('Eroare bloc extern: ' || SQLERRM );
END;
/
LINE specific numrul liniei n care apare eroarea, dar acesta nu corespunde
liniei efective din fiierul text (se refer la codul surs depus n
USER_SOURCE).
Exemplul 9.9 -
CREATE OR REPLACE FUNCTION f_test
RETURN NUMBER;
IS
BEGIN
RETURN 1;
END;
/
FUNCTION F_TEST compiled
Errors: check compiler log
Bibliografie