Sunteți pe pagina 1din 13

Facultatea de Cibernetic, Statistic i Informatic Economic

SGBD Oracle seminarul 2

VARIABILE

1. Declarare i iniializare

declararea variabilelor se realizeaz n zona declarativ (delimitat prin DECLARE) a


blocului (sau sub-blocului);
iniializarea se poate face la declarare sau n zona de execuie (ntre BEGIN i END);
variabilele vor fi vizibile n restul blocului, respectiv i n blocurile incluse n el, mai puin n
sub-blocurile n care numele lor este redefinit (ca n majoritatea limbajelor de programare
structurate, semnificaia unui nume definit de utilizator ntr-un bloc/sub-bloc este dat de cea
mai apropiat declaraie anterioar locului folosirii);
toate variabilele PL/SQL au un tip de dat, restricii i un ir valid de valori;
declararea i iniializarea se realizeaz astfel:

nume_variabila [CONSTANT] TIP_DATA [NOT NULL] [:= | DEFAULT expresie]

constantele trebuie obligatoriu iniializate, iar ulterior nu i vor putea schimba valoarea;
variabilele NOT NULL trebuie obligatoriu iniializate, iar ulterior nu vor putea primi
valoarea NULL;
se folosete urmtoarea convenie de notare:
c_nume Constanta
v_nume Variabila
g_nume VarGlobala (variabil global definit n zona de specificaii a pachetului de
programe i valabil pentru toate subprogramele pachetului).

2. Tipuri de variabile

Variabile PL/SQL
Scalare
Compozite
Referin
LOB (Large Objects): NCLOB, CLOB, BLOB, BFILE
Obiect
Variabile non-PL/SQL: variabile de mediu (BIND VARIABLES), variabile gazd
(HOST VARIABLES), variabile indicator (INDICATOR VARIABLES)

a) Variabile Scalare:
Tipurile scalare conin valori simple (o variabila scalar poate conine la un moment dat o
singur valoare simpl). Cele mai folosite tipuri sunt:

CHAR (lung_max) - lungime fix de max 32.767 bytes


VARCHAR2 (lung_max) lungime variabil de max 32.767 bytes
LONG [ir de caractere de lungime variabil 2GB]
NUMBER (precizie,scal) virgul fix, precizie maxim 38 cifre
zecimale

1
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle seminarul 2

BOOLEAN (poate lua valorile TRUE, FALSE sau NULL) nu are un


tip SQL echivalent
DATE
BINARY_integer i PLS_INTEGER (numere ntregi ntre
-2147483647 i 2147483647) sunt specifice PL/SQL, folosesc
aritmetica mainii astfel nct operaiile sunt mai rapide comparativ
cu tipul NUMBER
BINARY_FLOAT i BINARY_DOUBLE (pentru numere reale,
precizie simpl, respectiv dubl)
TIMESTAMP (f) dat calendaristic i timp cu precizia f pentru
milisecunde. Exist i varianta TIMESTAMP WITH TIME ZONE
precum i TIMESTAMP WITH LOCAL TIME ZONE

Exemple de definire variabile i constante:


v_functie varchar2(9);
v_numar binary_integer:=0;
v_totalsal number(9,2):=0;
v_datainceput date:=sysdate+7;
c_taxa constant number(3,2):=8.25;
v_valid boolean not null:=true;

Tipurile de date pot avea subtipuri, definite de Oracle sau de ctre utilizator. Subtipurile pot
introduce restricii tipului de baz, coninnd o submulime a acestuia. Exist i subtipuri care nu
introduc nicio restricie tipului de baz, acestea pot avea rol n asigurarea compatibilitii cu alte
baze de date i limbaje de programare. Spre exemplu, NUMBER are printre subtipuri,
DECIMAL pentru virgul fix cu o precizie maxim de 38 cifre zecimale i FLOAT pentru
virgul mobil cu o precizie de aproximativ 38 cifre zecimale (nu introduce practic vreo restricie
tipului de baz). Tipul PLS_INTEGER are printre subtipuri NATURAL pentru valori nenegative
i SIGNTYPE care poate lua doar valorile -1, 0 sau 1. VARCHAR i STRING sunt subtipuri cu
acelai domeniu de valori ca i VARCHAR2.

