Sunteți pe pagina 1din 12

Facultatea de Cibernetic, Statistic i Informatic Economic

SGBD Oracle, an II, IDD seminar


Subprograme PL/SQL
Blocuri PL/SQL care au nume
Pot fi proceduri /functii
Se pot stoca la nivel de Oracle Server (proceduri/functii stocate) sau de aplicatie (Developer
Suite)
Se pot grupa in pachete de programe (PACA!")
#aria$ilele declarate in %ona declarativa a procedurii se numesc parametri formali (formal
parameters)& Pentru acestia se pot specifica valori implicite (D"'A(L))
#aria$ilele utili%ate in apelul procedurii/functiei se numesc parametri actuali (actual
parameters)
C*nd procedura/functia e apelata+ varia$ilele din procedura sunt incarcate cu valorile
varia$ilelor definite in %ona declarativa a $locului anonim
,n corpul procedurilor/functiilor nu se pot utili%a varia$ile glo$ale sau de su$stitutie+ acestea
vor fi transmise in su$programe cu a-utorul parametrilor
Pentru afisarea erorilor aparute la compilare se utili%ea%a S.O/ "00O0S
1 P!"CE#$!I
Parametrii utili%ati in procedura (parametri formali) pot fi de tip1
I% (valoarea parametrului actual este transferata in varia$ila definita in procedura&
Aceasta varia$ila este considerata read2onl3)& C*nd procedura se 4ncheie+ controlul
revine mediului apelant& Parametrul actual nu se modifica& "ste modul implicit&
"$& (valoarea parametrului formal este transferata in parametrul actual c*nd
procedura se incheie)
I% "$& (valorile sunt transferate de la un tip de varia$il5 la cel5lalt (la lansarea 4n
e6ecu7ie/terminarea procedurii))
un parametru ,8 poate apare numai 4n partea dreapta a (19)
un parametru O() poate apare numai 4n partea st*nga a (19)
un parametru ,8 O() poate apare 4n am$ele p5r7i ale (19)
Sinta'a pentru crearea unei proceduri(
C!E)&E *"! !EPL)CE+ P!"CE#$!E %$,E-P!"C
*.param1 *I%/"$&/I% "$&+ &IP1,
Param0*I%/"$&/I% "$&+ &IP0, 1 +
22 tipul varia$ilelor este preci%at fara dimensiune (e61 8(:B"0 sau #A0C.A0;)
IS/)S
22 %ona de declarare a varia$ilelor utili%ate in su$program
22 8( se utili%ea%a D"CLA0"
2E3I%
4444
*E5CEP&I"%+
444444
E%# *%$,E-P!"C+6
Pentru a sterge procedura(
#!"P P!"CE#$!E %$,E-P!"C6
<
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle, an II, IDD seminar
)pelul unei proceduri se poate reali7a in urmatoarele moduri(
prin nume dintr2un $loc PL/SQL anonim sau un alt su$program=
prin apel direct cu E5EC$&E nume-proc sau E5EC nume-proc sau C)LL nume-proc=
din alt mediu Oracle (Oracle Developer Suite)
E'emple(
44 adauga o inregistrare noua in tabela Produse
S") S"0#"0O()P() O8
22 crearea procedurii1
C0"A)" O0 0"PLAC" P0OC"D(0" adauga>produs
(p>codp produse&codprodus?t3pe+
p>denp produse&denprodus?t3pe+
p>um produse&um?t3pe+
p>stoc produse&stoc?t3pe)
,S
B"!,8
insert into produse values (p>codp+ p>denp+ p>um+ p>stoc)=
e6ception
@hen dup>val>on>inde6 then
d$ms>output&put>line(AProdus e6istentBA)=
"8D=
/
S.O/ "00O0S
22 apelul procedurii prin $loc PL/SQL anonim1
$egin
adauga>produs(<CC+ AcafeaA+ <<+ <C)=
end=
/
22 apelul direct1
call adauga>produs(<CC+ AcafeaA+ <<+ <C)=
44 mareste stocul unui produs specificat cu un procent dat. Daca produsul nu exista, se va
invoca o exceptie
S") S"0#"0O()P() O8
22 crearea procedurii1
C0"A)" or 0"PLAC" P0OC"D(0" mareste-stoc
(codp ,8 produse&codprodus?t3pe+ procent ,8 num$er)
,S
v>stoc produse&stoc?t3pe=
produs>invalid "DC"P),O8=
B"!,8
(pdate produse
Set stoc9stocE(<Fprocent/<CC)
;
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle, an II, IDD seminar
/here codprodus9codp=
if SQL?notfound then
raise produs>invalid=
end if=
d$ms>output&put>line(AS2au modificat AGGSQL?ro@countGGA inregistrariA)=
e6ception
@hen produs>invalid then d$ms>output&put>line(A8u e6ista produsul cu codul AGGcodp)=
"8D=
/
22 apelul direct1
call mareste>stoc(<<<+ <C)=
22verificare e6ecutie
select E from produse @here codprodus 9<<<=
Stergerea unei proceduri se reali%ea%a prin comanda1
#!"P P!"CE#$!E nume-procedura6
#i%uali%area procedurilor in dictionarul metadatelor se reali%ea%a prin1
Select ob8ect-name
From user-ob8ects
9:ere ob8ect-t;pe<=P!"CE#$!E=6
,ar pentru a vi%uali%a corpul procedurii1
Select te't
From user-source
9:ere name<=%$,E-P!"C= and t;pe<=P!"CE#$!E=6
E'emplu(
Select te6t
'rom user>source
/here name9A:A0"S)">S)OCA and t3pe9AP0OC"D(0"A=
H
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle, an II, IDD seminar
0 F$%C>II(
Sinta'a pentru crearea unei functii(
C!E)&E *"! !EPL)CE+ F$%C&I"% nume-functie
*.param1 *I%+ &IP1,
Param0*I%+ &IP0, 1 +
!E&$!% &IP-#)&)
22 tipul varia$ilelor este preci%at fara dimensiune (e61 8(:B"0 sau #A0C.A0;)
IS/)S
22 %ona de declarare a varia$ilelor utili%ate in su$program
22 nu se utili%ea%a D"CLA0"
2E3I%
4444
!E&$!% ?)L")!E6
*E5CEP&I"%+
444444
E%# *%$,E-F$%C&IE+6
Pentru @i7uali7area tipului returnat se utili7ea7a(
#ESC!I2E nume-functie6
Pentru a sterge functia(
#!"P F$%C&I"% nume-functie6
E'emplu(
-- afiseaza denumirea unui produs al carui cod este precizat drept parametru:
C0"A)" O0 0"PLAC" '(8C),O8 afisea7a-denumire
(p>codp produse&codprodus?t3pe)
0")(08 varchar;
,S
v>denp produse&denprodus?t3pe=
B"!,8
select denprodus into v>denp
from produse
@here codprodus9p>codp=
return v>denp=
"DC"P),O8
@hen no>data>found then
d$ms>output&put>line(A8u e6ista produsul cu codul specificatBA)=
@hen too>man3>ro@s then
d$ms>output&put>line(APrea multe produse cu acest codBA)=
"8D=
/
sho@ errors=
-- vizualizarea tipului returnat:
descri$e afisea7a-denumire=
I
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle, an II, IDD seminar
-- apelul functiei:
declare
v>nume varchar;(;C)=
$egin
v>nume19 afisea7a-denumire.1111=
d$ms>output&put>line(v>nume)=
end=
$tili7area functiilor PL/SQL in e'presii SQL
C0"A)" O0 0"PLAC" '(8C),O8 t@a (valoare ,8 8(:B"0)
0")(08 8(:B"0
,S
B"!,8
0")(08 (valoareEC&<J)=
"8D=
/
--apelul funciei
S"L"C) codprodus+ cant E pret as valoare+ t@a (cant E pret) as tva
'0O: rindcom=
"bser@atiiA
'unctiile utili%ate in e6presii SQL tre$uie sa accepte doar parametrii de tip ,8 si sa returne%e
numai tipuri de date specifice PL/SQL&
'unctiile nu tre$uie sa contina comen%i D:L (update+ delete+ insert) sau comen%i DDL si nici
comen%i pentru controlul tran%actiilor (commit+ roll$acK) si nici nu tre$uie sa apele%e alte
su$programe care sa incalce aceste restrictii&
'unctiile apelate in cadrul e6presiilor SQL pot fi continute in pachete&
Stergerea unei functii se reali%ea%a utili%and comanda1
#!"P F$%C&I"% nume-functie6
#i%uali%area functiilor in dictionarul metadatelor se reali%ea%a prin1
Select ob8ect-name
From user-ob8ects
9:ere ob8ect-t;pe<=F$%C&I"%=6
,ar pentru a vi%uali%a corpul functiei1
Select te't
From user-source
9:ere name<=%$,E-F$%C&IE= and t;pe<= F$%C&I"% =
"!#E! 2B line6
E'emplu(
Select te6t
'rom user>source
/here name9A)ADA and t3pe9A'(8C),O8A
O0D"0 BL line=
M
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle, an II, IDD seminar
Pac:ete de subprograme
!rupea%a varia$ile+ su$programe+ tipuri de date PL/SQL care sunt corelate logic&
Sunt formate din ; parti1
2 specificatia pac:etului N %ona pu$lica
2 corpul pac:etului N %ona privata
Specificatia pac:etului(
C!E)&E *"! !EPL)CE+ P)CC)3E nume-pac:et
IS/)S
22declaratii de varia$ile si tipuri pu$lice+ sunt initiali%ate cu 8(LL implicit
22specificatii ale su$programelor pu$lice
E%# *nume-pac:et+6
Corpul pac:etului(
C!E)&E *"! !EPL)CE+ P)CC)3E 2"#B nume-pac:et
IS/)S
22declaratii de varia$ile si tipuri private
22definitii ale su$programelor pu$lice si private
*2E3I%
22 "ste optional si se e6ecuta o singura data la primul apel si la incarcarea pachetului in memorie
E%# *nume-pac:et+6
"bser@atie1 ,n cadrul pachetelor pentru a utili%a o functie/procedura in cadrul unui su$program+
aceasta tre$uie declarata inainte (principiul for@ard declarations)=
,n %ona de specificatii a pachetului se pot declara1
proceduri=
func7ii=
varia$ile=
cursoare=
e6cep7ii&
Corpul pachetului defineste complet procedurile+ functiile si cursoarele&
Supraincarcarea subprogramelor
Se poate reali%a numai pentru functii/proceduri din cadrul pachetelor+ nu si pentru su$programe
singulare (stocate direct in $a%a de date)=
8u se pot supraincarca ; su$programe care au paramentrii de tipuri asemanatoare (e61
8(:B"0 si D"C,:AL sau #A0C.A0; si #A0C.A0)=
E'emplu(
C!E)&E "! !EPL)CE P)CC)3E actuali7are-produse IS
procedure adauga>produs
(p>codp produse&codprodus?t3pe+
p>denp produse&denprodus?t3pe+
p>um produse&um?t3pe+
O
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle, an II, IDD seminar
p>stoc produse&stoc?t3pe)=
procedure modifica>produs
(p>codp produse&codprodus?t3pe+
p>denp produse&denprodus?t3pe+
p>um produse&um?t3pe+
p>stoc produse&stoc?t3pe)=
procedure modifica>produs
(p>codp produse&codprodus?t3pe+
p>stoc produse&stoc?t3pe)=
procedure sterge>produs
(p>codp produse&codprodus?t3pe)=
function e6ista>cod
(p>codp produse&codprodus?t3pe)
return $oolean=
e6ceptie e6ception=
E%#6
/
C!E)&E "! !EPL)CE P)CC)3E 2"#B actuali7are-produs IS
procedure adauga>produs
(p>codp produse&codprodus?t3pe+
p>denp produse&denprodus?t3pe+
p>um produse&um?t3pe+
p>stoc produse&stoc?t3pe)
is
$egin
if e6ista>cod(p>codp) then
raise e6ceptie=
else
insert into produse values (p>codp+ p>denp+ p>um+ p>stoc)=
end if=
e6ception
@hen e6ceptie then
d$ms>output&put>line(AProdus e6istentBA)=
end=
procedure modifica>produs
(p>codp produse&codprodus?t3pe+
p>denp produse&denprodus?t3pe+
p>um produse&um?t3pe+
p>stoc produse&stoc?t3pe)
is
$egin
if e6ista>cod(p>codp) then
P
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle, an II, IDD seminar
update produse
set denprodus9p>denp+ um9p>um+ stoc9p>stoc
@here codprodus9p>codp=
else
raise e6ceptie=
end if=
e6ception
@hen e6ceptie then
d$ms>output&put>line(AProdusul cu aceast cod nu e6istaBA)=
end=
procedure modifica>produs
(p>codp produse&codprodus?t3pe+
p>stoc produse&stoc?t3pe)
is
$egin
if e6ista>cod(p>codp) then
update produse
set stoc9p>stoc
@here codprodus9p>codp=
else
raise e6ceptie=
end if=
e6ception
@hen e6ceptie then
d$ms>output&put>line(AProdusul cu aceast cod nu e6istaBA)=
end=
procedure sterge>produs
(p>codp produse&codprodus?t3pe)
is
$egin
if e6ista>cod(p>codp) then
delete from produse
@here codprodus9p>codp=
d$ms>output&put>line(AProdusul cu codul AGGp>codprodusGGA a fost stersBA)=
else
raise e6ceptie=
end if=
e6ception
@hen e6ceptie then
d$ms>output&put>line(AProdusul cu aceast cod nu e6istaBA)=
end=
function e6ista>cod
(p>codp produse&codprodus?t3pe)
return $oolean
is
v>unu num$er=
$egin
Q
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle, an II, IDD seminar
select < into v>unu
from produse
@here codprodus9p>codprodus=
return true=
e6ception
@hen no>data>found then
return false=
end=
E%#6
/
Apelul procedurilor / functiilor din cadrul pachetului1
e6ecute actuali%are>produse&adauga>produs(IIJ+AceaiA+ <;+ ;CC)=
select E from produse=
e6ecute actuali%are>produse&modifica>produs(IIJ+AgogosiA+ <C+ ;CC)=
select E from produse=
e6ecute actuali%are>produse&modifica>produs(III+ null)=
select E from produse=
e6ecute actuali%are>produse&sterge>produs(IIJ)=
select E from produse=
Stergerea pachetului se reali%ea%a cu comen%ile1
#!"P P)CC)3E nume-pac:et6
#!"P P)CC)3E 2"#B nume-pac:et6
#i%uali%area specificatiilor pachetelor in dictionarul metadatelor se reali%ea%a prin1
Select te't
From user-source
9:ere name<=%$,E-P)CDE&= and t;pe<=P)CC)3E=
,ar pentru a vi%uali%a corpul pachetului1
Select te't
From user-source
9:ere name<=%$,E-P)CDE&= and t;pe<=P)CC)3E 2"#B=
E'emplu(
Select te6t
'rom user>source
/here name9AAC)(AL,RA0">P0OD(S"A and t3pe9APACA!" BODLA=
J
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle, an II, IDD seminar
&riggeri pe ba7a de date
Sunt asociati cu o ta$ela+ vie@+ schema sau data$ase
Sunt stoca7i 4n $a%a de date
Se e6ecut5 c*nd are loc un eveniment& )ipuri de evenimente1
operatii L:D pe o ta$ela (insert/ update/ delete)
operatii L:D pe o ta$ela virtuala (vie@) cu clau%a ,8S)"AD O'
operatii LDD (Create+ Alter+ Drop) la nivel de data$ase sau schema
evenimente la nivelul schemei sau $a%ei de date (shutdo@n sau logon/off)
Se folosesc pentru gestionarea restric7iilor de integritate comple6e+ monitori%are+ centrali%area
operatiilor& 8u se recomanda construirea in e6ces a triggerilor&
Pentru fiecare trigger se sta$ileSte1
comanda care2l declanSea%5 (insertG updateG delete) 2 (n trigger poate fi declanSat de mai
multe comen%i
momentul de timp la care se declanSea%5 ($eforeG afterG instead of)& Pentru vie@ se
utili%ea%a instead of+ actiunile D:L vor fi inlocuite de corpul triggerului si vor fi afectate
ta$elele din care este construit vie@2ul&
nivelul (ro@G statement) 2 dac5 triggerul este la nivel de r*nd se e6ecut5 pentru fiecare
r*nd afectat de comen%ile1 insertG updateG delete& Daca nu este afectat nici un rand
triggerul nu se e6ecuta&
Din acest motiv+ o ta$el5 poate avea <; tipuri de triggeri&
Dimensiunea unui trigger nu poate depasi H; K$B Se poate include apelul unei proceduri in
corpul triggerului pentru a micsora dimensiunea acestuia&
Pentru a vedea erorile la compilare1
SD"9 E!!"!S &!I33E! nume-trigger6
Sinta6a de creare a unui trigger1
C!E)&E *"! !EPL)CE+ &!I33E! nume-trigger
*2EF"!E/ )F&E!/ I%S&E)# "F+
*I%SE!&/ *"!+ / $P#)&E *"F coloana,E+/ *"!+ / #ELE&E+
"% tabela
*F"! E)CD !"9 +
*9DE% conditie+
corp-trigger
Corp-trigger poate fi un $loc PL/SQL (BeginT"nd) sau un apel de procedura& Procedura poate
fi implementata in PL/SQL+ C sau UA#A+ iar apelul se reali%ea%a1 CALL nume_proc (fara = dupa
numele sauBBB)
E'emplu(
--Se creeaz un trigger care se declaneaz naintea fiecrei operaii de inserare n tabela
!"#$S%&
C0"A)" O0 0"PLAC" )0,!!"0 produse>trig
B"'O0" ,8S"0) O8 produse
<C
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle, an II, IDD seminar
B"!,8
d$ms>output&put>line(Atriggerul s2a e6ecutatA)=
"8D=
/
&riggeri la ni@el de rand F F"! E)CD !"9
,n triggerul la nivel de r*nd se poate accesa r*ndul curent procesat folosind doua pseudo4records (
(old, (neG)& )ipul lor este1
nume-tabela-pe-care-actionea7a-triggerulH!"9&BPE
#alorile pentru (old si (neG
"peratie ?aloare pt "ld ?aloare pt %eG
I%SE!& 8(LL valoarea noua+ inserata
$P#)&E valoare veche+ anterioara lui
update
valoare noua+ modificata
#ELE&E valoare veche+ anterioara lui
delete
8(LL
(1OLD) nu este definit pentru ,8S"0) Si (18"/) nu e definit pentru D"L")"
DeSi sintactic sunt tratate ca tip de dat5 record+ 4n realitate ele nu sunt Si opera7iile de atri$uire
directa var>record191old ce sunt valide pentru record nu sunt valide pentru (1ne@) Si (1old)& Din
acest motiv tre$uie preci%ate e6act campurile din pseudo2record 1old&camp sau 1ne@&camp&
E'emple(
--Se creeaz un trigger care asigur unicitatea codului produsului folosind valorile generate de o
secven
C0"A)" S"Q("8C" produse>secv
S)A0) /,). <
,8C0":"8) BL <
:AD#AL(" <CC
8OCLCL"=
C0"A)" O0 0"PLAC" )0,!!"0 generare>codprodus
B"'O0" ,8S"0) O8 produse
'O0 "AC. 0O/
B"!,8
S"L"C) produse>secv&ne6tval ,8)O (neGcodprodus '0O: dual=
"8D=
/
sho@ errors=
--'rigger care sa actualizeze cod client si in C"(%)*+ cand el e modificat in ,+!(%&
C0"A)" O0 0"PLAC" )0,!!"0 inlocuieste>cod
A')"0 (PDA)" O' codfirma O8 firme
'O0 "AC. 0O/
B"!,8
update comen%i
set codfirma 9 (neGcodfirma
@here codfirma 9 (oldcodfirma=
<<
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle, an II, IDD seminar
"8D=
/
c*nd un trigger e creat+ codul surs5 al triggerului este stocat 4n dic7ionarul de date in
user-triggers si se poate afisa1
SELEC& trigger-t;pe, trigger-name, triggering-e@ent
F!", user-triggers
9DE!E table-name<=P!"#$SE=6
3estiunea triggerilor(
(n trigger poate fi de%activat
)L&E! &!I33E! nume-trigger #IS)2LE/E%)2LE6
Sau1
)L&E! &)2LE nume-tabela
#IS)2LE/E%)2LE )LL &!I33E!S6
E'emplu(
)L&E! &)2LE produse
E%)2LE )LL &!I33E!S6
0ecompilarea unui trigger se reali%ea%a prin1
)L&E! &!I33E! nume-trigger C",PILE6
(n trigger se Sterge cu1
#!"P &!I33E! nume-trigger6
"bser@atie1 ,n momentul stergerii unei ta$ele se sterg automat toti triggerii asociati acelei ta$ele&
PL/SQL stochea%5 triggerii 4n forma compilat5 la fel ca procedurile+ func7iile Si pachetele&
Aceasta permite triggerilor s5 fie apela7i f5r5 recompilare&
<;