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;
|