Sunteți pe pagina 1din 10

Programarea in SGBD Oracle

1. Managementul datelor folosind cursoare.


Ce sunt cursoarele?
Cursoarele sunt structuri care permit utilizatorului sa denumeasca o zona privata de memoriecare
urmeaza sa pastreze o anumita instructiune, n vederea utilizarii ei ulterioare, n sistemul Oracle
exista doua tipuri de cursoare: implicite si explicite. Limbajul PL/sQL declara n mod implicit un
cursor pentru fiecare dintre instructiunile DML insert, delete si update. Cursoarele explicite sunt
declarate de utilizator si sunt folosite pentru 15115p1517p procesarea rezultatelor interogarii lor,
care returneaza linii multiple.
Numarul de linii returnate de o interogare poate fi zero, una sau mai multe, n functie de conditiile
de cautare ale interogarii. In Oracle, cursoarele sunt destinate procesarii linie cu linie a seturilor
de rezultate multi-linie. n lipsa cursoarelor, proiectantul de aplicatii Oracle ar trebui sa preia si sa
gestioneze n mod explicit fiecare linie selectata de interogare.
Liniile multiple returnate de o interogare se numesc setul activ. Limbajul PL/SQL defineste
dimensiunea acestuia ca reprezentnd numarul de linii care au ndeplinit criteriile de cautare si
au format setul activ. Figura 17.1 ilustreaza un cursor care contine linii multiple. Prin definitie,
fiecare cursor poseda un indicator care tine evidenta liniei curent accesate, ceea ce permite
programului dumneavoastra sa proceseze liniile, una cte una.

Figura 17.1.
Cursor multi-linie.

De ce se folosesc cursoarele?
Puteti sa va imaginati un cursor ca fiind un fisier care urmeaza sa fie procesat de la nceput pna
la sfrsit, nregistrare cu nregistrare. Cursoarele sunt folosite pentru a procesa linie cu linie seturi
de rezultate multi-linie. n plus, cursoarele tin evidenta liniei curent accesate, ceea ce permite
procesarea interactiva a setului activ.
Utilizarea mai multor cursoare simultan poate mbunatati performantele sistemului prin reducerea
frecventei interpretarii si deschiderii cursoarelor. Dupa fiecare parcurgere iterativa a cursorului,
acesta pastreaza suficiente informatii despre setul activ si instructiunile SQL nct poate fi reexecutat de mai multe ori. Fiecare noua iteratie este realizata fara sa fie necesara redeschiderea
si interpretarea cursorului.

Prin deschiderea mai multor cursoare, forma interpretata a instructiunilor SQL poate fi salvata,
eliminndu-se n acest fel neajunsurile legate de deschiderea si interpretarea repetata a
cursorului.
Cum se folosesc cursoarele
Limbajul SQL*Plus creeaza n mod implicit un cursor pentru fiecare instructiune DML executata.
Acest lucru survine indiferent daca interogarea returneaza una sau mai multe linii. Utilizatorii au
posibilitatea sa declare n mod explicit un cursor pentru procesarea linie cu linie a setului multilinie activ, n continuare, sunt prezentate etapele care trebuie parcurse pentru crearea si utilizarea
cursoarelor:
1.

Declararea cursorului

2.

Deschiderea cursorului

3.

Preluarea datelor n cursor

4.

nchiderea cursorului

Declararea cursoarelor explicite


Cursorul trebuie declarat nainte de a se face referire la el n instructiuni PL/SQL. Prin declararea
unui cursor se realizeaza urmatoarele:

Se denumeste cursorul

Se asociaza o interogare cursorului

Numele pe care l atribuiti unui cursor nu este o variabila PL/SQL ci un identificator nedeclarat.
Numele este folosit pentru a face referire la interogare. Nu puteti sa atribuiti valori numelui unui
cursor si nici sa-1 folositiJn expresii. Rezultatele interogarii cursorului devin setul activ al
cursorului, n exemplul urmator, este declarat un cursor numit c_articole:
declare
cursor c_articole IS
select * from lista_articole;
Nu exista o limita predefinita n legatura cu numarul maxim de cursoare care pot exista pe
parcursul unei sesiuni. Singura limitare a numarului de cursoare este data de memoria
disponibila pentru gestionarea lor. De asemenea, exista o limita a numarului de cursoare din
ntregul sistem per sesiune. Aceasta limita este data de valoarea parametrului open_cursor si
este stabilita de administratorul bazei de date.
Atunci cnd lucrati cu cursoare, puteti folosi parametri pentru a transfera cursorului diverse Valori
care sa le nlocuiasca pe cele prestabilite. Acesti parametri trebuie declarati odata cu cursorul.
Parametrii pot sa apara ntr-o interogare oriunde poate sa apara o constanta.

Exemplul urmator ilustreaza cursorul


c_articole si parametrul v_ cant_articol:
declare
cursor c_articole (v_ cant_articol NUMBER) IS select from lista_articole where cant_articol >
v_cant_articol;

Deschiderea cursoarelor explicite


Deschiderea cursoarelor explicite duce la executarea interogarii si la identificarea setului activ.
Setul activ contine toate liniile care ndeplinesc criteriile de cautare. Pentru cursoarele care sunt
declarate folosind clauza for update, programul Oracle blocheaza liniile care ndeplinesc criteriile
de cautare ale interogarii cursorului.
n instructiunea cursor open trebuie specificate valorile actuale pentru fiecare parametru specificat
n declaratia cursorului. In caz contrar, parametrii care apar n declaratia cursorului vor avea
valorile prestabilite.
ntr-o instructiune open, puteti asocia parametrii actuali, parametrilor formali ai unui
cursor,' folosind notatia pozitionala. Instructiunea urmatoare deschide cursorul c_articole:
open c_articole
Atunci cnd este executata comanda open, cursorul identifica numai acele linii care satisfac
interogarea. Practic, liniile nu sunt citite pna cnd nu se face preluarea cursorului. Cursorul este
initializat la prima linie a setului activ.

Atributele cursoarelor explicite


Fiecare cursor pe care l definiti are patru atribute. Prin accesarea acestor atribute pot fi obtinute
informatii utile despre cursor. Cele patru atribute ale cursoarelor sunt urmatoarele:
% is open

Acest atribut boolean are valoarea True n cazul n care cursorul este
deja deschis. Exemplul urmator verifica daca cursorul numit c_cursor
este deschis. Daca este deja deschis, este executata instructiunea
fetch. Daca este nchis, este executata comanda de deschidere a
cursorului.
Begin
if c_cursor%isopen then
fetch c_cursor into v_cant_comanda,
v_pret_comanda;
else
open c_cursor;
3

end if;
end;
%not found

Acest atribut boolean are valoarea True n cazul n care nu a fost


returnata nici o linie la cea mai recenta executare a instructiunii fetch.
ntruct instructiunea fetch va esua mai devreme sau mai trziu fara sa
fie generata nici o exceptie, acest atribut este folosit pentru a parasi
ciclul atunci cnd nu mai este nici o linie de procesat, ca n exemplul
urmator:
loop
fetch c_cursor into v_cant_comanda,
v_pret_comanda;
exit when c_cursor%not found;
end loop;
end;

% found

Acest atribut are valoarea True pna n momentul n care ultima


instructiune fetch nu preia nici o linie. Acest atribut este opusul logic al
atributului %not found. Dupa deschiderea cursorului si naintea primei
preluari cu instructiunea fetch, atributul %found are valoarea Nuli. Dupa
prima preluare, acest atribut va avea valoarea True pna n momentul
n care comanda fetch nu mai returneaza nici o linie. Acest exemplu
foloseste atributul % found pentru a controla executia comenzii insert:
begin
loop
fetch c_cursor into v_cant_comanda,
v_pret_comanda;
i~ c_cursor%found then
insert into lista_comenzi values
(v_cant_comanda, v_pret_comanda);
else
exit;
end if;
end loop;
end;

