Sunteți pe pagina 1din 12

Facultatea de Cibernetică, Statistică şi Informatică Economică

SGBD Oracle, opțional – seminarul 4

CURSORUL ÎN PL/SQL

 Atunci când se execută o comandă SQL, Oracle Server deschide o zonă de memorie (context
area) în care comanda este executată. Cursorul este un pointer către această zonă.
 În PL/SQL se utilizează două tipuri de cursoare:
 implicit: declarat pentru toate instrucţiunile PL/SQL de tip LMD
 explicit: declarat şi gestionat de programator.

CURSORUL IMPLICIT
 Este declarat de PL/SQL implicit pentru toate comenzile de manipulare a datelor (INSERT,
UPDATE, DELETE, SELECT);
 Dacă o instrucțiune LMD nu afectează nicio linie a tabelei, NU se generează automat o
excepție;
 Atributele cursorului implicit:
 SQL%ROWCOUNT
 SQL%FOUND
 SQL%NOTFOUND
 SQL%ISOPEN este mereu FALSE
 Atributele se referă la cea mai recentă instrucțiune LMD. Înaintea primei instrucțiuni LMD
din bloc, toate atributele au valoarea NULL;
 După o instrucțiune COMMIT sau ROLLBACK, SQL%ROWCOUNT are valoarea 0.

Atenție - Cursorul implicit NU este util pentru instrucțiunea SELECT folosită cu INTO. Aceasta
va rula cu succes doar dacă interogarea returnează un singur rând și atunci SQL%ROWCOUNT
va fi 1, SQL%FOUND va fi TRUE iar SQL%NOTFOUND va fi FALSE. Dacă interogarea nu
returnează niciun rând sau returnează două sau mai multe, se va ridica o excepție
(NO_DATA_FOUND sau TOO_MANY_ROWS – vezi seminarul 4).

Rulează următorul bloc PL/SQL!


Se șterg produsele din categoria hardware3 care nu au fost comandate. Se afișează numărul de
rânduri şterse.

SET SERVEROUTPUT ON
BEGIN
DELETE FROM produse
WHERE categorie='hardware3' AND
id_produs NOT IN (SELECT id_produs FROM rand_comenzi);
DBMS_OUTPUT.PUT_LINE (SQL%ROWCOUNT || ' randuri sterse');
ROLLBACK;
DBMS_OUTPUT.PUT_LINE (SQL%ROWCOUNT || ' randuri afectate');
END;
/
După ROLLBACK, atributul SQL%ROWCOUNT devine 0. Rezultatul rulării este:

10 randuri sterse
0 randuri afectate
1
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle, opțional – seminarul 4

Rulează următorul bloc PL/SQL!


Se încearcă adăugarea unei regiuni și apoi modificarea denumirii produsului având codul 3. În
cazul în care acest produs nu există (comanda UPDATE nu realizează nicio modificare) va fi
afişat un mesaj corespunzător.
BEGIN
INSERT INTO regiuni VALUES(5,'Oceania');
UPDATE produse
SET pret_lista = pret_lista + 100
WHERE categorie = 'hardware4';
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('Nu exista produse in aceasta categorie');
ELSE
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' produse modificate');
END IF;
ROLLBACK;
END;
/
Explică la care dintre comenzile SQL din cadrul blocului se referă atributul SQL
%NOTFOUND ? INSERT sau UPDATE?

CURSORUL EXPLICIT
 se foloseşte pentru a procesa individual fiecare linie (înregistrare) returnată de o instrucţiune
SELECT ce returnează mai multe înregistrări.
 mulţimea înregistrărilor returnate de o instructiune SELECT este numită mulţime rezultat.
 cursorul păstrează un pointer către linia curentă în cadrul unei mulţimi rezultat.
Verificarea stării unui cursor explicit se realizează prin intermediul următoarelor atribute:
 NUME_CURSOR%ISOPEN - evaluat la TRUE în cazul în care cursorul este
