DECLARE, sau definiţie subprogram (procedură, funcţie) [declaraţii de variabile, constante, cursoare, excepţii, tipuri, proceduri locale, funcţii locale, etc.] BEGIN instrucţiuni [EXCEPTION tratare excepţii ] END;
Un bloc anonim sau un subprogram se poate termina în mod normal, când se execută toate instrucţiunile,
sau la apariţia unei erori (excepţie). O eroare apărută poate fi tratată:
WHEN identificare_exceptie THEN lista_de_instructiuni;Excepţiile netratate până la un moment dat pot fi luate împreună pentru o tratare unică. Acestea vor fi precizate prin identificarea OTHERS din clauza WHEN.
Exemple:
Denumirea excepţiei | Codul Oracle | Observaţii |
CURSOR_ALREADY_OPEN | ORA-06511 | |
DUP_VAL_ON_INDEX | ORA-00001 | |
LOGIN_DENIED | ORA-01017 | |
VALUE_ERROR | ORA-06502 | la trunchieri sau conversii, ex: x varchar(5); x:='0123456'; |
ZERO_DEVIDE | ORA-01476 | |
INVALID_NUMBER | ORA-01722 | se face referire la o construcţie care nu este număr, ex: to_char('abc'); |
NO_DATA_FOUND | ORA-01403 | |
TOO_MANY_ROWS | ORA-01422 |
identificator EXCEPTION;Atunci când sunt întrunite condiţiile dorite pentru o excepţie (acea excepţie pentru care s-a definit identificatorul) se poate genera această excepţie prin instrucţiunea:
RAISE identificator;Excepţia definită de utilizator poate fi tratată în partea de excepţii a blocului, la fel ca o excepţie a sistemului.
DECLARE n CHAR(20); BEGIN SELECT nume INTO n FROM studenti; -- va genera: ORA-01422: exact fetch returns more than requested number of rows END; |
Memorarea erorilor într-un tabel:
CREATE TABLE erori(cod number, mesaj varchar(80)); DECLARE n CHAR(20); mesaj CHAR(80); cod NUMBER; BEGIN SELECT nume INTO n FROM studenti; EXCEPTION WHEN OTHERS THEN mesaj:=SUBSTR(SQLERRM,1,80); cod:=SQLCODE; INSERT INTO erori VALUES(cod, mesaj); END; / SELECT * FROM erori; DROP TABLE erori; |
CREATE TABLE erori(cod number, mesaj varchar(80)); DECLARE n CHAR(20); mesaj CHAR(80); cod NUMBER; BEGIN SELECT nume INTO n FROM studenti; EXCEPTION WHEN TOO_MANY_ROWS THEN INSERT INTO erori(mesaj) VALUES('Prea multe linii'); WHEN OTHERS THEN mesaj:=SUBSTR(SQLERRM,1,80); cod:=SQLCODE; INSERT INTO erori VALUES(cod, mesaj); END; / SELECT * FROM erori; DROP TABLE erori; |
Calculul factorialului cu o funcţie locală. In funcţie nu se verifică valoarea argumentului (dacă argumentul este >=0). set serveroutput on DECLARE n number; m number; i number; FUNCTION f(n in number) RETURN NUMBER; FUNCTION f(n in number) RETURN NUMBER IS BEGIN IF n=0 THEN RETURN 1; ELSE RETURN n*f(n-1); END IF; END; BEGIN dbms_output.enable; n:=10; FOR i IN 1..n LOOP m:=f(i); dbms_output.put_line('(' || to_char(i) || ')! = ' || to_char(m)); END LOOP i; END; |
Calculul factorialului cu o funcţie locală. In funcţie se generează eroare pentru argument negativ. set serveroutput on DECLARE n number; m number; i number; FUNCTION f(n in number) RETURN NUMBER; FUNCTION f(n in number) RETURN NUMBER IS val_negativa EXCEPTION; BEGIN IF n<0 then RAISE val_negativa; END IF; IF n=0 THEN RETURN 1; ELSE RETURN n*f(n-1); END IF; EXCEPTION WHEN val_negativa THEN dbms_output.put_line('Valoare negativa'); END; BEGIN --vor rezulta erori dbms_output.enable; n:=-10; --n:=10; m:=f(n); dbms_output.put_line('(' || to_char(n) || ')! = ' || to_char(m)); END;La folosirea funcţiei, dacă apare o eroare, atunci apare o eroare suplimentară la blocul de bază, deoarece f(...) nu are valoare. |
Eliminarea erorii precedente.
set serveroutput on DECLARE n number; m number; i number; FUNCTION f(n in number) RETURN NUMBER; FUNCTION f(n in number) RETURN NUMBER IS val_negativa EXCEPTION; BEGIN IF n<0 then RAISE val_negativa; END IF; IF n=0 THEN RETURN 1; ELSE RETURN n*f(n-1); END IF; EXCEPTION WHEN val_negativa THEN dbms_output.put_line('Valoare negativa'); END; BEGIN dbms_output.enable; n:=-10; m:=f(n); dbms_output.put_line('(' || to_char(n) || ')! = ' || to_char(m)); EXCEPTION WHEN OTHERS THEN dbms_output.put_line('Terminare eronata'); END; |
Funcţie memorată pentru calculul factorialului, fără analiza excepţiilor.
CREATE OR REPLACE FUNCTION factorial (n in NUMBER) RETURN NUMBER AS BEGIN IF n=0 THEN RETURN 1; ELSE RETURN n*factorial(n-1); END IF; END; |
Funcţie memorată pentru calculul factorialului, cu analiza argumentului negativ.
CREATE OR REPLACE FUNCTION factorial (n in NUMBER) RETURN NUMBER AS val_negativa exception; BEGIN IF n<0 THEN raise val_negativa; end if; IF n=0 THEN RETURN 1; ELSE RETURN n*factorial(n-1); END IF; EXCEPTION WHEN val_negativa THEN RETURN -1; END; |