Exemplu:
declare
m decimal; -- echivalent m NUMBER(38,0)
n float; -- echivalent n NUMBER
begin
m:=100.20;
dbms_output.put_line('m='||m);
n:=100.20;
dbms_output.put_line('n='||n);
end;
/

Execuia blocului va afia:


m=100
n=100.2

2
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle seminarul 2

Exemplu:
declare
z signtype;
begin
z:=2;
dbms_output.put_line('z='||z);
end;
/

Execuia blocului va genera o excepie deoarece variabila z nu poate lua dect valorile -1, 0 sau
1.

Afiarea variabilelor PL/SQL se realizeaz prin intermediul funciei PUT_LINE din pachetului
DBMS_OUTPUT. Se poate utiliza operatorul de concatenare ( || ) pentru a afia mai multe
mesaje sau variabile pe aceeai linie.

DBMS_OUTPUT.PUT_LINE ('VALOAREA VARIABILEI ESTE:' ||variabila);

Popularea variabilelor cu valori din tabelele bazei de date


Se utilizeaz comanda SELECT cu clauza INTO pentru popularea variabilelor PL/SQL cu
valori ale atributelor din tabele;
cererile SELECT din cadrul blocurilor PL/SQL trebuie s furnizeze o singur linie rezultat
(n caz contrar se semnaleaz eroare).

Exemplu:
--se afiseaza numele angajatului cu codul 100
SET SERVEROUTPUT ON
DECLARE
v_nume VARCHAR2(20);
BEGIN
SELECT nume
INTO v_nume
FROM angajati
WHERE id_angajat = 100;
DBMS_OUTPUT.PUT_LINE('NUMELE ANGAJATULUI ESTE:' || v_nume);
END;
/

3. Atributul %TYPE

Atribuie unei variabile tipul altei variabile sau tipul de date specific unei coloane din tabel.
Contribuie la asigurarea independenei programelor fa de baza de date.

Declararea unei variabile cu %TYPE:

variabila tabel.nume_coloan%TYPE;
sau

3
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle seminarul 2

variabila1 tip_dat;
variabila2 variabila1%TYPE;

Exemplu:
--afiseaza numele si prenumele angajatului cu codul 100.

Observaie: Restricia NOT NULL a unei coloane nu se aplic i variabilei declarate prin
folosirea atributului %TYPE.

4. Variabile de mediu sau variabile de legtur ale aplicaiilor gazd (BIND VARIABLES)

sunt variabile de legtur cu aplicaia n care ruleaz motorul PL/SQL;


trebuie declarate n aplicaie (n mediul gazd) i pot fi accesate i modificate n cadrul
blocurilor PL/SQL;
dup terminarea execuiei blocului PL/SQL, variabila rmne n mediul gazd cu valoarea
primit n urma rulrii blocului (i poate fi pasat altui bloc, realiznd astfel transmiterea de
valori ntre blocurile PL/SQL);
nu pot fi utilizate n cadrul procedurilor, funciilor sau pachetelor;
se declar n afara blocului PL/SQL cu ajutorul cuvntului cheie VARIABLE:
VARIABLE g_numevariabil TIP
pentru declararea unei variabile host de tip NUMBER nu se specific precizia i scala;
pentru utilizarea lor n cadrul unui bloc PL/SQL sau ntr-o fraz SQL din afara blocului se
prefixeaz cu :

:host_variabila:=v_variabila;

se afieaz n afara blocului cu ajutorul comenzii PRINT (la afiare variabila nu se va prefixa
cu :)
PRINT g_numevariabil