deschis;
 NUME_CURSOR%NOTFOUND - evaluat la TRUE în cazul în care cel mai
recent FETCH nu a returnat nici o linie;
 NUME_CURSOR%FOUND - complementul lui %NOTFOUND;
 NUME_CURSOR%ROWCOUNT - are ca valoare numărul liniilor returnate
până în momentul curent.

PARCURGEREA FOLOSIND OPEN-LOOP-FETCH-CLOSE


In această abordare, prelucrarea cursorului explicit presupune parcurgerea următoarelor etape:
 se declară variabilele în care vor fi încărcate valorile corespunzătoare unei linii din
cursor;
 se declară cursorul explicit, specificându-se un nume pentru acesta şi definindu-se
interogarea de procesat în cadrul lui:
DECLARE nume_cursor IS SELECT........................;
 se deschide cursorul prin intermediul instrucţiunii OPEN, care execută interogarea şi
legarea tuturor variabilelor referite. Înregistrările returnate de interogare sunt
desemnate drept set activ de date, care pot fi de acum încărcate.
OPEN nume_cursor;
 utilizându-se instrucţiunea FETCH, se încarcă linia curentă din cursor în variabile.
Fiecare încărcare determină mutarea pointerului cursorului la linia următoare din
setul activ de date.
2
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle, opțional – seminarul 4

FETCH nume_cursor INTO var1, var2,..............;


 este închis cursorul prin instrucțiunea CLOSE, care dezafectează setul activ de linii.
Cursorul poate fi din nou deschis pentru a stabili un nou set activ de linii.
CLOSE nume_cursor;
Pentru a procesa liniile unui cursor explicit se defineşte de obicei o buclă pentru
executarea unui FETCH în fiecare iteraţie. În final, toate liniile din setul activ sunt procesate şi
un FETCH executat fără succes poziţionează atributul %NOTFOUND pe TRUE.
Înaintea primului FETCH, %NOTFOUND se evaluează la NULL, ca şi în cazul în care
FETCH nu se execută niciodată cu succes.

Rulează următorul bloc PL/SQL!


Să se afişeze lista cu numele şi salariul angajaţilor din departamentul 60 folosind un cursor
explicit și trei variabile scalare:
DECLARE
CURSOR ang_cursor IS SELECT id_angajat, nume, salariul
FROM angajati WHERE id_departament=60;
ang_id angajati.id_angajat%TYPE;
ang_nume angajati.nume%TYPE;
ang_sal angajati.salariul%TYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE('Lista cu salariariile angajatilor din departamentul 60');
OPEN ang_cursor;
LOOP
FETCH ang_cursor INTO ang_id, ang_nume, ang_sal;
EXIT WHEN ang_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Salariatul '||ang_nume||' are salariul: '||ang_sal);
END LOOP;
CLOSE ang_cursor;
END;
/
Pentru o flexibilitate mai mare se poate utiliza o variabilă de tip înregistrare (record) pentru
încărcarea valorilor din cursor. Această variabilă de tip record poate avea aceleaşi atribute ca şi
cursorul prin specificarea proprietăţii %ROWTYPE. În acest caz încărcarea din cursor se va face
direct prin instrucţiunea fech var_cursor into var_record.

Rulează următorul bloc PL/SQL!


DECLARE
CURSOR ang_cursor IS SELECT id_angajat, nume, salariul
FROM angajati WHERE id_departament=60;
--tipul record definit cu %ROWTYPE pt incarcarea valorilor cursorului
ang_rec ang_cursor%ROWTYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE('Lista cu salariariile angajatilor din departamentul 60');
OPEN ang_cursor;
LOOP
FETCH ang_cursor INTO ang_rec;
EXIT WHEN ang_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(ang_rec.nume||' are salariul: '||ang_rec.salariul);
END LOOP;
CLOSE ang_cursor;

3
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle, opțional – seminarul 4

END;

Rulează următorul bloc PL/SQL!


Să se afișeze primii 5 angajaţi (id şi nume)

