Sunteți pe pagina 1din 6

Facultatea de Cibernetică, Statistică şi Informatică Economică

SGBD Oracle – seminarul 8

Pachete de subprograme

Grupeaza variabile, subprograme, tipuri de date PL/SQL care sunt corelate logic.
Sunt formate din 2 părți:
- specificația pachetului – partea publică;
- corpul pachetului – partea privată.

În zona de specificații a pachetului se pot declara:


 proceduri;
 funcții;
 variabile;
 cursoare;
 excepții.

Corpul pachetului definește complet procedurile, funcțiile și cursoarele. Dacă există, acesta va
conține cel puțin corpul funcțiilor, procedurilor și cursoarelor declarate în specificații.
Subprogramele private care apar doar în partea privată a pachetului nu pot fi apelate din afara
acestuia. Pentru a utiliza o funcție sau o procedură privată, în cadrul unui alt subprogram din pachet,
aceasta trebuie declarată înainte (principiul forward declarations);

Specificatia pachetului:
CREATE [OR REPLACE] PACKAGE nume_pachet
IS|AS
--declaratii de variabile si tipuri publice, sunt initializate cu NULL implicit
--specificatii ale subprogramelor publice
END [nume_pachet];

Corpul pachetului:
CREATE [OR REPLACE] PACKAGE BODY nume_pachet
IS|AS
--declaratii de variabile si tipuri private
--definitii ale subprogramelor publice și private
[BEGIN
-- Este optional si se executa o singura data la primul apel si la incarcarea pachetului in memorie
END [nume_pachet];

Supraîncărcarea subprogramelor
 Se poate realiza numai pentru functii/proceduri din cadrul pachetelor, nu și pentru subprograme
singulare (stocate direct in baza de date);
 Nu se pot supraincarca 2 subprograme care au paramentrii de tipuri asemanatoare (ex: NUMBER
si DECIMAL sau VARCHAR2 si VARCHAR).

Exemplu:
create or replace PACKAGE actualizare_produse IS
procedure adauga_produs

1
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle – seminarul 8

(p_codp produse.id_produs%type,
p_denp PRODUSE.DENUMIRE_PRODUS%type,
p_lista produse.pret_lista%type,
p_min produse.pret_min%type);

procedure modifica_produs
(p_codp produse.id_produs%type,
p_denp PRODUSE.DENUMIRE_PRODUS%type,
p_lista produse.pret_lista%type,
p_min produse.pret_min%type);

procedure modifica_produs
(p_codp produse.id_produs%type,
p_lista produse.DENUMIRE_PRODUS%type);

procedure sterge_produs
(p_codp produse.id_produs%type);

function exista_cod
(p_codp produse.id_produs%type)
return boolean;

exceptie exception;

END;
/

create or replace PACKAGE BODY actualizare_produse IS


procedure adauga_produs
(p_codp produse.id_produs%type,
p_denp PRODUSE.DENUMIRE_PRODUS%type,
p_lista produse.pret_lista%type,
p_min produse.pret_min%type)

is
begin
if exista_cod(p_codp) then
raise exceptie;
else
insert into produse(id_produs,denumire_produs,pret_lista,pret_min) values (p_codp,
p_denp, p_lista, p_min);
end if;
exception
when exceptie then
dbms_output.put_line('Produs existent!');
end;

procedure modifica_produs
(p_codp produse.id_produs%type,
p_denp PRODUSE.DENUMIRE_PRODUS%type,

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

p_lista produse.pret_lista%type,
p_min produse.pret_min%type)
is
begin
if exista_cod(p_codp) then
update produse
set DENUMIRE_PRODUS=p_denp, pret_lista=p_lista, pret_min=p_min
where id_produs=p_codp;
else
raise exceptie;
end if;
exception
when exceptie then
dbms_output.put_line('Produsul cu aceast cod nu exista!');
end;

--supraîncarcare a procedurii modifica_produs


procedure modifica_produs
(p_codp produse.id_produs%type,
p_lista produse.DENUMIRE_PRODUS%type)
is
begin
if exista_cod(p_codp) then
update produse
set pret_lista=p_lista
where id_produs=p_codp;
else
raise exceptie;
end if;
exception
when exceptie then
dbms_output.put_line('Produsul cu aceast cod nu exista!');
end;

procedure sterge_produs
(p_codp produse.id_produs%type)
is
begin
if exista_cod(p_codp) then
delete from produse
where id_produs=p_codp;
dbms_output.put_line('Produsul cu codul '||p_codp||' a fost sters!');
else
raise exceptie;
end if;
exception
when exceptie then
dbms_output.put_line('Produsul cu aceast cod nu exista!');
end;

3
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle – seminarul 8

function exista_cod
(p_codp produse.id_produs%type)
return boolean
is
v_unu number;
begin
select 1 into v_unu
from produse
where id_produs=p_codp;
return true;
exception
when no_data_found then
return false;
end;
END;
/

Apelul procedurilor / funcțiilor din cadrul pachetului:


execute actualizare_produse.adauga_produs(449,'ceai', 12, 14);
select * from produse where id_produs=449;

--Apelarea procedurii supra-încărcate


execute actualizare_produse.modifica_produs(449,20);
select * from produse where id_produs=449;

--Se poate folosi și CALL în loc de execute


call actualizare_produse.modifica_produs(449, null);
select * from produse where id_produs=449;

--Apelarea dintr-un bloc anonim


begin
actualizare_produse.sterge_produs(449);
end;
/
select * from produse where id_produs=449;

Întrebare:
Se poate apela funcția exista_cod din pachetul actualizare_produse dintr-o frază SELECT?
Argumentați.

Ștergerea pachetului se realizează cu comenzile:


DROP PACKAGE nume_pachet;
DROP PACKAGE BODY nume_pachet;

Vizualizarea specificațiilor pachetelor in dicționarul metadatelor se realizează prin:


Select text
From user_source
Where name='NUME_PACHET' and type='PACKAGE'

4
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle – seminarul 8

Iar pentru a vizualiza corpul pachetului:


Select text
From user_source
Where name='NUME_PACHET' and type='PACKAGE BODY'

Exemplu:
Select text
From user_source
Where name='ACTUALIZARE_PRODUSE' and type='PACKAGE BODY';

După finalizarea unui pachet, partea privată se poate cripta folosind utilitarul wrap sau pachetul
DBMS_DDL.

Exemplu folosire wrap, unde actualizare_produse_body.txt conține corpul pachetului:

Sursa criptată se regăsește în fișierul actualizare_produse_body.plb și poate fi rulată:

5
Facultatea de Cibernetică, Statistică şi Informatică Economică
SGBD Oracle – seminarul 8

După rulare, corpul corpului nu mai poate fi descifrat dar subprogramele din acesta rulează: