Sunteți pe pagina 1din 8

SISTEME INFORMATICE DE GESTIUNE | CIG, ANUL III

ORACLE Application Express


14. PACHETE
14.1 Aspecte introductive

Un pachet (package) reprezintă, de fapt, o bibliotecă de obiecte stocate pe server, de tipul


procedurilor, funcțiilor, cursoarelor, tipurilor de date, excepțiilor, variabilelor şi constantelor.
Practic, acesta este o colecţie de obiecte corelate logic ce sunt stocate în baza de date şi partajează
variabile comune. Toate obiectele declarate în pachete sunt globale şi pot fi apelate din orice
program PL/SQL, asemănător clasicelor variabile globale din alte limbaje de programare.

De exemplu, un pachet pentru departamentul Resurse Umane poate conține:


 proceduri de angajare și concediere;
 funcții pentru calcularea bonusurilor, comisioanelor sau penalizărilor;
 variabile folosite pentru scutirea de impozit.

Principalele avantaje oferite de pachete sunt:

 modularitatea aplicațiilor prin oferirea posibilității de a structura aplicația sub formă de


module ușor de înțeles și de gestionat;
 posibilitatea declarării de obiecte globale;
 îmbunătățirea performanțelor sistemului de gestiune prin încarcarea simultană în memorie
a mai multor obiecte;
 uşurința în proiectarea aplicațiilor;
 adăugarea de funcționalități noi.

14.2 Sectiunile unui pachet

Un pachet este compus din două secțiuni distincte:

1. CREATE PACKAGE: SPECIFICAŢIA PACHETULUI (zona publică) – conţine informaţii despre


conţinutul pachetului (definiţii de constante, variabile, cursori, subprograme), adică structura
obiectelor; definiţiile ce apar în specificaţia unui pachet sunt publice, ele fiind vizibile altor
aplicaţii.

2. PACKAGE BODY: CORPUL PACHETULUI (zona privată) – defineşte cursorii şi subprogramele


menționate în specificaţia pachetului, conţinând detalii de implementare şi declaraţii private
ce nu pot fi accesate de alte aplicaţii.

Asist.Univ.Drd. Bogoslov Ioana Andreea 1


SISTEME INFORMATICE DE GESTIUNE | CIG, ANUL III

Corpul pachetului este opţional dacă în specificaţie nu sunt declarate subprograme sau cursori.
Specificaţia şi corpul pachetului sunt compilate separat şi sunt stocate ca două obiecte distincte în
dicţionarul de date.

 SPECIFICAŢIILE UNUI PACHET

Specificațiile reprezintă partea publică a unui pachet şi au următoarea sintaxă:

Sintaxa generală aferentă specificatiilor unui pachet:


CREATE [OR REPLACE] PACKAGE denumire_pachet
IS|AS declarații de tipuri și variabile globale
specificații ale subprogramelor
END [denumire_pachet];
Unde:
- denumire_pachet – reprezintă numele pachetului;
- declarații de tipuri și variabile globale – reprezintă declarațiile globale ale cursoarelor,
excepțiilor, constantelor, variabilelor şi tipurilor de date şi descrierea acestora din punct de
vedere al structurii;
- specificații ale subprogramelor – reprezintă numele procedurilor şi funcțiilor cu parametrii
formali aferenți.

 CORPUL UNUI PACHET

Corpul unui pachet reprezintă partea privată a acestuia şi are următoarea sintaxă:

Sintaxa generală aferentă corpului unui pachet:


CREATE [OR REPLACE] PACKAGE BODY denumire_pachet
IS | AS
declarații de tipuri și variabile globale
[corp_cursor ...] [corp_funcție ...] [corp_procedură ...]
BEGIN
instrucțiuni
END [denumire_pachet];
Unde:
- opțiunea OR REPLACE șterge și recreează corpul de instrucțiuni al pachetului.
- denumire_pachet specifică un nume pentru pachet care trebuie să fie același ca și la specificația
pachetului.
- [corp_cursor ...] [corp_funcție ...] [corp_procedură ...] trebuie să conțină corpul tuturor
subprogramelor declarate în specificația pachetului
- folosirea denumirii pachetului după cuvântul cheie END este opțională.