Exemple:

SET SERVEROUTPUT ON
VARIABLE n number

BEGIN
select count(*) into :n
from comenzi
where modalitate = 'online';
END;
/
PRINT n
-- afiseaza 32
begin
:n:=:n+5;
dbms_output.put_line('n='||:n);

4
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle seminarul 2

-- afiseaza n=37
:n:=:n+5;
dbms_output.put_line('n='||:n);
-- afiseaza n=42
end;
/
PRINT n
-- afiseaza 42

Observaie: Se poate auto-afia variabila prin setarea AUTOPRINT ON (nu mai este necesar
folosirea comenzii PRINT dup execuia blocului).

Exemplu:

--se selecteaza produsele si pretul acestora pentru acele produse care au pretul <
pretul mediu al produsului cu codul 3133 fara a utiliza un select imbricat

SET SERVEROUTPUT ON
SET AUTOPRINT ON
VARIABLE g_pret number

BEGIN
select avg(pret) into :g_pret
from rand_comenzi
where id_produs = 3133;
END;
/
select * from rand_comenzi where pret< :g_pret;

5. Variabile de substituie

de regul, variabilele de substituie sunt folosite pentru a transmite valori dinspre mediul
SQL*Plus spre comenzile SQL sau blocurile PL/SQL, n timp ce variabilele de legtur
(bind variables) sunt folosite pentru a transmite valori n sens invers sau pentru a transfera
valori ntre blocuri PL/SQL lansate succesiv (primul bloc seteaz variabila, urmtorul o
consult);
prin variabile de substituie se pot transmite valori comenzilor SQL sau blocurilor PL/SQL
lansate (folosind "&" sau "&&");
se pot invoca din comenzile SQL sau din blocurile PL/SQL prin "&nume_variabila" sau
"&&nume_variabila";
sunt locale sesiunii SQL n care au fost declarate;
n mediul SQL variabilele de substituie pot fi uor citite prin introducerea de valori de la
tastatur (utiliznd ACCEPT), se pot defini (cu DEFINE) sau afia pe ecran (cu PROMPT);

Exemple:

--se afiseaza numarul de comenzi ale angajatului al carui cod este introdus de
utilizator prin intermediul variabilei de substitutie &id_angajat

5
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle seminarul 2

DECLARE
v_nr_comenzi number(2);
BEGIN
select count(nr_comanda) into v_nr_comenzi from comenzi
where id_angajat=&id_angajat;
dbms_output.put_line('Angajatul are: '|| v_nr_comenzi||' comenzi');
END;
/

Observaie: ntr-un bloc PL/SQL se pot utiliza toate tipurile de variabile, respectnd ns
caracteristicile i regulile de utilizare ale acestora. n exemplul urmtor se utilizeaz
att variabila de substituie s_nume definit i iniializat prin comanda DEFINE,
ct i variabila de legtur g_salariul, dar i variabila local v_prenume de acelai
tip cu coloana nume din tabela Angajati. Variabila de substituie care conine un ir
de caractere va fi folosit cu apostrof drept n atribuiri sau comparaii, spre exemplu
nume:='&v_nume'.

-- se afiseaza salariul si prenumele angajatului cu numele Abel


SET SERVEROUTPUT ON
VARIABLE g_salariul number
DEFINE s_nume=Abel
DECLARE
v_prenume angajati.nume%type;
BEGIN
select prenume,salariul into v_prenume, :g_salariul
from angajati where nume='&s_nume';
DBMS_OUTPUT.PUT_LINE ('Prenumele angajatului este: '||v_prenume);
END;
/
print g_salariul

EXERCIII PROPUSE SI EXERCIII REZOLVATE

Specificai ce se va afia la rularea urmtorului bloc PL/SQL:

DECLARE
v_var1 NUMBER :=100;
v_var2 NUMBER;
v_var3 NUMBER := v_var2;
v_var4 VARCHAR(20) := 'variabila PL/SQL';
v_var5 NUMBER NOT NULL := v_var1;
c_const1 CONSTANT DATE := TO_DATE('12/02/2007','dd/mm/yyyy');
c_const2 CONSTANT NUMBER NOT NULL := 2;
c_const3 CONSTANT NUMBER := NULL;
v_var6 NUMBER DEFAULT NULL;

BEGIN
DBMS_OUTPUT.PUT_LINE('variabila 1 = '||v_var1);

6
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle seminarul 2

DBMS_OUTPUT.PUT_LINE('variabila 2 = '||v_var2);
DBMS_OUTPUT.PUT_LINE('variabila 3 = '||v_var3);
DBMS_OUTPUT.PUT_LINE('variabila 4 = '||v_var4);
DBMS_OUTPUT.PUT_LINE('variabila 5 = '||v_var5);
DBMS_OUTPUT.PUT_LINE('constanta 1 = '||c_const1);
DBMS_OUTPUT.PUT_LINE('constanta 2 = '||c_const2);
DBMS_OUTPUT.PUT_LINE('constanta 3 = '||c_const3);
DBMS_OUTPUT.PUT_LINE('variabila 6 = '||v_var6);
END;
/

Specificai ce se va afia la rularea urmtorului bloc PL/SQL (care conine blocuri


imbricate, ilustrnd domeniul de vizibilitate al unor variabile care au acelai nume):

DECLARE
var NUMBER;
BEGIN
var := 1;
DBMS_OUTPUT.PUT_LINE(var);

<<bloc1>>
DECLARE
var NUMBER;
BEGIN
var :=2;
DBMS_OUTPUT.PUT_LINE(var);
END bloc1;

DBMS_OUTPUT.PUT_LINE(var);

<<bloc2>>
DECLARE
var NUMBER;
BEGIN
var :=3;
DBMS_OUTPUT.PUT_LINE(var);

<<bloc3>>
DECLARE
var NUMBER;
BEGIN
var :=4;
DBMS_OUTPUT.PUT_LINE(var);
DBMS_OUTPUT.PUT_LINE(bloc2.var);
END bloc3;
DBMS_OUTPUT.PUT_LINE(var);
END bloc2;
DBMS_OUTPUT.PUT_LINE(var);
END;

7
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle seminarul 2

Specificai de ce apare o eroare la execuia urmtorului bloc PL/SQL:

DECLARE
stoc NUMBER(3):=600;
mesaj VARCHAR2(50):='Produsul 101';
BEGIN
DECLARE
stoc NUMBER(3):=10;
mesaj VARCHAR2(50):='Produsul 102';
um VARCHAR2(10):= ' bucati ';
BEGIN
stoc:= stoc+1;
mesaj:='Stocul pentru '||mesaj||' este de: '||stoc||um;
DBMS_OUTPUT.PUT_LINE(mesaj);
END;
stoc:= stoc+100;
mesaj:='Stocul pentru '||mesaj||' este de: '||stoc||um;
DBMS_OUTPUT.PUT_LINE(mesaj);
END;
/

S se calculeze suma a dou numere, iar rezultatul s se divid cu 3. Numerele se vor


introduce de la tastatur.

VARIABLE g_rezultat number


ACCEPT p_num1 PROMPT 'Introducei primul numr:'
ACCEPT p_num2 PROMPT 'Introducei al doilea numr:'
DECLARE
v_num1 number(9,2):=&p_num1;
v_num2 number(9,2):=&p_num2;
BEGIN
:g_rezultat:=(v_num1+v_num2)/3;
END;
/
PRINT g_rezultat

S se afieze salariul mrit cu un x procente. Salariul i procentul se citesc de la tastatur.

ACCEPT p_sal PROMPT 'Introducei salariul:'


