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.
|