Asist.Univ.Drd. Bogoslov Ioana Andreea 2


SISTEME INFORMATICE DE GESTIUNE | CIG, ANUL III

14.3 Stergerea pachetelor

 Pentru a șterge întreg pachetul, specificația și corpul, se foloseste sintaxa:

DROP PACKAGE denumire_pachet;

 Pentru a șterge doar corpul pachetului, se folosește sintaxa:

DROP PACKAGE BODY denumire_pachet;

Observație! - Nu se poate elimina doar specificația pachetului.

14.4 Supraîncărcarea pachetelor

Sistemul Oracle permite existența în același pachet a mai multor subprograme cu aceeași denumire.
Această tehnică, cunoscută sub denumirea de supraîncărcare, este utilă în special atunci când vreți
să executați aceleași subprograme de mai multe ori, însă cu argumente de tipuri diferite.

Un exemplu de utilizare a supraîncărcării procedurilor îl reprezintă pachetul dbms_output. În acest


pachet, procedura put_line este apelată de mai multe ori, pentru a genera linii de ieșire cu tipuri de
date diferite.

Un alt exemplu îl constituie funcția TO_CHAR care are mai multe modalități de a fi apelată, permițând
convertirea unui număr sau a unei date calendaristice într-un șir de caractere.

De asemenea, putem utiliza tehnica de supraîncărcare și în ceea ce privește subprogramele definite


de utilizator. De exemplu, poate doriți să găsiți un angajat prin căutarea codului acestuia sau prin
căutarea datei de angajare. Scopul este același, dar diferă parametrii sau criteriul de căutare.

Reguli referitoare la supraîncărcare:

 Puteți folosi același nume pentru subprograme diferite cât timp parametrii lor formali diferă ca
număr, ordine, categorie sau tip de date.
 Supraîncarcarea poate fi aplicată doar subprogramelor în pachete, dar nu subprogramelor de
sine stătătoare.

Lucrări aplicative:

Aplicatia 1

 Să se realizeze două proceduri după cum urmează:


 O procedură care să permită inserarea de date în tabela produse;
 O procedură care să permită ștergerea unui produs al cărui cod este introdus de la
tastatură.

Asist.Univ.Drd. Bogoslov Ioana Andreea 3


SISTEME INFORMATICE DE GESTIUNE | CIG, ANUL III

1. Realizarea pachetului cu denumirea pachet_inserare_stergere:

CREATE OR REPLACE PACKAGE pachet_inserare_stergere AS


PROCEDURE inserare_produs (p_cod produse.cod_produs%type, p_denumire
produse.denumire%type, p_an produse.an_fabricatie%type, p_sortiment produse.sortiment%type,
p_pret produse.pret%type, p_culoare produse.culoare%type, p_stoc produse.stoc%type, p_um
produse.um%type);
PROCEDURE stergere_produs (p_cod produse.cod_produs%type);
END pachet_inserare_stergere;

2. Realizarea corpului pachetului cu denumirea pachet_inserare_stergere:

CREATE OR REPLACE PACKAGE BODY pachet_inserare_stergere AS

PROCEDURE inserare_produs (p_cod produse.cod_produs%type, p_denumire


produse.denumire%type, p_an produse.an_fabricatie%type, p_sortiment produse.sortiment%type,
p_pret produse.pret%type, p_culoare produse.culoare%type, p_stoc produse.stoc%type, p_um
produse.um%type)
IS
BEGIN
INSERT INTO produse(cod_produs, denumire, an_fabricatie, sortiment, pret, culoare, stoc, um)
VALUES(p_cod, p_denumire, p_an, p_sortiment, p_pret, p_culoare, p_stoc, p_um);
END inserare_produs;

PROCEDURE stergere_produs (p_cod produse.cod_produs%TYPE) IS


BEGIN
DELETE FROM produse
WHERE cod_produs=p_cod;
END stergere_produs;
END;

 Se cere inserarea în tabela Produse a produsului cu următoarele caracteristici: Cod_produs: 7,


