Documente Academic
Documente Profesional
Documente Cultură
Obiective
Scopul lectiei
Lectia prezinta regulile de baza si structura procedurilor si functiilor PL/SQL stocate. De
asemenea se descrie modul de apelare si folosire a procedurilor si functiilor stocate.
Fiecare modul PL/SQL contine unul sau mai multe blocuri. Aceste blocuri pot fi separate sau
imbricate unul in altul.
Blocurile anonime
Blocurile anonime nu au nume. Ele sunt declarate in cadrul aplicatiilor si executate la run-time.
Se pot integra blocuri anonime in cadrul programelor precompilate si in cadrul SQL*Plus sau Server
Manager. Triggerii (declansatorii) din Developer/2000 sunt astfel de blocuri.
Subprogramele
Subprogramele sunt blocuri PL/SQL care au nume, care pot lua parametri si poti fi apelate. Pot
fi declarate ca proceduri sau functii. In general se folosesc proceduri pentru a executa o actiune si o
functie pentru a calcula o valoare.
Subprogramele se pot stoca la nivel de server de date sau la nivelul aplicatiilor. Daca folositi
componentele Developer/2000 (Forms,Reports,Graphics) puteti declara proceduri si functii ca parte
componenta a aplicatiei si pot fi apelate din alte proceduri, functii sau triggere.
Nota: O functie este similara cu o procedura, cu exceptia faptului ca trebuie sa intoarca o
valoare.
Modul Descriere Disponibilitate
Anonymous Blocuri PL/SQL fara nume care sunt incluse in aplicatie In toate mediile PL/SQL
block sau sunt lansate interactiv.
Stored Blocuri PL/SQL cu nume care sunt stocate de Serverul Server Oracle
procedure or Oracle si care pot accepta parametri si care pot fi apelate
function dupa nume.
Application Blocuri PL/SQL cu nume care sunt stocate in aplicatiile Modulele Developer/200
procedure or dezvolatate cu Developer/2000 sau in biblioteci si care pot
function fi apelate dupa nume.
Package Modul PL/SQL care grupeaza impreuna proceduri, functii Server Oracle,
sau identificatori care sunt in relatie. Developer/2000
Database Bloc PL/SQL asociat cu o tabela a bazei de date si care este Oracle Server
trigger lansat automat cand o instructiune DML este executata.
Application Bloc PL/SQL asociat cu un eveniment al aplicatie si care Developer/2000
trigger este lansat automat.
Securitatea datelor (se poate restrictiona accesul utilizatorilor la baza de date doar prin
folosirea subprogramelor stocate)
Performanta (se poate imbunatati performanta bazei de date: cantitatea de informatie transmisa
prin retea este mai mica decat in cazul folosirii instructiunilor SQL sau a blocurilor PL/SQL,
deoarece textul e transmis o singura data si apoi este apelat subprogramul; subprogramul stocat
este in forma compilata pe server, astfel incat la fiecare apelare se executa; daca subprogramul
este incarcat deja in zona dememorie comuna a serverului SGA atunci incarcarea de pe disc nu
mai e necesara si incepe imediat executia)
Alocarea memoriei (subprogramele stocate pot fi incarcate odata in zona de memorie comuna
a serverului SGA si executata de mai multi utilizatori sau aplicatii)
Productivitate (se mareste productivitatea dezvoltarii aplicatiilor prin construirea unui set de
subprograme stocate pe server)
Integritatea datelor (se imbunatateste integritatea si consistenta aplicatiilor si a datelor din
baza de date)
Proceduri stocate
Exemplu:
O procedura are doua parti: specificatile si corpul procedurii. Specificatiile procedurii incep prin
cuvantul cheie PROCEDURE si se termina cu numele procedurii sau cu lista de parametri. Declararea
parametrilor este optionala. Procedurile care nu au parametri sunt scrise fara paranteze. Definirea unui
parametru se face astfel:
Parameter_name [ IN | OUT | IN OUT ] datatype [ { := | DEFAULT } expresion]
Nu se poate impune constrangerea NOT NULL unui parametru. De asemenea nu se poate specifica
o constrangere asupra unui tip de date. De exemplu, urmatoarea declaratie a emp_id este ilegala, pentru
ca nu se poate specifica o constrangere de marime:
PROCEDURE raise_salaray(emp_id NUMBER(4)) IS … - ar trebui NUMBER
Corpul procedurii incepe prin cuvantul cheie IS si se termina la cuvantul cheie END, urmat optional
de numele procedurii. Corpul procedurii are 3 parti: declarativa, executabila si de tratarea exceptiilor.
Partea declarativa contine declaratiile locale care sunt incluse intre IS si BEGIN. Cuvantul DECLARE
care introduce declaratii intr-un bloc PL/SQL nu este folosit. Partea executabila contine instructiuni
care sunt plasate intre BEGIN si EXCEPTION sau END.
Se considera urmatoarea procedura de marire a salariului unui angajat:
Cand este apelata procedura accepta marca unui angajat si suma cu care se mareste salarul angajatului
dat. Procedura foloseste marca angajatului pentru a selecta valoarea actuala a salarului din tabela. Daca
angajatul nu este gasit sau daca salarul este null se trateaza exceptiile corespunzatoare. Altfel, salarul
este actualizat.
Definiti proceduri pentru a indeplini actiuni mici si distincte. Nu definiti proceduri lungi pentru
diverse actiuni distincte deoarece se poate scrie acelasi cod de mai multe ori in mai multe proceduri
Nu definiti proceduri care dubleaza functionalitatea procedurilor si functiilor deja existente in
Oracle. De exemplu nu definiti proceduri pentru verificarea constrangerilor simple de integritate pe
care le puteti face prin declararea constrangerilor la nivel de tabela sau coloana.
Crearea procedurilor stocate prin SQL*Plus
Scrieti corpul procedurii intr-un editor de texte si-l salvati intr-un fisier script (cu extensia sql)
De la prompterul SQL*Plus rulati fisierul pentru a compila codul sursa al procedurii si pentru
a-l stoca pe server.
Apelati procedura dintr-un instrument Oracle (SQL*Plus) pentru a determina daca se executa
fara erori
Procedurile transmit informatii folosind parametrii. Variabilele sau expresiile referite in lista de
parametri a unei proceduri apelate se numesc parametri actuali. De exemplu procedura raise_salary
poate fi apelata de 2 ori astfel: raise_salary(emp_num,amount) si apoi
raise_salary(emp_num,merit + bonus);
Variabilele declarate la definirea procedurii si referite in corpul procedurii se numesc parametri
formali. O metoda corecta de programare este aceea in care numele parametrilor formali difera de cei
actuali. Cand se apeleaza procedura raise_salary, parametrii actuali sunt evaluati si valorile rezultate
sunt asignate parametrilor formali corespunzatori. Inainte de a asigna valorile parametrilor actuali celor
formali, PL/SQL converteste tipurile de date daca este necesar. Parametrii actuali si cei formali
corespunzatori trebuie sa aiba tipuri de date compatibile. De exemplu, PL/SQL nu poate converti valori
de tip DATE in REAL.
Exemplu: raise_salary(emp_num,’2500’) - legal
Raise_salary(emp_num,’$2500’) ilegal, exceptie VALUE_ERROR
Transmiterea pozitionala
Exemplu: raise_salary(emp_num, value);
Compilatorul PL/SQL asociaza primul parametru actual emp_num cu primul parametru formal
emp_id si al doilea parametru actual value cu al doilea parametru formal increase.
Transmiterea prin nume
Exemplu: raise_salary(increase=>value,emp_id=>emp_num)
Raise_salary(emp_id=>emp_num, increase=>value)
Sageata ‘=>’ este un operator de asociere care asociaza parametrul formal din stanga cu parametrul
actual din dreapta. Ordinea in care sunt transmisi parametri nu este importanta.
Transmiterea mixta
Exemplu: raise_salary(emp_id, increase=>value)
In acest caz primul parametru foloseste transmiterea pozitionala iar cel de-al doilea prin nume.
Parametrii transmisi prin pozitie trebuie scrisi inantea celor transmisi prin nume.
Exemplu: raise_salary(increase=>value,emp_id) ilegal
Tipul(modul) parametrilor
Modul parametrilor defineste comportamentul parametrilor formali. Sunt trei tipuri de parametri:
IN (predefinit), OUT si IN OUT. Aceste moduri se pot folosi in orice subprogram dar este indicat sa se
evite folosirea parametrilor de tip OUT si IN OUT in cadrul functiilor, deoarece functiile sunt definite
pentru a intoarce o singura valoare si pentru a limita efectele colaterale.
Parametri de tip IN : permite transmiterea valorilor parametrilor in cadrul subprogramelor
apelate. Acestia actioneaza ca o constanta, deci nu li se pot asigna valori in corpul procedurii.
Parametrii de acest tip pot fi initializati cu valori predefinite.
Exemplu: SQL> CREATE OR REPLACE PROCEDURE raise_salary
2 (v_id in emp.empno%TYPE)
3 IS
4 BEGIN
5 UPDATE emp
6 SET sal = sal * 1.10
7 WHERE empno = v_id;
8 END raise_salary;
9 /
Parametrii de tip OUT: permit returnarea valorilor programului apelant. In corpul procedurii
un parametru OUT actioneaza ca o variabila neinitializata. De aceea valoarea acestui tip de
parametru nu poate fi asignata altui parametru si nu i se poate asigna o alta valoare
parametrului. Parametrul actual corespunzator parametrului formal de tip OUT trebuie sa fie o
variabila.Nu poate fi o constanta sau o expresie. Un parametru actual de tip OUT poate avea o
valoare initiala , dar aceasta este pierduta cand se apeleaza procedura. In cadrul procedurii un
parametru de tip OUT nu poate fi folosit intr-o expresie, singura operatie valida ce i se poate
aplica este asignarea de valori.Ca orice variabila un parametru OUT este initializat cu NULL.
Deci, inainte de iesirea din procedura asignati o valoare parametrului altfel va fi NULL. Daca
procedura se incheie cu succes valorile calculate se asigneaza parametrilor actuali. Daca apar
exceptii netratate PL/SQL nu asigneaza valori parametrilor actuali.
Exemplu: SQL>CREATE OR REPLACE PROCEDURE query_emp
1 (v_id INemp.empno%TYPE,
2 v_name OUT emp.ename%TYPE,
3 v_salary OUT emp.sal%TYPE,
4 v_comm OUT emp.comm%TYPE)
5 IS
6 BEGIN
7 SELECT ename, sal, comm
8 INTO v_name, v_salary, v_comm
9 FROM emp
10 WHERE empno = v_id;
11 END query_emp;
12 /
Apelare procedura din SQL*Plus:
SQL> START emp_query.sql
IN OUT IN OUT
Predefinit Trebuie specificat Trebuie specificat
Transmite valori subprogramului Intoarce valori dupa apelare Transmite valori initiale unei
proceduri si intoarce valorile
actualizate dupa apelare
Parametrii formali actioneaza ca Parametrii formali actioneaza ca Parametrii formali actioneaza ca
niste constante niste variabile neinitializate niste variabile initializate
Parametrii formali nu pot lua Parametrii formali nu pot fi Parametrii formali trebuie sa ia
valori folositi in expresii si trebuie valori
asignati cu valori
Parametrii actuali pot fi Parametrii actuali trebuie sa fie Parametrii actuali trebuie sa fie
constante, variabile initializate, variabile variabile
literali sau expresii
Parametrii actuali sunt transmisi Parametrii actuali sunt transmisi Parametrii actuali sunt transmisi
prin referinta (un pointer la prin valoare (copii dupa valoare) prin valoare (copii dupa valoare
valoare) sunt transmise in procedura si
sunt intoarse din procedura)
Valori predefinite ale parametrilor
Parametrii de tip IN pot fi intializati cu valori predefinite. In acest fel se pot transmite
parametrii actuali in diverse moduri unui subprogram, acceptand sau suprascriind valorile predefinite.
Astfel se pot adauga noi parametri formali fara a schimba fiecare apel al subprogramului.
Exemplu: PROCEDURE create_dept (
new_dname CHAR DEFAULT ’TEMP’,
new_loc CHAR DEFAULT ’TEMP’) IS
BEGIN
INSERT INTO dept
VALUES (deptno_seq.NEXTVAL, new_dname, new_loc);
END;
Daca parametrul actual nu este transmis atunci este folosita valoarea predefinita a parametrului formal
corespondent. Urmatoarele apeluri sunt valide:
create_dept;
create_dept(’MARKETING’);
create_dept(’MARKETING’, ’NEW YORK’);
In general se foloseste notatia pozitionala pentru suprascrierea valorilor predefinite ale parametrilor
formali, dar nu se poate ignora un parametru formal daca nu transmitem parametrul formal
corespunzator.
Exemplu: create_dept(‘NEW YORK’); incorect, asigneaza valoarea New York departamentului
Create_dept( ,’NEW YORK’); ilegal
In aceste cazuri se foloseste modul de transmitere prin nume:
Create_dept(new_loc=>’NEW YORK’);
De asemenea nu se poate asigna NULL unui parametru formal neinitializat prin netransmiterea valorii
parametrului actual corespondent.
Exemplu: PROCEDURE create_dept ( new_deptno NUMBER,
new_dname CHAR DEFAULT ’TEMP’,
new_loc CHAR ) IS …
create_dept(100) ; ilegal, nu va asigna NULL parametrului new_loc;
Forma corecta este: create_dept(100, new_loc=>NULL) sau la declarare:
new_loc CHAR DEFAULT NULL
Cand se creaza un subprogram stocat, nu se pot folosi variabile de legatura(mediu) a SQL*Plus in
caluza DEFAULT.
SQL> VARIABLE num NUMBER
SQL> CREATE PROCEDURE create_dept(new_deptno IN NUMBER DEFAULT :num, …)
Aceasta declaratie este ilegala.
Supraincarcarea suprogramelor
PL/SQL permite supraincarcarea numelor procedurilor sau functiilor. Se poate folosi acelasi
nume pentru diferite subprograme atata timp cat parametrii lor fomali difera in numar, ordine sau
familie de tip de date (tipuri de date incompatibile).
Exemplu: DECLARE
TYPE DateTabTyp IS TABLE OF DATE INDEX BY BINARY_INTEGER;
TYPE RealTabTyp IS TABLE OF REAL INDEX BY BINARY_INTEGER;
hiredate_tab DateTabTyp;
sal_tab RealTabTyp;
DECLARE
TYPE DateTabTyp IS TABLE OF DATE INDEX BY BINARY_INTEGER;
TYPE RealTabTyp IS TABLE OF REAL INDEX BY BINARY_INTEGER;
hiredate_tab DateTabTyp;
comm_tab RealTabTyp;
indx BINARY_INTEGER;
...
BEGIN
indx := 50;
initialize(hiredate_tab, indx); -- apeleaza prima versiune
initialize(comm_tab, indx); -- apeleaza a doua versiune
...
END;
Pot fi supraincarcate doar subprogramele locale sau impachetate, nu si cele de sine statatoare
(stand-alone). Doua subprograme nu se pot supraincarca daca parametrii lor formali difera doar prin
nume sau modul de apelare(IN/OUT/IN OUT).
Exemplu: Cele doua proceduri nu pot fi supraincarcate.
Nu pot fi supraincarcate doua subprograme daca difera doar tipul parametrilor formali dar aceste
tipuri sunt din aceeasi familie (compatibile).
Exemplu: PROCEDURE charge_back (amount INTEGER) IS
BEGIN
...
END;
Sau
DECLARE
SUBTYPE Delimiter IS CHAR;
SUBTYPE Text IS LONG;
...
PROCEDURE scan (x Delimiter) IS
BEGIN
...
END;
Nu se pot supraincarca doua functii in care difera doar tipul rezultatului returnat.
CREATE [OR REPLACE] FUNCTION name [(parameter[, parameter, ...])] RETURN datatype IS
[local declarations]
BEGIN
executable statements
[EXCEPTION
exception handlers]
END [name];
Unde parametrul are urmatoarea sintaxa:
parameter_name [IN | OUT | IN OUT] datatype [{:= | DEFAULT} expression]
Nu se pot impune constrangeri de tip NOT NULL sau de marime de tip parsametrilor. Ca si la
proceduri o functie are doua parti: specificatia si corpul. Functiile care nu au parametri se scriu fara
paranteze. Semnificatia celor doua parti este aceeasi cu cea de la proceduri.
Cand este apelat functia accepta ca parametri marimea unui salar si denumirea unei meserii si intoarce
o valoare logica. Functia poate fi apelata ca in urmatorul context:
IF sal_ok(new_sal, new_title) THEN ...
PROCEDURA FUNCTIE
Executa instructiuni PL/SQL Este apelata ca parte a unei expresii
Nu returneaza nimic prin instructiunea RETURN Returneaza o valoare prin RETURN
Poate intoarceuna sau mai multe valori Poate intoarce o valoare
REZUMAT
Practica