ACCEPT p_procent PROMPT 'Introducei procentul:'
DECLARE
v_sal number:=&p_sal;
v_procent number:=&p_procent;

8
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle seminarul 2

BEGIN
dbms_output.put_line(to_char(nvl(v_sal,0)*(1+nvl(v_procent,0)/100)));
END;
/

TEM: S se calculeze valoarea fr TVA pentru un pre introdus de la tastatur ce


conine TVA.

9
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle seminarul 2

INTERACIUNEA CU SERVERUL ORACLE PRIN COMENZI SQL

Interaciunea se realizeaz prin intermediul comenzilor LDD (Limbajul de Descriere a Datelor),


LCD (Limbajul de Control al Datelor), LMD (Limbajul de Manipulare a Datelor), LPT
(Limbajul pentru Procesarea Tranzaciilor) astfel:

PL/SQL nu suport comenzi LDD sau LCD n cadrul unui bloc. Pentru executarea acestor
comenzi se utilizeaz comanda EXECUTE IMMEDIATE:
Comenzi DDL/DCL Executie
CREATE, ALTER, DROP EXECUTE IMMEDIATE 'CREATE
GRANT, REVOKE TABLE.... '

Se poate folosi i pachetul DBMS_SQL pentru comenzi LDD i LCD. Acest pachet, precum i
EXECUTE IMMEDIATE pot fi folosite i pentru alte instruciuni SQL care conin instruciuni
ce se pot modifica n timpul execuiei. Spre exemplu, putem construi o procedur care folosete
o interogare a crei clauze nu sunt cunoscute dect n momentul execuiei (spre exemplu, pentru
cutare dinamic n funcie de criteriile selectate de utilizator).

PL/SQL suport toate comenzile din limbajul de manipulare a datelor (LMD) i din cel de
control al tranzaciilor (LPT). Un bloc PL/SQL nu e o tranzacie. Comenzile Commit/
Rollback/ Savepoint sunt independente de bloc dar pot s apar n interiorul su.

Comenzi DML/TPL Executie


SELECT, INSERT, UPDATE, DELETE, Se executa normal in cadrul blocului
MERGE

COMMIT, ROLLBACK, SAVEPOINT Pot apare n bloc dar au efect asupra


tuturor tranzaciilor din interiorul i din
afara acestuia.

Exemple:
Se creeaz tabela PROD n cadrul unui bloc PL/SQL:

SET SERVEROUTPUT ON
--comenzi LDD
begin
--execute immediate 'DROP table prod';
execute immediate 'CREATE table prod AS SELECT * FROM produse where 1=2';
end;
/
Se adaug n tabela PROD nregistrri din tabela produse:

--comenzi LMD
--comenzi LMD
declare
v_codp produse.id_produs%type;
v_denp produse.denumire_produs%type;
v_cat produse.categorie%type;

10
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle seminarul 2

v_des produse.descriere%type;
begin
SELECT id_produs, denumire_produs, categorie, descriere INTO v_codp, v_denp,
v_cat, v_des
FROM produse where id_produs=3133;
INSERT INTO prod (id_produs, denumire_produs, categorie, descriere) VALUES
(v_codp, v_denp, v_cat, v_des);
DBMS_OUTPUT.PUT_LINE ('S-a adaugat in tabela prod produsul: '||v_codp||' '||
v_denp||' '||v_cat);
end;
/
select * from prod;

Pentru o mai mare flexibilitate se poate declara o variabil de tip ir de caractere care s
primeasc comanda LDD care va fi executat prin Execute Immediate:

Exemple:
Se creeaz tabela EMP_SAL prin intermediul unei variabile de tip VARCHAR2. La creare, n
tabela EMP_SAL se va aduga o nou nregistrare.

