ex.: Error- 1403 produce NO_DATA_FOUND--prin generarea lor explicita
ex.: RAISE my_exception;
Exceptiile in general apar in doua moduri:
Sintaxa : RAISE exceptie_identificator;Exceptia generata deliberat poate fi fie una definita de utlizator sau o exceptie interna predefinita.
Este de dorit a genera o exceptie in conditii in care acea exceptie nu ar aparea normal . De exemplu,sa presupunem ca o interogare particulara are nevoie sa produca o eroare daca intoarce orice rand. In mod normal numai cand mai mult de un rand este intors apare exceptia TOO_MANY_ROWS:
BEGIN SELECT 'anything' INTO PLVAR FROM emp WHERE deptno = dept_number; IF SQL%FOUND THEN RAISE TOO_MANY_ROWS; END_IF; EXCEPTION WHEN NO_DATA_FOUND THEN NULL; END;
Deasemenea observati cat timp 'NO_DATA_FOUND' este considerat normal pentru
aceasta interogare, declaratia SELECT poate sa primeasca un sub_block
in care exceptia are un identificator nul. Cealalta exceptie TOO_MANY_ROWS
va fi transmisa la blocul exterior.
EXCEPTII DEFINITE DE UTILIZATOR
--nume declarate de utilizatori --RAISE cand trebuie sa termini procesarea --permite definirea propriilor conditii
SINTAXA identifier EXCEPTION EXEMPLU DECLARE credit_exceeded EXCEPTION; BEGIN IF stock_ordered>credit_limit THEN RAISE credit_exceeded; END IF
Exceptiile pot fi declarate impreuna cu alti identificatori la inceputul unui bloc. Aceste exceptii user_defined pot fi generate pentru situatii in care nici o procesare ulterioara a actiunilor blocului nu trebuie sa apara. Exceptiile sunt declarate astfel :
identificator EXCEPTION;
Exceptiile user_defined ne permit sa definim identificatori convenabili pentru propriile noastre conditii anormale. Cand apar aceste conditii exceptiile pot fi generate a.i . controlul este trecut la un identificator exceptie la sfarsitul blocului:
DECLARE credit_exceeded EXCEPTION; BEGIN IF stock_ordered> credit_limit THEN END IF; EXCEPTION WHEN credit_exceeded THEN ...
Sa ne amintim ca PL/SQL are nume predefinite pentru cateva dintre codurile exceptiilor interne dar nu pentru toate . Se pot prinde exceptiile fara nume cu identificatorul WHEN OTHERS, dar se poate dori declararea numelor propiilor exceptii pentru cateva coduri in mod specific. PL/SQL furnizeaza o pragma numita EXCEPTION_INIT , care ne permite specificarea unui nume de exceptie declarata, si numarul erorii ORACLE de care este legat.
Sintaxa: PRAGMA EXCEPTION_INIT( exception-identifier, number) ;`Exception-identifier` trebuie sa fi fost deja declarat in partea de declaratie a blocului.`Number` se refera la un numar de eroare tip executie.
Exemplu: DECLARE fetch_failed EXCEPTION; PRAGMA EXCEPTION_INIT (fetch_failed, -1002); . BEGIN . FETCH cursor1 INTO record1; . FETCH cursor1 INTO record1; /* Daca eroarea -1002 apare aici atunci exceptia fetch_failed este ridicata automat */ EXCEPTION WHEN fetch_failed THEN ...
Cind controlul este trecut partii EXCEPTION a unui bloc, numai o exceptie va fi intr-o stare `generata`. Se poate totusi dori definirea acelorasi actiuni pentru a minui mai mult de o exceptie:
WHEN invalid_number OR value_error THEN INSERT INTO problems (...)
Identificatorul WHEN OTHERS prinde toate exceptiile neincluse deja. Citeva
instrumente ORACLE ca SQL*Forms au exceptiile lor predefinite pe care le poti
genera pentru a produce evenimente. WHEN OTHERS le va prinde si pe acestea !
EXERCITII
1. Produceti un fisier SQL*Plus care accepta trei parametri (&1, &2,
&3) reprezentind numarul departamentului, numele departamentului si locatia.
Blocul PL/SQL din acest fisier trebuie sa produca o exceptie USER-DEFINED
daca nr. departamentului este 33 inregistrind un mesaj adecvat in MESSAGES.
Daca nu este 33 atunci numarul, numele si locatia trebuie sa fie inregistrate
ca un rind in tabelul NEWDEPT (care are aceleasi coloane ca DEPT).
Fisierul trebuie sa fie executabil in urmatorul mod:
@FILENAME 50 TRAINING BRACKNELLDaca aveti timp: 2. Produceti un bloc pentru a sterge toate rindurile din tabelul PROJECTS. Definiti o exceptie care sa prinda eroarea interna -2292 (Integrity violation), si includeti un identificator care trimite un mesaj tabelului MESSAGES daca aceasta exceptie apare.
DECLARE v_deptno NUMBER := &1; dept_33 EXCEPTION; BEGIN IF v_deptno=33 THENRAISE dept_33; END IF; INSERT INTO newdept (deptno, dname, loc) VALUES (&1, `&2`, `&3`); EXCEPTION WHWN dept_33 THEN INSERT INTO messages (charcoll) VALUES ('Attempt to create Department 33!'); END;2.
DECLARE integ_error EXCEPTION; PRAGMA EXCEPTION_INIT (integ_error, -2292); BEGIN DELETE FROM projects; EXCEPTION WHEN integ_error THEN INSERT INTO messages (charcol1) VALUES (`Integrity Error`); END;