Sunteți pe pagina 1din 13

Subprograme PL/SQL

Obiective

 Sa faceti distinctia intre blocurile anonime PL/SQL si subprogramele PL/SQL


 Sa cunoasteti avantajele folosirii subprogramelor
 Sa creati, apelati si stergeti proceduri stocate
 Sa creati, apelati si stergeti functii stocate

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.

Tipuri de blocuri in PL/SQL

Anonim Procedura Functie

[DECLARE] PROCEDURE name FUNCTION name


IS RETURN datatype
IS
BEGIN BEGIN BEGIN
-statements - statements - statements
RETURN value;
[EXCEPTION] [EXCEPTION] [EXCEPTION]

END; END; END;

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.

Avantajele folosirii subprogramelor

 Extensibilitate si flexibiliatate (creati proceduri pentru a va indeplini anumite scopuri)


 Modularizare (programele devin formate din module logice bine definite care pot fi urmarite usor)
 Reutilizare si mentenanta (odata definit un subprogram el poate fi folosit de numeroase aplicatii)
 Abstractizare (folosind subprogramele trebuie sa stiti ce fac, nu cum lucreaza)
Avantajele folosirii subprogramelor stocate (pe server)

 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

 O procedura este un bloc PL/SQL cu nume care indeplineste o actiune


 O procedura poate fi stocata in baza de date, ca un obiect al bazei de date, pentru executii
repetate
 Sintaxa procedurilor este:

CREATE [OR REPLACE] PROCEDURE procedure_name


(argument1 [mode1] datatype1,
argument2 [mode2] datatype2, . . .)
IS [AS]
[local declarations]
BEGIN
executable statements
[EXCEPTIONS
exception handlers]
END [name];

Exemplu:

PROCEDURE create_dept(new_dname CHAR, new_loc CHAR) IS


BEGIN
INSERT INTO dept
VALUES (deptno_seq.NEXTVAL, new_dname, new_loc);
END create_dept;

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:

PROCEDURE raise_salary (emp_id INTEGER, increase REAL) IS


current_salary REAL;
salary_missing EXCEPTION;
BEGIN
SELECT sal INTO current_salary FROM emp
WHERE empno = emp_id;
IF current_salary IS NULL THEN
RAISE salary_missing;
ELSE
UPDATE emp SET sal = sal + increase
WHERE empno = emp_id;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO emp_audit VALUES (emp_id, ’No such number’);
WHEN salary_missing THEN
INSERT INTO emp_audit VALUES (emp_id, ’Salary is null’);
END raise_salary;

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.

Sfaturi pentru crearea si folosirea procedurilor stocate

 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

Exemplu: SQL> EXECUTE raise_salary(7369,200);

Modul de transmitere a parametrilor

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

Modul de transmitere a parametrilor pozitional si prin nume

 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 /

SQL> EXECUTE raise_salary (7369)

 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

SQL> VARIABLE g_name varchar2(15)


SQL> VARIABLE g_salary number
SQL> VARIABLE g_comm number
SQL> EXECUTE query_emp (7654, :g_name, :g_salary, :g_comm);
SQL> PRINT g_name

 Parametri de tip IN OUT : permit transmiterea valorilor initiale procedurilor apelate si


actualizarea parametrilor cu noile valori calculate. In corpul procedurii un parametru IN OUT se
comporta ca o variabila initializata. De aceea i se poate asigna o valore si valoarea lui poate fi
asignata altei variabile. Parametrul actual ce corespunde parametrului formal de tip IN OUT
trebuie sa fie o variabila, nu poate fi o expresie sau constanta.
Exemplu: SQL> CREATE OR REPLACE PROCEDURE format_phone
2 (v_phone_no IN OUT VARCHAR2)
3 IS
4 BEGIN
5 v_phone_no := '(' || SUBSTR(v_phone_no,1,3) ||
6 ')' || SUBSTR(v_phone_no,4,3) ||
7 '-' || SUBSTR(v_phone_no,7);
8 END format_phone;
9/
Apelarea procedurii:
SQL>VARIABLE g_phone_no varchar2(15)

SQL> BEGIN :g_phone_no := '8006330575'; END;


2 /

SQL> EXECUTE format_phone (:g_phone_no)

SQL> PRINT g_phone_no

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;

Avem urmatoarele proceduri de initializare:

PROCEDURE initialize (tab OUT DateTabTyp, n INTEGER) IS


BEGIN
FOR i IN 1..n LOOP
tab(i) := SYSDATE;
END LOOP;
END initialize;