% rowcount

Acest atribut numeric este egal cu numarul total de linii returnate de


instructiunea f etch. Dupa deschiderea cursorului si naintea primei
preluari cu instructiunea f etch, acest atribut are valoarea zero. Dupa
prima executare a instructiunii f etch, el are valoare numarului total de
linii preluate pna n acel moment. Exemplul urmator foloseste atributul
& r owcount pentru a opri executia dupa procesarea primelor 100 de
linii:
begin
loop
fetch c_cursor into v_cant_comanda,
v_pret_comanda ;
exit when c__cursor%rowcount > 100;
end loop;
end;

Utilizarea cursoarelor explicite


Comanda fetch preia liniile din setul activ una cte una. Prima instructiune fetch sorteaza setul
activ, daca este necesar. Cursorul avanseaza la 'linia urmatoare a setului activ ori de cte ori este
executata o comanda fetch. Singura cale de a parcurge setul activ este prin intermediul comenzii
fetch. Pentru fiecare valoare a unei coloane returnata de interogarea cursorului, n lista trebuie
sa existe o variabila care sa-i corespunda. Exemplul urmator ilustreaza utilizarea comenzilor open
si f etch, precum si a atributului &notfound:
begin
open c_vizitatori
loop
fetch c_vizitatori into lista__vizitatori;
exit whe"n c_vizitatori%notfound;
end loop;
end;
n exemplul precedent, setul activ definit de cursorul c_vizitatori este procesat linie cu linie. Ciclul
iterativ de citire si procesare a liniilor individuale continua pna la procesarea tuturor liniilor din
setul activ.
Exemplul urmator este un script PL/SQL complet care utilizeaza un cursor pentru procesarea
datelor n mod individual, n acest exemplu, vor fi citite nregistrari continnd date referitoare la
vnzari, nregistrararile sunt procesate, iar datele sunt inserate n fisierul lista_comenzi.

Daca vreti sa consultati o linie preluata anterior, trebuie sa nchideti si sa redeschideti cursorul,
dupa care sa preluati liniile, una cte una. Daca vreti sa schimbati setul activ, trebuie sa atribuiti
noi valori variabilelor de intrare din interogarea cursorului si sa redeschideti cursorul. In acest fel,
este re-creat setul activ continnd rezultatele actualizate ale interogarii.
declare
v_cant_comanda number(7,2):=0;
v_pret_comanda number(7,2):=0;
total_cx>manda number(11,2):=0;
cursor c_comenzi is - declaratia cursorului
select cant, pret from lista_comenzi;
begin
open c_comenzi

deschiderea cursorului

loop
fetch c_comenzi into v_cant_comanda, v_pret_comanda;
exit when c_comenzi%notfound;
- calculeaza totalul comandat pe baza valorilor cursorului dupa care insereaza rezultatul n tabelul
s_comenzi
v_total_comanda = v_pret_comanda * v_cant_comanda; insert Tnto s_comenzi values
(v_total_comanda); end loop;
close c_comenzi;

- inchide cursorul

commit;

- salveaza rezultatele prelucrarii

end;
- programul se incheie
nchiderea cursoarelor explicite
Pentru a nchide un cursor, trebuie sa executati instructiunea close. Instructiunea urmatoare
nchide cursorul c_comenzi:
close c_comenzi;
Atunci cnd programul utilizatorului ncheie legatura cu serverul, acesta nchide n mod implicit
cursorul.
Cursoare implicite
Oracle creeaza si deschide n mod implicit un cursor pentru fiecare instructiune SQL care nu face
parte dintr-un cursor declarat n mod explicit. Cel mai recent cursor implicit poate fi considerat a
fi cursorul SQL. Comenzile open, close si fetch nu pot fi folosite n legatura cu cursoarele
6