DECLARE
v_id angajati.id_angajat%type;
v_nume angajati.nume%type;
CURSOR c1 IS SELECT id_angajat, nume FROM angajati;

BEGIN
OPEN c1;
FOR i IN 1..5 LOOP
FETCH c1 INTO v_id, v_nume;
DBMS_OUTPUT.PUT_LINE('Salariatul '||v_id||' are numele: '||v_nume);
END LOOP;
CLOSE c1;
END;
/

Rulează următorul bloc PL/SQL!


Testul de ieşire din buclă în acest caz se poate face şi cu ajutorul atributului %ROWCOUNT.

DECLARE
v_id angajati.id_angajat%type;
v_nume angajati.nume%type;
CURSOR c1 IS SELECT id_angajat, nume FROM angajati;

BEGIN
OPEN c1;
LOOP
FETCH c1 INTO v_id, v_nume;
EXIT WHEN c1%ROWCOUNT>5 OR c1%NOTFOUND;
INSERT INTO mesaje VALUES (v_id, v_nume);
END LOOP;
CLOSE c1;
END;
/

PARCURGEREA FOLOSIND FOR-LOOP


In această abordare, prelucrarea cursorului explicit presupune parcurgerea următoarelor etape:
 se declară cursorul explicit, specificându-se un nume pentru acesta şi definindu-se
interogarea de procesat în cadrul lui:
DECLARE nume_cursor IS SELECT........................;
 în cadrul secțiunii executabile, se parcurge cursorul prin structura FOR-LOOP,
încărcându-se astfel datele din cursor într-o variabilă de tip record definită automat:
FOR nume_var_record IN nume_cursor LOOP
................
END LOOP;

4
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle, opțional – seminarul 4

În acest caz, tipul record nu trebuie declarat. Se realizează în mod implicit deschiderea,
încărcarea și închiderea cursorului.

Rulează următorul bloc PL/SQL!


Să se afişeze printr-un ciclu FOR numele şi salariile angajaţilor din departamentul 60:

DECLARE
CURSOR ang_cursor IS SELECT id_angajat, nume, salariul
FROM angajati WHERE id_departament=60;
BEGIN
DBMS_OUTPUT.PUT_LINE('Lista cu salariariile angajatilor din departamentul 60');
FOR ang_rec IN ang_cursor LOOP
DBMS_OUTPUT.PUT_LINE('Salariatul '||ang_rec.nume||' are salariul: '||
ang_rec.salariul);
END LOOP;
END;
/

Rulează următorul bloc PL/SQL!


Să se afişeze primele 3 comenzi care au cele mai multe produse comandate.
În acest caz înregistrările vor fi ordonate descrescător în funcţie de numărul produselor
comandate.

DECLARE
CURSOR c_com IS SELECT c.nr_comanda, c.data, COUNT(r.id_produs) numar
FROM comenzi c, rand_comenzi r
WHERE c.nr_comanda=r.nr_comanda
GROUP BY c.nr_comanda, c.data
ORDER BY COUNT(r.id_produs) DESC;
BEGIN
DBMS_OUTPUT.PUT_LINE('Numarul de produse pentru fiecare comanda:');
FOR rec_com IN c_com LOOP
EXIT WHEN c_com%ROWCOUNT>3;
DBMS_OUTPUT.PUT_LINE('Comanda '||rec_com.nr_comanda||' data pe '||
rec_com.data||' are: '||rec_com.numar||' produse');
END LOOP;
END;
/

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. Apariția 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ă și poate fi specificată o rutină de tratare a acesteia. Atenție: a nu se confunda o excepție
cu o eroare de sintaxă. Erorile de sintaxă nu pot fi captate și tratate în partea de EXCEPTION.
O excepție poate fi invocată (ridicată) în doua moduri:
5
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle, opțional – seminarul 4

a. Apare o eroare Oracle și excepția asociată ei este implicit invocată;


b. Excepţia poate fi invocată în mod explicit prin instrucțiunea RAISE în 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 Mod de manipulare