PROCEDURE initialize (tab OUT RealTabTyp, n INTEGER) IS


BEGIN
FOR i IN 1..n LOOP
tab(i) := 0.0;
END LOOP;
END initialize;
Deoarece procesarile in cele doua proceduri sunt aceleasi din pct.v. logic atunci au acelasi nume. Se pot
plasa 2 apeluri ale procedurilor in acelasi bloc, subprogram sau pachet. PL/SQL determina care din cele
doua proceduri trebuie apelata verificand parametrii formali.

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;

Restrictii de supraincarcare a subprogramelor

 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.

PROCEDURE reconcile (acct_no IN INTEGER) IS


BEGIN
...
END;
PROCEDURE reconcile (acct_no OUT INTEGER) IS
BEGIN
...
END;

 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;

PROCEDURE charge_back (amount REAL) IS


BEGIN
...
END;

Sau
DECLARE
SUBTYPE Delimiter IS CHAR;
SUBTYPE Text IS LONG;
...
PROCEDURE scan (x Delimiter) IS
BEGIN
...
END;

PROCEDURE scan (x Text) IS


BEGIN
...
END;

 Nu se pot supraincarca doua functii in care difera doar tipul rezultatului returnat.

FUNCTION acct_ok (acct_id INTEGER) RETURN BOOLEAN IS


BEGIN
...
END;
FUNCTION acct_ok (acct_id INTEGER) RETURN INTEGER IS
BEGIN
...
END;

Stergerea unei proceduri stocate

Sintaxa de baza este: DROP PROCEDURE procedure_name

Exemplu: DROP PROCEDURE raise_salary;


Functii stocate

 O functie este un bloc PL/SQL cu nume care intoarce o valoare


 O functie poate fi stocata in baza de date, ca un obiect al acesteia, si utilizata de numeroase aplicatii
 O functie poate fi apelata ca parte a unei expresii

Sintaxa de baza este:

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.

Se considera exemplul in care se valideaza salariul corespunzator unui job.

FUNCTION sal_ok (salary REAL, title REAL) RETURN BOOLEAN IS


min_sal REAL;
max_sal REAL;
BEGIN
SELECT losal, hisal INTO min_sal, max_sal
FROM sals
WHERE job = title;
RETURN (salary >= min_sal) AND (salary <= max_sal);
END sal_ok;

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 ...

Exemplu de creare a unei functii din mediul SQL*Plus:


SQL> CREATE OR REPLACE FUNCTION get_sal
2 (v_id IN emp.empno%TYPE)
3 RETURN NUMBER
4 IS
5 v_salary emp.sal%TYPE :=0;
6 BEGIN
7 SELECT sal
8 INTO v_salary
9 FROM emp
10 WHERE empno = v_id;
11 RETURN (v_salary);
12 END get_sal;
13 /

SQL> VARIABLE g_salary number


SQL> EXECUTE :g_salary := get_sal(7934)
SQL> PRINT g_salary

Locurile unde pot fi apelate functiile stocate

 Lista de selectie care urmeaza dupa instructiunea SELECT


 In conditiile din cluzele WHERE sau HAVING
 In clauzele CONNECT BY, START WITH, ORDER BY si GROUP BY
 In clauza VALUES a comenzii INSERT
 In clauza SET a comenzii UPDATE

Restrictii in folosirea functiilor stocate

 O functie definita de utilizator (UDF) trebuie sa fie o functie stocata


 O functie UDF trebuie sa fie o functie ROW si nu GROUP
 Functiile UDF accepta doar parametri de tip IN
 Tipurile de date trebuie sa fie: CHAR, DATE sau NUMBER , si nu tipuri PL/SQL ca BOOLEAN,
RECORD sau TABLE.
 Tipul valorii returnate trebuie sa fie intern Oracle
 Instructiunile INSERT, UPDATE si DELETE nu sunt permise in functii
 Nu sunt permise apeluri la subprograme in corpul functiilor care sa incalce regulile anterioare

Stergerea functiilor stocate

Sintaxa de baza: DROP FUNCTION function_name;

Exemplu: DROP FUNCTION get_salary;

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

 Subprogramele sunt blocurile PL/SQL cu nume care se impart la randul lor in


proceduri si functii
 Se folosesc parametri pentru a transmite valori functiilor si procedurilor
 Pentru returnarea valorilor din proceduri se folosesc parametri de tip OUT sau IN
OUT
 O functie poate returna doar o singura valoare prin instructiunea RETURN

Practica

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