SET SERVEROUTPUT ON
VARIABLE G_EID NUMBER
DECLARE
V_SIR VARCHAR2(200);
BEGIN
:G_EID:=110;
V_SIR:='CREATE table emp_sal AS SELECT id_angajat, nume, prenume, salariul
FROM angajati where id_angajat='||:G_EID;
DBMS_OUTPUT.PUT_LINE (V_SIR);
EXECUTE IMMEDIATE V_SIR;
END;
/
select * from emp_sal;

Se adaug o nou coloan STOC n tabela PRODUSE:


DECLARE
V_SIR VARCHAR2(200);
BEGIN
V_SIR:='ALTER TABLE PRODUSE ADD (STOC NUMBER (7))';
DBMS_OUTPUT.PUT_LINE (V_SIR);
EXECUTE IMMEDIATE V_SIR;
END;
/
select * from PRODUSE;

Manipularea datelor in PL/SQL se face prin instruciunile LMD (INSERT, UPDATE, DELETE)
care pot fi lansate fr restricii n PL/SQL.
11
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle seminarul 2

Exemple:

Comanda INSERT
Se adaug o nou nregistrare n tabela EMP_SAL:

BEGIN
INSERT INTO emp_sal (id_angajat, nume, prenume, salariul)
VALUES (200, 'Pop', 'Marian', 7500);
END;
/
select * from emp_sal;

Se adaug o nou nregistrare n tabela produse prin introducerea valorilor cu ajutorul


variabilelor de substituie:

BEGIN
INSERT INTO produse (id_produs, denumire_produs, categorie, stoc)
VALUES (&id, '&denumire', '&categorie', &stoc);
END;
/
select * from produse;

Comanda UPDATE

Se mrete cu x procente salariul angajailor din tabela EMP_SAL care au n prezent salariul
mai mic dect o anumit valoare:
DECLARE
v_procent number:=0.1;
v_prag angajati.salariul%type:=10000;
BEGIN
UPDATE emp_sal
SET salariul=salariul*(1+v_procent)
WHERE salariul<v_prag;
END;
/
select * from emp_sal;

Se realizeaz o aprovizionare n cadrul depozitului prin care se mresc stocurile tuturor


produselor cu 100 buci (coloana STOC a fost anterior adugat):
BEGIN
UPDATE produse
SET stoc=nvl(stoc,0)+100;
END;
/
select * from produse;

n urma comenzilor realizate de clieni, monitoarele de tipul LCD sunt vndute, se deci scade
din stocul existent un numr de monitoare introdus de la tastatur:

12
Facultatea de Cibernetic, Statistic i Informatic Economic
SGBD Oracle seminarul 2

BEGIN
UPDATE produse
SET stoc=stoc-&nr_buc_vandute
WHERE lower(denumire_produs) like 'monitor lcd%';
COMMIT;
END;
/
select * from produse;

Atenie! n acest caz utilizarea comenzii COMMIT va finaliza att tranzacia curent ct i
tranzaciile executate anterior.

Comanda DELETE

Se terge angajatul cu numele Pop din tabela emp_sal:


DECLARE
BEGIN
DELETE FROM emp_sal WHERE initcap(nume) like 'Pop%';
ROLLBACK;
END;
/
select * from emp_sal;

EXERCITII PROPUSE
1. Creai un bloc PL/SQL ce adaug un produs nou in tabela PRODUSE.
a. Folosii maximul dintre codurile produselor si adugai 10 la aceasta valoare,
folosind-o ca valoare pentru codul produsului nou introdus.
b. Folosii un parametru (variabila de substituie) pentru denumire, categoria i
stocul produsului.
c. Lsai descrierea produsului NULL.
d. Executai blocul.
2. Creai un bloc PL/SQL ce selecteaz stocul maxim pentru produsele existente in tabela
PRODUSE. Tiprii rezultatul pe ecran.
3. Creai un bloc PL/SQL care terge un produs pe baza codului acestuia primit ca
parametru (variabila de substituie). Anulai tergerea dintr-ul alt bloc PL/SQL.

13

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