implicite, n schimb, puteti folosi atributele cursoarelor pentru a obtine prin intermediul cursorului
SQL informatii despre cea mai recent executata instructiune SQL.
Atributele cursoarelor implicite
La
fel
ca
si
cursoarele
explicite,
cursoarele
implicite
au
patru
atribute: %isopen, %f ound, %rowcount si %notf ound. Puteti folosi aceste atribute n instructiuni
procedurale, nsa nu si n instructiuni SQL. Aceste atribute, prezentate n lista care urmeaza, va
permit sa accesati informatii n legatura cu cea mai recenta executie a uneia dintre comenzile
insert, select into, update si delete.
%isopen

ntr-un cursor implicit, acest atribut are ntotdeauna valoarea False.


Programul nchide automat cursoarele implicite dupa executarea
instructiunilor SQL asociate.

%notfound

Acest atribut boolean are valoarea True n cazul n care nu a fost


returnata nici o linie de catre instructiunea select into sau daca o
instructiune insert, update sau delete nu a afectat nici o linie.

%found

Pna n momentul executarii unei instructiuni SQL de manipulare a


datelor, acest atribut are valoarea Nuli. Daca o instructiune insert,
update sau delete afecteaza una sau mai multe linii, acesta ia valoarea
True. n caz contrar, atributul % f ound ia valoarea False.

%rowcount

Acest atribut returneaza numarul de linii afectate de o instructiune


insert, update sau delete sau numarul de linii returnate de o instructiune
select into. Atributul % rowcount returneaza zero daca instructiunea
SQL nu afecteaza sau nu returneaza nici o linie.

Valoarea atributelor cursorului se refera ntotdeauna la cea mai recent executata instructiune
SQL. Acest lucru este valabil indiferent unde apare instructiunea n program.
Cursoare de pachet
Sistemul Oracle permite stocarea specificatiei cursorului ntr-un pachet (package). n aceasta
specificatie, trebuie folosita clauza return. Aceasta abordare a cursoarelor va permite sa
modificati corpul cursorului fara sa schimbati specificatia acestuia. Exemplul urmator ilustreaza
un cursor de pachet numit clsal_ang:
create package ang_lunar as
cursor c_sal_ang return ang%rowtype;
end ang_lunar;
create package body ang_lunar as
cursor c_sal_ang return ang%rowtype;
select marca_ang, salariu__ang from lista_ang where
data_angajaFe > '01-JAN-1986'; END ang_lunar;

n specificatia cursorului nu apare instructiune select deoarece clauza return defineste tipul de
data al valorii rezultante. In exemplul precedent, este folosit atributul %rowtype n clauza return
pentru a furniza tipul de nregistrare care reprezinta o linie a bazei de date.
n corpul cursorului apare o instructiune select si aceeasi clauza return ca si n specificatia
cursorului.
Utilizarea ciclurilor for n interiorul cursoarelor
Ca scurtatura pentru preluarea liniilor ntr-un cursor, puteti folosi ciclul for. Ciclul for este parcurs
iterativ o data pentru fiecare linie returnata de interogare. Cursorul nsusi este cel care determina
momentul n care se paraseste ciclul for. Ciclul for simplifica codificarea prin efectuarea
urmatoarelor operatii:

La initierea ciclului, este executata n mod implicit o instructiune open

La fiecare parcurgere a ciclului este executata n mod implicit o instructiune fetch

La parasirea ciclului este executata n mod implicit o instructiune close

Urmatorul exemplu PL/SQL utilizeaza ciclul for pentru a acumula comenzile pentru fiecare linie
de produse:
accept comanda_prod prompt 'Introduceti numarul comenzii:'
declare
v_id_comanda s_articol_comanda%tip := p_comanda;
v_total_comanda number (11,2) :=0;
cursor c_cursor is

