Documente Academic
Documente Profesional
Documente Cultură
VARIABILE
1. Declarare i iniializare
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
Obiect
Variabile non-PL/SQL: variabile de mediu (BIND VARIABLES)
a) Variabile Scalare:
Tipurile scalare conin valori simple (o variabila scalar poate conine la un moment dat o
singur valoare simpl) i corespund n principal tipurilor pe care le pot avea coloanele tabelelor.
date
binary_integer i pls_integer (numere ntregi ntre -2147483647 i
2147483647)
binary_float i binary_double (pentru numere reale n varianta
Oracle 10g)
timestamp (pentru fraciuni de secund)
Exemple:
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;
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.
set serveroutput on
DECLARE
v_salariu number(5);
BEGIN
SELECT salariul INTO v_salariu FROM angajati WHERE id_angajat=100;
DBMS_OUTPUT.PUT_LINE('Salariul angajatului cu id-ul 100 este='||v_salariu);
END;
/
Exemplu:
--se afiseaza numele angajatului cu codul 100
SET SERVEROUTPUT ON
DECLARE
v_nume VARCHAR2(20);
BEGIN
SELECT nume
INTO v_nume
2
FROM angajati
WHERE id_angajat = 100;
DBMS_OUTPUT.PUT_LINE('NUMELE ANGAJATULUI ESTE:' || v_nume);
END;
/
o singur linie
Exemplu:
Sa se afiseze numele angajatului care are functia 'IT_PROG'.
set serveroutput on
DECLARE
v_angajat varchar2(25);
BEGIN
--sunt mai multi angajati cu functia de IT_PROG
Atribuie unei variabile tipul altei variabile sau tipul de date specific unei coloane din
tabel.
Declararea unei variabile cu %TYPE:
variabila
sau
variabila1
variabila2
tabel.nume_coloan%TYPE;
tip_dat;
variabila1%TYPE;
Exemplu:
3
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:
--se afieaz mesajul: Bloc PL/SQL
VARIABLE g_mesaj varchar2(30)
BEGIN
:g_mesaj:='Bloc PL/SQL';
END;
/
PRINT g_mesaj
4
SET SERVEROUTPUT ON
VARIABLE g_comenzi varchar2(30)
BEGIN
select count(*) into :g_comenzi
from comenzi
where modalitate = 'online';
END;
/
PRINT g_comenzi
Exemplu:
Sa se afiseze mesajul "Ana are mere"
--se foloseste o variabila de mediu(variabila de legatura)
--o declaram in afara blocului PL/SQL
set serveroutput on
VARIABLE g_mesaj varchar2(30)
BEGIN
--pentru a utiliza aceasta variabila de mediu declarata in afara blocului trebuie sa
prefixam cu ":"
PRINT g_mesaj
set serveroutput on
--declaram variabila in care stocam mesajul, este mereu in afara blocului
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
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 utilizaz
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 definit cu
DEFINE va fi implicit de tipul CHAR:
-- 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
Sa se afiseze denumirea produsului din categoria software1 care are id-ul dat de la
tastatura.
set serveroutput on
VARIABLE g_denumire_produs varchar2(25)
DEFINE v_categorie_produs=software1
BEGIN
--pt a indroduce o valoare de la tastatura, se foloseste caracterul '&' plasat in fata numelui
EXERCIII PROPUSE
Specificai ce se va afia la rularea urmtorului bloc PL/SQL:
7
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);
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;
/
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;
/
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.
--punem rezultatul intr-o variabila de legatura pe care o vom afisa in afara blocului cu PRINT
factor2 number(3):=&factor2;
BEGIN
:g_rezultat:=factor1*factor2;
end;
/
10
PRINT g_rezultat
--folosim o variabila de legatura in care sa punem salariul si o afisam in afara blocului cu PRINT
--folosim o variabila de legatura in care sa punem salariul si o afisam in afara blocului cu PRINT
VARIABLE g_salariul number
--trebuie sa introducem numele si prenumele angajatului
11
Interaciunea se realizeaz prin intermediul comenzilor DDL (Data Definition Language), DCL
(Data Control Lnaguage), DML (Data Manipulation Language), TPL (Transaction Processing
Language) astfel:
PL/SQL nu suport comenzi DDL sau DCL n cadrul unui bloc. Pentru executarea acestor
comenzi se utilizeaza comanda EXECUTE IMMEDIATE:
Comenzi DDL/DCL
Executie
CREATE, ALTER, DROP
EXECUTE
IMMEDIATE
'CREATE
TABLE....
'
GRANT, REVOKE
PL/SQL suport toate comenzile din limbajul de manipulare a datelor (DML) i din cel de
control al tranzaciilor (TPL). 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
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;
/
set serveroutput on
BEGIN
--PL/SQL nu permite folosirea comenzilor LDD, prin urmare se foloseste sintaxa
EXECUTE IMMEDIATE
--id_trupa si nume_trupa sunt numele coloanelor sale
/
select * from prod;
set serveroutput on
begin
--comanda INSERT este o comanda LMD, deci este permisa de pl/sql
set serveroutput on
begin
execute immediate 'create table angajati5 as select * from angajati';
end;
/
select * from angajati5;
set serveroutput on
DECLARE
--declaram variabilele in care sa se stocheze valorile pt id_angajat si nume
--folosim %TYPE pentru ca variabele noastre sa preia tipul coloanelor id_angajat, respectiv
nume, trebuie sa indicam si tabela din care acestea fac parte
v_id angajati.id_angajat%TYPE;
v_nume angajati.nume%TYPE;
BEGIN
--comenzile LMD INSERT si SELECT sunt permise in blocul PL/SQL
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 DML (INSERT, UPDATE, DELETE)
care pot fi lansate fr restricii n PL/SQL.
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:
15
BEGIN
INSERT INTO produse (id_produs, denumire_produs, categorie, stoc)
VALUES (&id, '&denumire', '&categorie', &stoc);
END;
/
select * from produse;
Comanda UPDATE
Se mrete cu un procent 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 socurile tuturor
produselor cu 100 buci:
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:
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
16
set serveroutput on
DECLARE
v_id produse.id_produs%TYPE;
v_denumire produse.denumire_produs%TYPE;
BEGIN
v_id:=&v_id;
v_denumire:='&v_denumire';
INSERT INTO produse (id_produs,denumire_produs) VALUES (v_id,v_denumire);
end;
/
a. Folosii maximul dintre codurile produselor si adugai 10 la aceasta valoare,
folosind-o ca valoare pentru codul produsului nou introdus.
set serveroutput on
DECLARE
--avem nevoie de o variabila care sa stocheze maximul dintre codurile produselor
v_max_cod produse.id_produs%TYPE;
BEGIN
SELECT MAX(id_produs) INTO v_max_cod FROM produse;
DBMS_OUTPUT.PUT_LINE('Maximul dintre codurile produselor este='||
v_max_cod);
--comanda UPDATE este LMD deci poate aparea intr-un bloc PL/SQL
UPDATE
produse
SET
id_produs=v_max_cod+10
WHERE
denumire_produs='Frigider';
END;
/
17
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.
set serveroutput on
ACCEPT v_cod PROMPT 'Introduceti codul produsului'
BEGIN
v_cod:=&v_cod;
DELETE FROM produse WHERE id_produs=v_cod;
18
end;
/
19