Excepţii pre-definite asociate erorilor care apar cel Nu trebuie declarate, serverul Oracle le
mai frecvent în blocurile PL/SQL (de exemplu invocă în mod automat, dar trebuie
NO_DATA_ FOUND, TOO_MANY_ROWS, tratate în secţiune EXCEPTION.
INVALID_CURSOR,
ZERO_DIVIDE)
Excepţii non-predefine recunoscute de Oracle dar Trebuie declarate în secţiunea
tratate de utilizator cu ajutorul codului de eroare declarativă. Serverul Oracle le invocă în
returnat (de exemplu ORA- 01400). 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
statement1 ;
statement2 ;
…]
[WHEN OTHERS THEN
statement1 ;
statement2 ;
…]

1. Tratarea excepţiilor predefinite ale Serverului Oracle

6
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle, opțional – seminarul 4

Acestea nu trebuie declarate, fiind definite de către Oracle Server si invocate implicit. Lista
completă a excepţiilor predefinite Oracle va fi consultată din PL/SQL Reference, capitolul 10,
pagina 10-4 (http://bd.ase.ro/uploads/sgbd_activitate/PL_Reference.pdf ) cât și la finalul acestui
seminar. Câteva exemple de excepţii predefinite sunt prezentate mai jos:

Numele Numărul erorii Descriere


NO_DATA_FOUND ORA-01403 O instrucţiune SELECT care ar fi trebuit sa întoarcă
o singura linie nu a returnat nici o linie.
TOO_MANY_ROWS ORA-01422 O instrucţiune SELECT care ar fi trebuit sa întoarcă
o singura linie a returnat mai multe linii.
INVALID_CURSOR ORA-01001 Apariţia unei operaţii ilegale asupra unui cursor (de
şi respectiv exemplu încercarea de a deschide un cursor deja
CURSOR_ALREADY_ ORA-06511 deschis sau a închide unul deja închis).
OPEN

Exemple:
Să se afişeze angajatul cu codul 10. Să se trateze eroarea apărută în cazul în care nu există nici
un angajat cu acest cod.
SET SERVEROUTPUT ON

DECLARE
v_nume VARCHAR2(20);

BEGIN
SELECT nume INTO v_nume
FROM angajati
WHERE id_angajat=10;
dbms_output.put_line(v_nume);

EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Nu exista angajatul cu acest ID!');

END;
/
Să se afişeze salariul angajatului cu prenumele John. 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).

SET SERVEROUTPUT ON
DECLARE
sal angajati.salariul%type;
BEGIN
select salariul into sal from angajati where prenume='John';
DBMS_OUTPUT.PUT_LINE('John are salariul de: '||sal);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Exista mai multi salariati cu numele John! Utilizati un
cursor pentru selectie!');
7
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle, opțional – seminarul 4

END;
/

2. 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. In PL/SQL,
directiva EXCEPTION_INIT determină compilatorul sa asocieze un nume de excepţie unui
număr (cod) de eroare standard a Serverului Oracle. Aceasta permite referirea erorii standard
prin nume şi scrierea unei rutine de tratare a ei.
Tratarea acestor erori se realizează in 3 paşi:
1) Declararea excepţiei: se face în zona DECLARE a blocului
NUME_EXCEPTIE EXCEPTION;
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, COD_EROARE);
Unde COD_EROARE este un cod de eroare standard Oracle;
3) Tratarea excepţiei în zona EXCEPTION a blocului:
EXCEPTION
WHEN NUME_EXCEPTIE THEN .........;

Se pot utiliza 2 atribute pentru a gestiona erorile apărute:


SQLCODE – returnează codul numeric al erorii. Poate avea următoarele valori:
 0 – nu a apărut nici o excepţie;
 1 – este o excepție declanșată de utilizator căreia nu i s-a asociat alt cod
folosind PRAGMA EXCEPTION_INIT;
 +100 – excepţia NO_DATA_FOUND;
 un număr negativ – o eroare Oracle Server;
SQLERRM – returnează mesajul asociat erorii.
Aceste atribute pot fi încărcate în variabile și adăugate într-o tabelă de erori pentru vizualizare şi
verificare ulterioară.

Exemplu:
Să se insereze în tabela departamente un nou departament cu ID-ul 200, fără a preciza denumirea
acestuia. În acest caz va apare o eroarea cu codul ORA-01400 prin care programatorul este
avertizat de încălcarea unei restricţii de integritate. Această excepţie poate fi tratată astfel:
SET SERVEROUTPUT ON
DECLARE
-- se asociază un nume codului de eroare apărut
INSERT_EXCEPT EXCEPTION;
PRAGMA EXCEPTION_INIT(INSERT_EXCEPT, -01400);
BEGIN
insert into departments (department_id, department_name) values (200, NULL);
EXCEPTION
--se tratează eroarea prin numele său
WHEN insert_except THEN
DBMS_OUTPUT.PUT_LINE('Nu ati precizat informatii suficiente pentru
departament');
--se afişează mesajul erorii
DBMS_OUTPUT.PUT_LINE(SQLERRM);
8
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle, opțional – seminarul 4

END;
/

Să se şteargă toate înregistrările din tabela PRODUSE. Acest lucru va duce la apariţia erorii cu
codul –2292, reprezentând încălcarea restricţiei referenţiale. Valorile SQLCODE şi SQLERRM
vor fi inserate în tabela ERORI. ATENTIE! Aceste variabile nu se pot utiliza direct într-o
comandă SQL (cum ar fi SELECT, INSERT, UPDATE sau DELETE), drept pentru care vor fi
încărcate mai întâi in variabilele PL/SQL COD și MESAJ și apoi utilizate în instrucţiuni SQL.

CREATE TABLE erori


(utilizator VARCHAR2(40),
data DATE,
cod_eroare NUMBER(10),
mesaj_eroare VARCHAR2(255)
);

DECLARE
cod NUMBER;
mesaj VARCHAR2(255);
del_exception EXCEPTION;
PRAGMA EXCEPTION_INIT(del_exception, -2292);

BEGIN
DELETE FROM produse;

EXCEPTION
WHEN del_exception THEN
dbms_output.put_line('Nu puteti sterge produsul');
dbms_output.put_line('Exista comenzi asignate lui');
cod:=SQLCODE;
mesaj:=SQLERRM;
INSERT INTO erori VALUES(USER, SYSDATE, cod, mesaj);

END;
/
SELECT * FROM erori;

3. Tratarea excepţiilor definite de utilizator

In PL/SQL se pot defini excepții de către utilizator. Ele pot fi declarate în secțiunea
declarativa a blocului şi invocate explicit prin instrucțiunea RAISE sau
RAISE_APPLICATION_ERROR.

Etape:
1. Se declara excepţia în secţiunea declarativă:
nume_exceptie EXCEPTION;

9
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle, opțional – seminarul 4

2. Prin instrucţiunea RAISE se invocă în mod explicit, în cadrul secţiunii executabile:


RAISE nume_exceptie;
3. Dacă este necesar, se tratează în rutina corespunzătoare din secţiunea de tratare a
excepţiilor:
WHEN nume_exceptie THEN......

Exemple:
Să se invoce o excepție în cazul în care utilizatorul încearcă să execute blocul PL/SQL după ora
17.
SET SERVEROUTPUT ON
DECLARE
e_exc1 EXCEPTION;

BEGIN
IF TO_NUMBER(TO_CHAR(SYSDATE, 'HH24'))>=17 THEN
RAISE e_exc1;
END IF;

EXCEPTION
WHEN e_exc1 THEN
dbms_output.put_line('Este ora '||TO_CHAR(SYSDATE, 'HH24'));
dbms_output.put_line('Operatiune permisa doar '||' in timpul programului');
END;
/

Să se modifice denumirea produsului cu id-ul 3. Dacă nu se produce nici o actualizare (valoarea


atributului SQL%ROWCOUNT este 0) sau dacă apare o altă excepție (clauza OTHERS) atunci
să se declanşeze o excepţie prin care să fie avertizat utilizatorul:

DECLARE
invalid_prod EXCEPTION;

BEGIN
UPDATE produse
SET denumire_produs='Laptop ABC'
WHERE id_produs=3;

IF SQL%NOTFOUND THEN
RAISE invalid_prod;
END IF;

EXCEPTION
WHEN invalid_prod THEN
DBMS_OUTPUT.PUT_LINE('Nu exista produsul cu acest ID');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('A aparut o eroare! Nu se poate actualiza denumirea
produsului!');
END;
/

10
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle, opțional – seminarul 4

Putem invoca în mod explicit și excepții pre-definite. In exemplul următor este invocată excepția
NO_DATA_FOUND:

DECLARE
invalid_prod EXCEPTION;

BEGIN
UPDATE produse
SET denumire_produs='Laptop ABC'
WHERE id_produs=3;

IF SQL%NOTFOUND THEN
RAISE NO_DATA_FOUND;
END IF;

EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/

Clauza OTHERS este similară clauzei ELSE dintr-o instrucțiune CASE. Se folosește mereu
ultima în partea EXCEPTIONS a unui bloc PL/SQL și captează toate excepțiile, fie ele
predefinite, non-predefinite sau definite de utilizator care nu sunt explicit tratate anterior.

Propagarea excepţiilor

O dată excepția declanșată în secţiunea executabilă a unui bloc, se caută în cadrul


secţiunii de tratare a excepţiilor (EXCEPTION) o rutină de tratare asociată. Daca rutina este
găsită, excepția 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.
Atunci când un sub-bloc tratează o excepţie, se termină normal iar execuţia se reia în
blocul ce-l cuprinde imediat după instrucţiunea END a sub-blocului.
Daca apare o excepţie iar în blocul curent nu există o rutină pentru tratarea sa, execuţia
blocului se termina cu eşec, iar excepţia se propagă succesiv în blocurile exterioare până este
găsită într-unul din ele o rutină pentru tratarea ei. Daca nu se găseşte nici una, în mediul apelant
apare o situaţie de excepţie nerezolvată, utilizator putând observa mesajul de eroare care a
întrerupt execuţia normală.

Exemple de exceptii predefinite:


 no_data_found—Single row SELECT returned no data.
 too_many_rows—Single row SELECT returned more than one row.
 invalid_cursor—Illegal cursor operation was attempted.
 value_error—Arithmetic, conversion, truncation, or constraint error occurred.
 invalid_number—Conversion of a number to a character string failed.
 zero_divide—Attempted to divide by zero.
 dup_val_on_index—Attempted to insert a duplicate value into a column that has a
unique index.

11
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle, opțional – seminarul 4

 cursor_already_open—Attempted to open a cursor that was previously opened.


 not_logged_on—A database call was made without being logged into Oracle.
 transaction_backed_out—Usually raised when a remote portion of a transaction is
rolled back.
 login_denied—Login to Oracle failed because of invalid username and password.
 program_error—Raised if PL/SQL encounters an internal problem.
 storage_error—Raised if PL/SQL runs out of memory or if memory is corrupted.
 timeout_on_resource—Timeout occurred while Oracle was waiting for a resource.
 value_error—Arithmetic, conversion, truncation, or constraint error occurred.
 others—This is a catchall. If the error was not trapped in the previous exception traps,
the error will be trapped by this statement

TEMĂ
Comenzile se vor testa în SQL Developer și apoi vor fi salvate într-un fișier Word, alături de
capturi de ecran justificative (care să evidențieze rezultatele blocurilor):
Folosind tabelele bazei de date de la proiect, să se creeze 4 blocuri PL/SQL care să utilizeze
cursori și excepții (de toate tipurile)

12

S-ar putea să vă placă și