- declaratie cursor

select cod_art, pret, cant from lista_articole


where cod_comanda = v_id_comanda;
begin

- deschidere implicita

for inreg_comanda in c_cursor loop

- preluare implicita

v_total_comanda := v_total_comanda +
((inreg_comanda.cant * inreg_comanda.cant)*.95) ;
insert into lista__comenzi (cod_articol, total_comanda)
values (inreg_comanda.cod_articol, v__total_comanda);
end loop;

- nchidere implicita

commit;

- finalizarea tranzactiei

end;
Aliasurile cursoarelor

Cmpurile unui cursor implicit au aceleasi nume ca si cmpurile corespunzatoare din


instructiunea interogativa. Din aceasta cauza'apar probleme atunci cnd instructiunea
interogativa contine o expresie. De exemplu, cum veti face referire la numele coloanei n
urmatoarea interogare?
cursor is c_vanzari
select nr_agent_vanzari, (total_vanzari/12)*.015 from
lista_vanzari
n situatiile de acest gen, folositi un alias pentru a face referire la articolul (total^_vanzari/12) *.
015 al listei select, n exemplul urmator, este folosit acelasi cursor ca si n exemplul anterior, nsa
este declarat aliasul comision_vanzari:
cursor is c_vanzari
select nr_agent_vanzari, (total_vanzari/12)*.015
comision_vanzari
from lista^vanzari
Din acest moment, puteti face pur si simplu referire la aliasul comision_vanzari:
if comision_vanzari > 5000 then ...
Performantele cursoarelor
Viteza de executie a apelurilor din interiorul cursoarelor poate fi mbunatatita prin ajustarea
parametrului cursor_space_for time. Acest parametru precizeaza momentul n care o zona SQL
partajata poate f dealocata pentru a face loc unei noi instructiuni SQL. Valoarea prestabilita a
acestui parametru este False. Acest lucru nseamna ca Oracle poate dealoca o zona SQL
partajata din biblioteca cache chiar daca este deschis un cursor al unei aplicatii asociat cu
instructiunile acesteia. Valoarea True nseamna ca o zona SQL partajata poate fi dealocata numai
atunci cnd toate cursoarele aplicatiei asociate instructiunilor SQL ale acesteia sunt nchise.
Daca valoarea acestui parametru este False, programul Oracle trebuie sa consume timp si
resurse pentru a verifica daca zona SQL partajata care contine instructiunea SQL se gaseste n
biblioteca cache. Stabilirea parametrului la valoarea True face ca serverul' sa realizeze o mica
economie de timp si poate mbunatati performantele apelurilor de executie. Aceasta deoarece
programul Oracle nil trebuie sa verifice zona SQL partajata care nu poate fi dealocata att timp
ct un cursor al unei aplicatii este asociat cu ea.
Rezumat
Cursoarele sunt structuri PL/SQL care va permit sa procesati linie cu linie rezultatele unei
interogari multi-linie. Cursoarele implicite sunt create pentru fiecare instructiune DML, n timp ce
cursoarele explicite sunt create de utilizatori pentru procesarea interogarilor care returneaza linii
multiple.
Cursoarele permit utilizatorului sa proceseze linie cu linie rezultatele unei interogari multi-linie. De
asemenea, cursoarele mbunatatesc procesarea codului prin eliminarea interpretarii repetate a
9

acestuia. Mai mult, pentru executarea instructiunilor unui cursor trebuie sa l deschideti o singura
data, mbunatatindu-se astfel performantele serverului.
n acest capitol, au fost trecute n revista cele patru etape necesare pentru utilizarea corecta a
cursoarelor. Acestea sunt: declararea cursorului, deschiderea cursorului, preluarea datelor si
nchiderea cursorului.
De asemenea, ati aflat care este diferenta dintre cursoarele implicite si cele explicite si ati vazut
cteva aplicatii practice ale ambelor.

10

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