ALTE DOCUMENTE
|
||||||
Un pachet (package) este o colectie īncapsulata de obiecte ale schemei. Aceste obiecte pot fi proceduri, functii, variabile, constante, cursoare si exceptii. Pachetul este compilat, dupa care este stocat īn dictionarul de date al bazei d 10410y2421k e date, ca obiect al schemei.
Pachetele contin subprograme rezidente, sau programe de sine-statatoare, numite subprograme pachet. Aceste subprograme pot fi apelate din alte programe rezidente, declansatori, programe precompilate sau din oricare dintre programele interactive Oracle, cum ar fi SQL*Plus. Spre deosebire de subprogramele rezidente, pachetul īnsusi nu poate fi apelat sau imbricat si nu i se pot transfera parametri.
De obicei, un pachet are doua parti componente: specificatia si corpul pachetului. Specificatia declara tipurile, variabilele, constantele, exceptiile, cursoarele si subprogramele care urmeaza sa fie folosite. Corpul pachetului defineste complet cursoarele, functiile si procedurile, implementānd īn acest fel specificatia.
Specificatia si corpul pachetului sunt stocate separat īn baza de date. Acest lucru face ca celelalte obiectele apelante sa depinda numai de specificatie, nu si de corpul pachetului. Aceasta separare va permite sa modificati definitia unui obiect din corpul pachetului, fara ca prin aceasta Oracle sa invalideze celelalte obiecte care apeleaza obiectul respectiv sau care fac referire la el, cum s-ar īntāmpla daca ati modifica specificatia pachetului.
Pachetele ofera urmatoarele avantaje:
Posibilitatea de a structura mai eficient aplicatia sub forma de module. Fiecare pachet, īmpreuna cu modulele acestuia, sunt usor de īnteles, simplificānd dezvoltarea aplicatiei.
Pachetele va permit sa acordati privilegii mai eficient.
Variabilele publice si cursoarele pachetelor persista pe durata īntregii sesiuni. Prin urmare, cursoarele si procedurile care sunt executate pe durata sesiunii le pot partaja.
Pachetele va permit sa supraīncarcati procedurile si functiile. Supraīncarcarea unei proceduri sau a unei functii īnseamna crearea īn acelasi pachet a mai multor proceduri sau functii cu acelasi nume, dar cu argumente diferite.
Pachetele īmbunatatesc performantele prin īncarcarea simultana īn memorie a mai multor obiecte, īn acest fel, la viitoarele apeluri ale subprogramelor aferente pachetului nu vor fi necesare operatii de I/O.
Pachetele promoveaza reutilizarea codului (eliminānd astfel codificarea redundanta), prin intermediul bibliotecilor care contin proceduri si functii rezidente.
Pachetele sunt create interactiv, folosind instrumente cum ar fi SQL*DBA si SQL*Plus. īn acest capitol sunt prezentate etapele necesare pentru crearea si gestionarea pachetelor Oracle.
Sfaturi īn legatura cu utilizarea pachetelor īn continuare sunt prezentate cāteva sfaturi utile pentru utilizarea cu succes a pachetelor Oracle:
Evitati sa scrieti pachete care reproduc functionalitati Oracle existente.
Pastrati pachetele cāt mai simple si generale, pentru a promova reutilizarea lor īn aplicatiile viitoare.
Creati corpul pachetului dupa ce ati conceput aplicatia. Plasati īn specificatia pachetului numai acele obiecte care vreti sa fie vizibile tuturor utilizatorilor.
Evitati sa plasati prea multe elemente īn specificatia pachetului, si cu atāt mai mult cele care trebuie compilate. Modificarea corpului unui pachet nu impune recompilarea procedurilor dependente, hi schimb, modificarea specificatiei unui pachet face ca programul Oracle sa recompileze toate subprogramele rezidente care fac referire la pachetul respectiv.
Specificatia pachetului contine declaratii publice ale numelui pachetului si ale numelor si tipurilor argumentelor. Domeniul acestor declaratii este global pentru īntregul pachet si local pentru baza de date. Acest lucru īnseamna ca obiectele declarate īn pachetul dumneavoastra sunt accesibile din orice punct al pachetului. Prin urmare, toate informatiile de care aplicatia dumneavoastra are nevoie pentru a executa un subprogram rezident sunt continute īn specificatia pachetului.
Īn exemplul urmator este ilustrata declararea unui pachet. Specificatia acestui pachet declara o functie si o procedura:
create package pachet_inventar as
function calcul_inventar(cant number, cod_articol ^varchar2 (15) ) return number;
procedure modif_inventar(cant number);
end pachet_inventar
Uneori, specificatia declara numai variabile, constante si exceptii, prin urmare corpul pachetului nu este necesar. Exemplul urmator ilustreaza specificatia unui pachet care nu poseda corpul pachetului:
create package inventar_costuri as
type inreg_inventar is record (nume_articol varchar2(30), pret_articol number,
cost_articol number);
pret number; cant number; lipsa_cost exception; END inventar costuri;
Corpul unui pachet contine definitiile obiectelor publice pe care le-ati declarat īn specificatie. De asemenea, corpul contine si declaratiile altor obiecte care sunt obiecte private ale pachetului. Obiectele declarate īn' corpul pachetului ca fiind obiecte private ale pachetului nu sunt accesibile obiectelor din exteriorul pachetului. Spre deosebire de specificatia pachetului, portiunea de declaratii a corpului pachetului poate sa contina corpuri de subprograme.
Corpul pachetului nu este īntotdeauna necesar. De exemplu, daca specificatia pachetului declara numai constante si variabile, corpul pachetului nu este necesar.
Dupa ce pachetul a fost creat, aplicatiile pot face referire la tipurile acestuia, īi pot apela subprogramele, īi pot folosi cursoarele si pot genera exceptiile acestuia. Dupa creare, pachetul este stocat īn baza de date si poate fi folosit de toti utilizatorii.
Prima etapa a crearii unui pachet o reprezinta crearea specificatiei acestuia. Specificatia declara publice obiectele schemei continute īn corpul pachetului.
Pentru a crea o specificatie, lansati comanda create package. Exemplul urmator ilustreaza sintaxa necesara pentru crearea specificatiei unui pachet:
create or replace package pachet_inventar as
function calcul_inventar(cant integer, cod articol varchar2(15)) return integer;
procedure modif_inventar(cant integer}; end pachet_inventar;
Remarcati utilizarea clauzei or replace. Aceasta recreeaza specificatia pachetului, conservānd toate privilegiile existente.
Dupa crearea specificatiei, creati corpul pachetului. Corpul pachetului este o colectie de obiecte ale schemei, care au fost declarate īn specificatie. Aceste obiecte sau subprograme ale pachetului sunt accesibile īn exteriorul pachetului numai daca specificatiile lor sunt incluse īn specificatia pachetului.
Pe lānga definitiile obiectelor declarate īn specificatia pachetului, corpul pachetului poate sa contina si declaratii private. Aceste obiecte private sunt locale pachetului din punct de vedere al domeniului si sunt destinate prelucrarilor din interiorul pachetului. Obiectele externe nu pot sa faca referire sau sa apeleze obiectele interne ale unui alt pachet.
Daca efectuati o initializare a corpului pachetului, aceasta este executata o singura data, si anume atunci cānd se face prima data referire la pachet.
Exemplul urmator ilustreaza corpul pachetului a carui specificatie a fost prezentata īn exemplul anterior:
create or replace package body pachet__inventar is
function calcul_inventar
(cant integer,
cod_articol varchar2(15))
return integer is ;
cant_noua integer;
begin
cant_noua:=cant * 6;
inser"t into lst_inventar values
(cant_noua, cod_articol); return(cant noua); end calcul_īnventar;
procedure modif_inventar(cant integer);
begin
delete from user_01.lst_inventar
where cant_inventar<100(JO;
end;
begin -- aici incepe initializarea pachetului insert into audit_inventar values (sysdate, user); end pachet_inventar;
Partea finala a corpului pachetului din exemplul precedent reprezinta initializarea pachetului. Prin definitie, ea este rulata o singura data, si anume atunci cānd se face prima data referire la pachet.
Pentru a crea specificatia sau corpul unui pachet īn schema dumneavoastra, trebuie sa posedati privilegiul de sistem create procedura. Pentru a crea un pachet īn schema altui utilizator, trebuie sa posedati privilegiul de sistem create any procedure
Atunci cānd este invocat un subprogram al unui pachet, sistemul Oracle parcurge trei etape īn vederea executarii acestuia:
Verifica drepturile de acces ale utilizatorului: confirma daca utilizatorul poseda privilegiul de sistem execute pentru subprogramul vizat.
Verifica validitatea subprogramului prin consultarea dictionarului de date. Daca obiectul este invalid, acesta este automat recompilat īnainte de a fi executat.
Subprogramul este executat.
Pentru a face referire la subprogramele sau la obiectele unui pachet, trebuie sa folositi notatia cu punct. Sintaxa generala a notatiei cu punct este urmatoarea:
nume_pachet.nume_tip
nume_pachet.nume_obiect
nume_pachet.nume_subprogram
Pentru a face referire la variabila sold_maxim din pachetul numit inventar, instructiunea de referire va arata īn felul urmator:
declare
sold_curent number; begin
if inventar.sold_maxim < sold_curent then end if;
Atunci cānd sistemul Oracle executa un subprogram continut īntr-un pachet, este creat un punct de salvare implicit. Daca subprogramul esueaza datorita unei exceptii netratate, īnainte de revenirea īn mediul gazda, Oracle deruleaza īnapoi tranzactia, anulānd astfel toate modificarile efectuate de subprogramul respectiv.
Puteti crea sinonime pentru pachetele rezidente īn urmatoarele scopuri:
Pentru ascunderea identitatii numelui pachetului si a proprietarului acestuia
Pentru a asigura transparenta localizarii pachetelor rezidente situate la distanta
Sinonimele pot fi folosite pentru invocarea pachetelor si altor subprograme. Puteti deci sa creati un sinonim care sa faca referire la un pachet, īn schimb nu puteti crea sinonime pentru procedurile individuale definite īn interiorul pachetului.
Pentru a recompila un pachet, folositi instructiunea alter package cu cuvāntul cheie compile. Aceasta recpmpilare explicita elimina necesitatea recompilarilor implicite īn timpul executiei si previne eventualele erori aferente recompilarii īn timpul executiei si degradarea performantelor, īn general, se practica recompilarea explicita a unui pachet dupa modificarea acestuia.
Recompilarea unui pachet duce la recompilarea tuturor obiectelor definite īn interiorul pachetului. Recompilarea nu modifica nici definitia pachetului, nici definitiile obiectelor acestuia.
Īn exemplul urmator, prima instructiune recompileaza numai corpul pachetului. A doua instructiune recompileaza īntregul pachet, atāt specificatia, cāt si corpul acestuia:
alter package pachet_inventar compile body;
alter package pachet_inventar compile package;
Folosind utilitarul dbms_utility, pot fi compilate toate pachetele din schema dumneavoastra:
execute dbms_utility.compile_all;
Pachetele si obiectele pachetelor trebuie sa se gaseasca īn schema dumneavoastra; īn caz contrar, trebuie sa posedati privilegiul de sistem alter any procedare.
Distrugerea unui pachet este sinonima cu eliminarea pachetului din baza de date. Atunci cānd pachetul este distrus, sunt invalidate obiectele locale care depind de specificatia pachetului. Daca un program īncearca sa faca referire la aceste ^obiecte locale invalide, sistemul Oracle īncearca automat sa recompileze pachetul, īn cazul īn care pachetul nu a fost recreat īntre timp, este generata o eroare.
Īn exemplul urmator, prima instructiune distruge corpul pachetului inventar. A doua instructiune distruge īntregul pachet:
drop package body inventar;
drop package inventar;
Atunci cānd distrugeti numai corpul unui pachet, nu si specificatia acestuia, toate obiectele dependente ramān valide, īn schimb, nu puteti apela nici una dintre procedurile sau functiile rezidente declarate īn specificatia pachetului, pāna cānd nu recreati corpul pachetului.
Nu puteti elimina direct un subprogram din corpul unui pachet. Trebuie sa recreati pachetul fara obiectul respectiv.
Pentru a distruge un pachet, acesta trebuie sa se gaseasca īn schema dumneavoastra; īn caz contrar, trebuie sa posedati privilegiul de sistem drop any procedure.
Pentru a a simplifica depanarea, programul Oracle va pune la dispozitie un pachet public numit dbms_output, care contine informatii de depanare pentru pachetul dumneavoastra. Puteti genera informatii de depanare din interiorul unei aplicatii prin lansarea comenzilor put sau put_line. Aceste comenzi depun informatiile de depanare īntr-un tampon creat de pachetul dbms_output. Pentru a afisa continutul tamponului, pur si simplu tastati comanda set server output on la promptul SQL*Plus sau 'din programul SQL*DBA.
Exemplul urmator ilustreaza comanda put_line pe care o puteti include īn interiorul procedurii apartinānd pachetului:
/*Specificatia unei proceduri stocate īntr-un pachet.*/
create package user_01.articole as
/* Corpul subprogramului incepe aici.*/
procedure articole (cant integer, cod_articol integer)
as begin
update registru
put line ('Cantitate Initiala =' |] registru.cant)
/*LTnie de depanare*/
set registru.cant = registru.cant + cant
where cod_registru = cod_articol
put_line ('Noua Cantitate =' ]| registru.cant)/*Linie de depanare*/
Instructiunile urmatoare sunt lansate de la linia de comanda a utilitarului SQL*DBA īn vederea executarii procedurii articole si afisarii informatiilor de depanare.
SQLDBA> set server on
SQLDBA> execute user_01.articole
īn continuare sunt prezentate rezultatele executarii acestor instructiuni. Aceste informatii sunt preluate din tamponul dba_output
Cantitate Initiala = 100 Noua Cantitate = 200 Cantitate Initiala = 200 Noua Cantitate = 325 ... si asa mai departe
īn interiorul corpului unui pachet, puteti defini subprograme, cursoare si declaratii private de tipuri si de obiecte. Obiectele care sunt declarate īn corpul pachetului nu pot fi utilizate'decāt īn pachetul respectiv. Cu alte cuvinte, codul PL/SQL din exteriorul pachetului nu poate face referire la nici una dintre variabilele care au fost declarate private īn interiorul pachetului.
Orice articole declarate īn specificatia pachetului sunt vizibile īn exteriorul pachetului. Acest lucru permite codului PL/SQL sa faca referire la obiectele din interiorul pachetului. Aceste obiecte declarate īn specificatia pachetului se numesc publice.
Variabilele, cursoarele si constantele īsi pot schimba valoarea īn timp si exista pentru un anumit interval de timp. Aceasta durata de viata poate varia, īri functie de locul īn care apare declaratia, īn cazul procedurilor de sine-statatoare, variabilele, cursoarele si constantele persista numai pe durata apelului procedurii. Ele īsi pierd valoarea atunci cānd executia procedurii se īncheie.
Daca variabilele, cursoarele si constantele sunt declarate īn specificatia sau īn corpul unui pachet, atunci valorile lor exista pe toata durata sesiunii utilizatorului, īn schimb, valorile lor se pierd atunci cānd pachetul este recompilat.
Un pachet nu poate fi decāt fie valid, fie invalid. Pachetul este considerat valid daca nici o parte a propriului cod sursa sau a obiectelor la care face referire nu a fost distrusa, īnlocuita sau modificata de la ultima recompilare a pachetului.
Īn caz contrar, pachetul este considerat invalid. Atunci cānd un pachet devine invalid, sistemul Oracle invalideaza toate obiectele care fac referire la pachetul respectiv.
Dependenta de pachete
Īn timpul recompilarii unui pachet, sistemul Oracle invalideaza toate obiectele dependente. Obiectele dependente reprezinta subprogramele de sine-statatoare sau stocate īn pachete, care apeleaza sau fac referire la obiectele declarate īn specificatia recompilata. Daca programul altui utilizator apeleaza sau face referire la un obiect dependent, īnainte ca acesta sa fie recompilat, Oracle īl recompileaza automat īn timpul executiei.
Īn timpul recompilarii pachetelor, sistemul Oracle determina daca obiectele de care depinde corpul pachetului sunt valide. Daca oricare dintre aceste obiecte este invalid, programul Oracle īl recompileaza īnainte de a recompila corpul pachetului. Daca recompilarea se īncheie cu succes, corpul pachetului devine valid. Daca sunt detectate erori, sunt generate mesajele de eroare corespunzatoare, iar corpul pachetului ramāne invalid.
Sistemul Oracle permite existenta īn acelasi pachet a mai multor proceduri cu acelasi nume. Aceasta tehnica, cunoscuta sub' numele de supraīncarcare, este utila īn special atunci cānd vreti sa executati aceeasi procedura de mai multe ori, īnsa cu argumente de tipuri diferite. Un exemplu de ^utilizare a supraīncarcarii procedurilor īl reprezinta pachetul dbms_output. īn acest pachet, procedura put_line este apelata de mai multe ori, pentru a genera linii de iesire cu tipuri de date diferite.
Dictionarul de date al programului Oracle poseda mai multe vederi care furnizeaza informatii despre pachete:
all errors |
O lista a erorilor curente ale tuturor obiectelor accesibile utilizatorului |
all source |
Textul sursa al tuturor obiectelor rezidente accesibile utilizatorului |
dba errors |
Erorile curente ale tuturor obiectelor rezidente din baza de date |
Dba object size |
Toate obiectele PL/SQL din baza de date |
dba source |
Textul sursa al tuturor obiectelor rezidente din baza de date |
user errors |
Erorile curente ale tuturor obiectelor rezidente apartinānd unui utilizator |
user source |
Textul sursa al tuturor obiectelor rezidente apartinānd utilizatorului |
user object size |
Obiectele PL/SQL ale utilizatorului |
Exemplul urmator interogheaza vederea user_errors pentru a obtine informatii despre erorile curente din pachet:
LINE |
TYPE |
NAME |
TEXT |
PROC |
LST_CANT |
PL/SQL-00387 : into variable cannot be a database object PL/SQL: SQL statement ignored |
Un pachet este un obiect al bazei de date care reprezinta o unitate logica de tipuri, obiecte si subprograme īnrudite. Pachetul poate fi apelat sau referit de alte pachete, programe de sine-statatoare si declansatori.
Īn acest capitol, ati vazut care sunt avantajele pachetelor fata de procedurile si functiile de sine-statatoare. Unul dintre aceste avantaje este reducerea procesarilor suplimentare ale serverului datorata posibilitatii de stocare īn memorie a mai multor obiecte simultan.
Pachetele sunt īntāi declarate si apoi sunt definite. Daca crearea unui pachet se īncheie cu succes, pachetul este stocat īn baza de date. Pachetele pot contine atāt obiecte publice, cāt si obiecte private. Obiectele publice pot fi apelate sau referite de orice utilizator, īn schimb obiectele private pot fi utilizate numai īn interiorul pachetului.
|