Denumire: Babeasca alba; An fabricație: 2008; Sortiment: Sec; Preț: 22; Culoare: Alb; Stoc: 108; UM: l.
De asemenea, se dorește ștergerea produsului cu codul 6. Cele două operații vor fi realizate prin
executarea pachetului realizat anterior.

DECLARE v_cod produse.cod_produs%TYPE:=6;


BEGIN
pachet_inserare_stergere.inserare_produs (7, 'Babeasca alba', 2008, 'Sec', 22, 'Alb', 108, 'l');
pachet_inserare_stergere.stergere_produs(v_cod);
END;

Asist.Univ.Drd. Bogoslov Ioana Andreea 4


SISTEME INFORMATICE DE GESTIUNE | CIG, ANUL III

Aplicatia 2

 Să se realizeze două funcții după cum urmează:


 O funcție care să determine concatenarea numelui cu prenumele aferente unui angajat
al cărui cod este introdus de la tastatură. Totodată, în urma invocării funcției, se dorește
afișarea șirului de caractere rezultat;
 O funcție care să determine extragerea și afișarea salariului aferent unui angajat al cărui
cod este introdus de la tastatură.

1. Realizarea pachetului cu denumirea personal:

CREATE OR REPLACE PACKAGE personal AS


FUNCTION nume_complet (p_cod_angajat NUMBER)
RETURN VARCHAR2;
FUNCTION extragere_salariu (p_cod_angajat NUMBER)
RETURN NUMBER;
END personal;

2. Realizarea corpului pachetului cu denumirea personal:

CREATE OR REPLACE PACKAGE BODY personal AS

FUNCTION nume_complet(p_cod_angajat NUMBER) RETURN VARCHAR2 IS


v_nume_complet VARCHAR2(46);
BEGIN
SELECT nume || ',' || prenume
INTO v_nume_complet
FROM angajati
WHERE cod_angajat = p_cod_angajat;
RETURN v_nume_complet;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
WHEN TOO_MANY_ROWS THEN
RETURN NULL;
END nume_complet;

FUNCTION extragere_salariu(p_cod_angajat NUMBER) RETURN NUMBER IS


p_salariu NUMBER(8);
BEGIN
SELECT salariu
INTO p_salariu

Asist.Univ.Drd. Bogoslov Ioana Andreea 5


SISTEME INFORMATICE DE GESTIUNE | CIG, ANUL III

FROM angajati
WHERE cod_angajat= p_cod_angajat;
RETURN p_salariu;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
WHEN TOO_MANY_ROWS THEN
RETURN NULL;
END extragere_salariu;
END personal;

 Se cere afișarea numelui complet aferent angajatului cu codul 6, precum și extragerea și


afișarea salariului acestuia, ca urmare a invocării pachetului realizat anterior.

DECLARE
p_salariu NUMBER(8);
v_nume VARCHAR2(46);
p_cod_angajat NUMBER := 6;
BEGIN

v_nume := personal.nume_complet(p_cod_angajat);
p_salariu := personal.extragere_salariu(p_cod_angajat);

IF v_nume IS NOT NULL AND


p_salariu IS NOT NULL
THEN
dbms_output.put_line('Angajatul: ' || v_nume);
dbms_output.put_line('Salariul: ' || p_salariu);
END IF;
END;

15. DECLANSATORI

15.1 Ce este un declansator?

Un declanșator (eng. trigger) reprezintă o unitate de program denumită specific, care este stocată în
bază de date și activată (executată) ca răspuns la un eveniment anume. Evenimentul specificat este
asociat cu un tabel, o vizualizare, o schemă sau baza de date și poate fi unul dintre următoarele:

 operație ce ține de manipularea bazei de date (DML - DELETE, INSERT sau UPDATE);
 operație ce ține de definirea bazei de date (DDL - CREATE, ALTER sau DROP);
 operație de bază de date (SERVERERROR, LOGON, LOGOFF, STARTUP sau SHUTDOWN).

Asist.Univ.Drd. Bogoslov Ioana Andreea 6


SISTEME INFORMATICE DE GESTIUNE | CIG, ANUL III

Sintaxa generală aferentă unui declansator:


