Pagina iLearning
Pentru testarea exemplelor in PL/SQL se va folosi SQL Workshop -> SQL Commands.
Introducere n PL/SQL
Acest mini tutorial realizeaz o scurt introducere a limbajului de programare PL/SQL folosit n cadrul
laboratoarelor de SGBD conform leciilor virtuale oferite de Academy Oracle.
PL/SQL este un limbaj de programare procedural folosit de Oracle pentru bazele de date relaionale. Pe
scurt PL/SQL este:
o extensie pentru limbajul SQL ce permite combinarea declaraiilor SQL cu un limbaj de
programare;
este un limbaj proprietar Oracle i poate fi folosit doar cu o baz de date Oracle;
este un limbaj procedural;
este un limbaj de generaia a treia 3GL.
Exemplu:
Considerm tabela enrollments cu notele studenilor. Daca vrem s selectm notele atunci avem urmtoarea
interogare:
Select stu_id, final_numeric_grade, final_letter_grade
From enrollments;
Dac vrem n continuare s modificm datele n funcie de o anumit condiie dup principiul DAC este
adevrat expresia ATUNCI execut instruciunea1, ALTFEL execut instruciunea2, nu putem doar cu declaraii
SQL. Aici intervine PL/SQL care folosete variabile, costante, tipuri de date, cursoare, structuri de control i
proceduri i funcii. n continuare vom oferi drept exemplu de utilizare a limbajului PL/SQL pentru modificarea
notelor studenilor din valori numerice cu valori de tip caracter:
Declare
v_new_letter_grade varchar2(1);
Cursor c_enrollments IS
For c1 in c_enrollments
Loop
If c1.final_numeric_grade between 66 and 75 then v_new_letter_grade:= A:
Elsif c1.final_numeric_grade between 56 and 65 then v_new_letter_grade:= B;
Elsif c1.final_numeric_grade between 56 and 65 then v_new_letter_grade:= C;
Elsif c1.final_numeric_grade between 56 and 65 then v_new_letter_grade:= D;
Else
V_new_letter_grade:=F;
End if;
Update enrollments
Set final_letter_grade=v_new_letter_grade where class_id=1 and stu_id=c1.stu_id;
End loop;
Commit;
End;
Dup cum se poate observa limbajul folosete variabile definite n partea declarativ; folosete cursoare
pentru situaii cnd avem mai mult de o nregistrare n urma unui select; structuri de control: FOR, IF; i declaraii
SQL.
Prin urmare avantajele PL/SQL sunt:
integrarea construciilor procedurale cu SQL;
integrarea structurilor de control cu SQL ceea ce ofer un control mult mai bun al instruciunilor
SQL i al execuiilor acestora;
modularizarea programelor deoarece unitatea de baz ntr-un program PL/SQL este blocul
considerat a fi un modul iar programul poate fi alctuit dintr-o secven de astfel de blocuri sau
putem avea blocuri imbricate;
performan ridicat prin combinarea logic a declaraiilor SQL reducnduse numrul de apeluri la
baza de date;
portabilitate, programele PL/SQL pot rula oriunde un server Oracle funcioneaz indiferent de SO
i platforma folosit;
manipularea excepiilor, limbajul PL/SQL ofer posibilitatea captrii excepiilor eficient reducnd
astfel posibilitatea apariiei erorilor.
Crearea blocurilor PL/SQL
Reprezint unitatea de baz n PL/SQL. Exist 3 tipuri de blocuri: blocul anonim, procedura i funcia,
ultimele dou sunt subprograme.
Un bloc PL/SQL conine trei pri:
1.
Partea Declarativ (opional): ncepe cu DECLARE i se termin cnd partea executabil
ncepe. Conine declaraii de variabile, cursoare i excepii definite de utilizator (exist i
excepii predefinite).
2.
Partea Executabil (obligatorie): ncepe cu BEGIN i se termin cu END. End se termin cu
punct i virgul. Partea executabil poate conine oricte blocuri sunt necesare.
3.
Partea de captare a Excepiilor (opional): partea aceast este inclus n partea executabil.
ncepe cu EXCEPTION.
a. Blocul anonim
[ Declare .......]
Begin ....................
[ Exception ............... ]
End;
Blocul anonim nu poate fi invocat deoarece nu are un nume i nu mai exist dup ce este executat.
Exemple de blocuri anonime:
Begin
End;
-------------------------------------------------------------------------Declare
v_date DATE := sysdate;
Begin
DBMS_OUTPUT.PUT_LINE(v_date);
End;
------------------------------------------------------------------------Declare
v_country_id varchar2(2);
Begin
select country_id into v_country_id from countries
where country_id='a';
Exception
WHEN NO_DATA_FOUND THEN
Dbms_Output.Put_Line('eroare');
End;
-------------------------------------------------------------------------Observaii!
Pentru exemplul cu exception avem o excepie predefinit: NO_DATA_FOUND.
De asemenea se poate deduce ca i regul de declarare a variabilelor: folosirea literei v i apoi ct mai
explicit denumiri pentru variabile.
Funcia de afiare este DBMS_OUTPUT.PUT_LINE iar ca argumente pentru aceasta se folosesc variabile
declarate i NU cmpuri din baza de date.
De asemenea n cadrul codului PL/SQL rezultatul n urma unei interogri SQL se pstreaz tot ntr-o
variabil declarat.
Exe.:
Begin
End;
Este greit, iar eroarea va fi: PLS-00428: an INTO clause is expected in this SELECT statement.
Corect este:
Declare
nr
Begin
number;
select 2*2
INTO nr
from dual;
DATE;
NUMBER(2) NOT NULL :=2;
CONSTANT NUMBER :=10;
VARCHAR2(30) DEFAULT Ema;
End;
-- ROLLBACK este folosit pentru a anula orice modificare realizat n baza de date dup ultimul
COMMIT realizat. n exemplul de mai jos doar ultimul insert are loc.
Begin
End;
-- SAVEPOINT este folosit pentru a marca puncte intermediare n procesul tranzaciei. Doar ROLLBACK
poate fi folosit cu SAVEPOINT. n exemplu prin ROLLBACK se anuleaz toate tranzaciile pn la
savepoint my_sp_1. n final vor fi introduse doar primul insert i cel de dup rollback.
CURSORUL IMPLICIT
De fiecare dat cnd o instruciune SQL urmeaz s fie executat, serverul Oracle aloc o zon de memorie
privat pentru a stoca declaraia SQL i datele implicate. Aceast zon de memorie se numete cursor
implicit.
Cu ajutorul atributelor cursorului implicit putem afla cte rnduri au fost procesate de ctre declaraia SQL.
Exist dou tipuri de cursoare:
- cursorul implicit, este automatic denumit SQL
- cursorul explicit, definit de ctre programator pentru interogri ce returneaz mai mult de o nregistrare
Atributele pentru cursorul implicit sunt:
- SQL%FOUND atribut boolean evaluat cu true dac interogarea returneaz cel puin o nregistrare
- SQL%NOTFOUND atribut boolean evaluat la true dac interogarea nu returneaz nicio valoare
- SQL%ROWCOUNT este o valoare intreag ce reprezint numrul de nregistrri afectate de interogare
Exemplu:
Declare
v_deptno copy_emp.department_id%TYPE:=50;
Begin
Delete from copy_emp where department_id = v_deptno;
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || nregistrri terse .);
End;
Structuri de control
Structura Condiional IF
IF condiie THEN
Instruciune;
[ELSIF condiie THEN
Instruciune;]
[ELSE
Instruciune;]
END IF;
Declare
V_varsta NUMBER:=13;
Begin
IF v_varsta < 18 THEN
DBMS_OUTPUT.PUT_LINE (Sunt copil);
ELSIF v_varsta < 40 THEN
DBMS_OUTPUT.PUT_LINE (Sunt nc tnr);
ELSE
DBMS_OUTPUT.PUT_LINE(Sunt mereu tnr!);
END IF;
End;
End;
END;
DBMS_OUTPUT.PUT_LINE(v_out);
Declare
v_counter NUMBER:=1;
Begin
While v_counter <= 3 LOOP
INSERT into salariat values (v_counter, Leonte,Bacau);
v_counter:=v_counter+1;
End LOOP;
End;
Bucla FOR
FOR contor IN [REVERSE]
End;
! Structurile repetitive pot fi imbricate una n alta. Atunci structurile sunt etichetate <<etichet>> astfel nct
putem specifica explicit din care bucl se iese: End LOOP <<etichet>>.
Cursorul Explicit
Este folosit atunci cnd n urma interogrii rezult mai mult de o nregistrare.
Exemplu: se declar un cursor explicit pentru a obine numele i zile naionale pentru rile din Asia
Declare
CURSOR wf_holiday_cursor IS
Select country_name, national_holiday_date
From wf_countries where region_id IN (30, 34, 35);
v_country_name
wf_countries.country_name%TYPE;
v_holiday
wf_countries.nationa_holiday_date%TYPE;
Begin
OPEN wf_holiday_cursor;
--nti se deschide cursorul
LOOP
-- bucl pentru parcurgerea tuturor nrgistrrilor obinute
FETCH wf_holiday_cursor INTO v_country_name, v_holiday;
EXIT WHEN wf_holiday_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_country_name || || v_holiday);
End LOOP;
CLOSE wf_holiday_cursor;
--se nchide cursorul
Tratarea EXCEPIILOR
Exception handler este poriunea de program care definete aciunile ce au loc cnd o excepie apare
EXCEPTION
PROCEDURI
CREATE [OR REPLACE] PROCEDURE nume [parametri] IS | AS
[variabile, cursoare];
Begin
Instruciuni SQL i PL/SQL;
[Exception
WHEN exception_nume;]
End [nume];
Exemplu:
CREATE OR REPLACE PROCEDURE add_salariat IS
v_id salariat.salariat_id%TYPE:=20;
v_nume
salariat.salariat_nume%TYPE:=Mihaela;
Begin
INSERT INTO salariat values(v_id, v_nume);
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT ); --folosit pentru a testa dac insertul are loc
End;
FUNCII
CREATE [OR REPLACE] FUNCTION nume [parametri [mode] tip] RETURN tip IS | AS
[variabile];
Begin
Instruciuni SQL i PL/SQL;
RETURN expresie;
End [nume];
Apelul se face: variabil := nume_funcie(parametri); SAU nume_funcie(parametri);
! Pentru a terge o procedur sau o funcie stocat se folosete DROP PROCEDURE|FUNCTION nume;