CREATE [OR REPLACE] TRIGGER denumire_declansator
{BEFORE | AFTER} {INSERT|UPDATE|DELETE} [OF denumire_coloana]
ON tabel_referit
[FOR EACH ROW [WHEN conditii]]
[DECLARE] -- Opțional, pentru declararea variabilelor locale
corpul_declansatorului
Observatii:
Declanșatorii sunt similari procedurilor, fiind tot blocuri PL/SQL denumite (după cum a fost menționat
mai sus). Deoarece declanșatorii apar în urma unor evnimente, se pot configura astfel încât să apară
imediat înainte sau după aceste evenimente (BEFORE | AFTER).

15.2 Tipuri de declansatori

Oracle oferă posibilitatea definirii și utilizării a două tipuri de declanșatori:


 la nivel de înregistrare (row-level triggers);
 la nivel de declarație (statement-level triggers).

Declansatori la nivel de înregistrare pentru acțiuni relativ la date


- sunt executați cate o data pentru fiecare rând dintr-o operație/instrucțiune;
- reprezintă cel mai comun tip de declanșatori și sunt adesea folosiți în aplicații;
- sunt identificați prin clauza FOR EACH ROW din comanda CREATE TRIGGER.

Declansatori la nivel de declarație pentru acțiuni relativ la operații


- sunt executați o singură dată pentru fiecare operație/instrucțiune. De exemplu, dacă prin
intermediul unei operații are loc inserarea a 200 de înregistrări, atunci declanșatorul aferent
tabelei respective se va executa o singură dată;
- se utilizează pentru a forța măsuri suplimentare de securitate asupra anumitor tipuri de
operații care se pot executa asupra unei tabele;
- reprezintă declanșatori realizați implicit - se omite clauza FOR EACH ROW din comanda
CREATE TRIGGER.

Lucrări aplicative:

 Să se realizeze un declanșator care să nu permită modificarea sumei înscrise pe facturile


aferente aprovizionării.

Rezolvare:
CREATE OR REPLACE TRIGGER declansator_modificare_suma
BEFORE UPDATE OF suma ON facturi_aprovizionare
FOR EACH ROW
BEGIN
IF (:NEW.suma != :OLD.suma) THEN

Asist.Univ.Drd. Bogoslov Ioana Andreea 7


SISTEME INFORMATICE DE GESTIUNE | CIG, ANUL III

RAISE_APPLICATION_ERROR(-20002,'Suma nu poate fi modificata');


END IF;
END;

Important!
În ceea ce privește declanșatorii aplicați la nivel de rând, se poate accesa rândul curent procesat
folosind două pseudo-records ( :old, :new). Tipul acestora este:

nume_tabelă_pe_care_acționează_declanșatorul%ROWTYPE

Valorile pentru :old și :new sunt următoarele:

OPERAȚIE VALOARE PENTRU :OLD VALOARE PENTRU :NEW


INSERT NULL Valoarea nouă, după inserare
Valoarea anterioară Valoarea nouă, după
UPDATE
actualizării actualizare
DELETE Valoarea anterioară ștergerii NULL

Observații:

- (:OLD) nu este definit pentru INSERT şi (:NEW) nu e definit pentru DELETE;


- Deşi sintactic sunt tratate ca tip de dată record, în realitate ele nu sunt. Astfel, operaţiile de
atribuire directă (var_record:=:old) care sunt valide pentru record nu sunt valide pentru
(:new) şi (:old). Din acest motiv trebuie precizate exact campurile din pseudo-record
:old.camp sau :new.camp.

 Să se realizeze un declanșator care să nu permită inserarea unui preț mai mare de 50 u.m..

Rezolvare:
CREATE OR REPLACE TRIGGER restrictie_pret
BEFORE INSERT or UPDATE on produse
FOR EACH ROW
DECLARE v_pret_max number:=50;
BEGIN
IF :new.pret>v_pret_max then
RAISE_APPLICATION_ERROR (-20202, 'Nu se poate seta un pret mai mare de 50.');
END IF;
END;

Asist.Univ.Drd. Bogoslov Ioana Andreea 8

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