ALTE DOCUMENTE
|
|||||||
O procedura rezidenta reprezinta o un set de instructiuni SQL si PL/SQL grupate logic si care efectueaza o anumita sarcina. Aceasta procedura este considerata obiect al schemei si este pastrata în baza de date. O procedura poate fi executata interactiv, folosind instrumente Oracle cum ar fi SQL*DBA sau explicit, prin intermediul unei aplicatii.
Procedurile rezidente au mai multe parti. Partea declarativa contine declaratii de tipuri, cursoare, constante, variabile, exceptii si subprograme imbricate. Partea executabila contine instructiuni care controleaza executia si manipularea datelor. Uneori, procedura contine o parte de tratare a exceptiilor care se ocupa cu exceptiile generate în timpul executiei.
Procedurile pot fi definite folosind instrumente Oracle care suporta limbajul PL/SQL, cum ar fi SQL*Plus. Procedurile pot fi declarate în blocuri PL/SQL, în pa 18518k109s chete si în alte proceduri. Procedurile trebuie declarate la sfârsitul sectiunii declarative, dupa toate celelalte obiecte ale programului.
Procedurile sunt create pentru rezolvarea unei anumite probleme sau sarcini. Aceste proceduri rezidente ofera urmatoarele avantaje:
PL/SQL va permite sa adaptati procedurile dumneavoastra unor cerinte specifice.
Aceste proceduri au structura modulara. Cu alte cuvinte, ele va permit sa împartiti un program în unitati bine definite si usor de gestionat.
Deoarece sunt stocate în baza de date, aceste proceduri sunt reutilizabile.
Odata validate, ele pot fi folosite în mod repetat, fara recompilarea lor sau redistribuirea lor în retea.
Îmbunatatesc securitatea bazei de date. Puteti restrânge accesul la baza de date, nepermitând utilizatorilor sa acceseze datele decât prin intermediul procedurilor rezidente.
Puteti îmbunatati utilizarea memoriei prin partajarea resurselor de memorie.
O procedura rezidenta este un subprogram Oracle care efectueaza o anumita sarcina. Paragrafele urmatoare prezinta etapele necesare pentru crearea, modificarea si întretinerea procedurilor rezidente.
Administratorul bazei de date este responsabil pentru rularea scriptului catproc. sql. Acest script ruleaza automat toate scripturile necesare optiunii procedurale a programului Oracle.
Procedurile rezidente au doua parti: specificatia si corpul. Specificatia declara procedura si contine numele procedurii rezidente, precum si numele si tipurile argumentelor. Corpul defineste procedura si consta dintr-un bloc de cod PL/SQL.
Comanda create procedure creeaza o procedura de sine-statatoare. In continuare, sunt enumerati parametrii care pot fi folositi în instructiunea create:
In |
Acest parametru specifica faptul ca programului apelat trebuie sa i se furnizeze o valoare. Parametrului in nu i se poate atribui o valoare, întrucât el se comporta ca o constanta. Valoarea reala care corespunde parametrului poate fi o constanta, un sir de caractere, o variabila initializata sau o expresie. |
Out |
Acest parametru specifica faptul ca procedura returneaza o valoare programului apelant. Acest parametru se comporta ca un parametru neinitializat; prin urmare, valoarea acestuia nu poate fi atribuita altei variabile. Valoarea reala care corespunde acestui parametru trebuie sa fie o variabila. Ea nu poate fi un sir de caractere, o constanta sau o expresie. Parametrului out trebuie sa i se atribuie o valoare în interiorul subprogramului. |
Inout |
Acest parametru specifica faptul ca trebuie sa transferati o valoare procedurii si ca, dupa executie,' procedura returneaza 6 valoare programului apelant. |
or replace |
Acest parametru recreeaza procedura daca aceasta exista deja. |
Exemplul urmator creeaza o procedura simpla. Procedura primeste doua argumente, cod_articol si cant:
/* Procedura rezidenta numita user_01.articole. Urmatoarea linie de cod reprezinta specificatia procedurii rezidente.*/
create procedure user_01.articole (cod_articol, number, cant number)
/* Aici incepe corpul procedurii.*/
as begin
update registru
set registru.cant = registru.cant + cant
where cod_registru = cod_articol;
end;
De obicei, procedurile sunt create ca obiecte de sine-statatoare ale schemei. Puteti totusi sa creati o procedura ca parte a unui pachet. Pentru informatii suplimentare despre pachete, consultati Capitolul 24, "Pachete".
Instructiunea return determina întreruperea imediata a executiei subprogramului si revenirea în programul apelant. Executia continua- în programul apelant cu instructiunea care urmeaza dupa apelul procedurii.
În proceduri, instructiunea return nu poate sa contina o expresie. Singurul ei scop îl constituie cedarea controlului programului apelant înainte de atingerea sfârsitului procedurii.
Pentru a recompila în mod explicit o procedura rezidenta, lansati comanda alter procedure. Aceasta comanda trebuie folosita numai pentru procedurile de sine-statatoare, nu si pentru procedurile interne ale pachetului.
Recompilarea unei proceduri nu modifica declaratia sau definitia procedurii. Pentru a face acest lucru, trebuie sa folositi comanda create procedure cu clauza or replace.
Daca recompilarea unei proceduri se încheie cu succes, procedura devine o procedura valida, care poate fi executata fara recompilare la executie. Daca recompilarea esueaza, procedura devine invalida si trebuie depanata. Pentru a simplifica munca de depanare, sistemul Oracle ofera un pachet public, numit dbms_output, care contine informatii de depanare.
Puteti folosi comanda alter procedure pentru a recompila în mod explicit o procedura invalida. Dupa compilarea procedurii, ea nu mai trebuie recpmpilata implicit în timpul executiei. Aceasta duce la eliminarea procesarilor suplimentare si a erorilor de compilare la executie.
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, tastati comanda set server output on la promptul SQll*Plus din interiorul programului SQL*DBA.
Exemplul urmator ilustreaza comanda put_line pe care o puteti include în procedura dumneavoastra:
create or replace procedure articole (cod_articol number, increment_cant number)
as
cant_noua number(5);
begin
select cant into cant_noua
from registru
where cod_registru = cod_articol;
dbms_outpu~t .put_line ('Cantitate Initiala = ' li cant_noua) ;
update registru
set registru.cant = registru.cant + increment_cant
where cod_registru = cod_articol;
select cant into cant_noua
from registru
where cod_registru = cod_articol;
dbms_output.put_line('Cantitate Curenta = ' !! cant_noua);
Instructiunile urmatoare sunt lansate la linia de comanda a utilitarului SQL*DBA pentru executarea procedurii articole si pentru afisarea informatiilor de depanare:
set serveout on
execute user_01. Articole(cod,cant)
În continuare, sunt prezentate rezultatele executiei acestor instructiuni. Aceste informatii sunt generate din tamponul dba_output:
Cantitate Initiala = 100
Cantitate Curenta= 200
Cantitate Initiala = 200
Cantitate Curenta = 325
... si asa mai departe
O procedura de sine-statatoare nu poate fi modificata; ea trebuie fie înlocuita cu o noua definitie, fie distrusa si re-creata.
De exemplu, nu puteti sa modificati pur si simplu una dintre instructiunile PL/SQL ale procedurii, ci trebuie sa recreati procedura cu modificarea respectiva.
Atunci când înlocuiti o procedura, trebuie sa includeti clauza or replace în instructiunea create procedure. Clauza or replace se foloseste pentru a înlocui o versiune mai veche a unei proceduri cu noua versiune. Aceasta înlocuire pastreaza intacte toate privilegiile; în consecinta, nu este nevoie sa le re-creati. în schimb, daca distrugeti procedura si o re-creati, privilegiile sunt distrase si trebuie sa le reconstruiti. Daca încercati sa'folositi comanda create procedure pentru o procedura care exista deja, 6racle genereaza un mesaj de eroare.
Exemplul urmator recreeaza procedura numita "articole" din schema utilizatorului user_01:
/* Procedura rezidenta numita user_01.articole. Urmatoarea linie de cod reprezinta noua specificatie a procedurii rezidente.*/ -
create or replace procedure user_01.articole (cod_articol number, cant number)
/* Aici incepe corpul procedurii.*/
as begin
update registru
set registru.cant = (registru.cant*.05) + cant
where cod_registru = cod_articol;
end;
Procedurile pot fi apelate din diverse medii, inclusiv din utilitarele SQL*Plus si SQL*Forms. De asemenea, procedurile pot fi apelate din alta procedura sau dintr-un declansator.
De exemplu, procedura suma_articole poate fi apelata din alta procedura sau dintr-un declansator cu instructiunea urmatoare:
suma_articole(cant, nr) ;
Iata un exemplu în care aceeasi procedura este executata din utilitarul SQL*DBA:
execute suma_articole(cant, nr) ;
Exemplul urmator ilustreaza apelarea unei proceduri dintr-un program precompilat:
exec sql execute
begin
suma_articole(:cant, nr);
end
end-exec
Pentru a executa o procedura, trebuie sa posedati privilegiul de sistem execute pentru procedurile de sine-statatoare, respectiv privilegiul de sistem execute any procedure pentru celelalte proceduri.
Pentru a apela o procedura dintr-o baza de date situata la distanta, includeti în instructiune o legatura la baza de date corespunzatoare, dupa cum se poate vedea în exemplul urmator. Acest exemplu utilizeaza SQL*DBA pentru executarea procedurii:
execute suma_articole@prod_011(:cant, nr);
O declaratie anticipata este pur si simplu declaratia unei proceduri urmata de caracterul punct si virgula (;). Oracle impune declararea tuturor identificatorilor înainte de utilizarea acestora. Acest lucru înseamna ca procedurile trebuie declarate înainte de a fi apelate; în general, chiar asa se procedeaza, în schimb, în anumite situatii, aveti nevoie de mecanisme de genul declaratiilor anticipate. Declaratiile anticipate va dau posibilitatea sa apelati o procedura înainte ca aceasta sa fi fost creata, urmând ca aceasta sa fie creata ulterior, ceea ce va permite sa definiti procedurile în ordine logica sau alfabetica si, de asemenea, sa grupati procedurile dintr-un pachet. Declaratiile anticipate va permit sa declarati proceduri recursive. Aceste proceduri se apeleaza reciproc.
Exemplul urmator ilustreaza doua proceduri recursive care utilizeaza declaratii anticipate, în acest exemplu, este prezentata numai o parte a codului procedurilor:
declare
procedure calc_retrib (...) - declaratie anticipata
/* Gruparea subprogramelor cu logica comuna */
procedure prima_anuala (...) is
begin
calc_retrib (...)
end
/* Declaratia este in procedura prima_anuala */
procedure calc_retrib(...) is
begin
prima_anuala(...)
end
Pentru transferul informatiilor, procedurile folosesc parametri (variabile sau expresii). Parametrii care apar în declaratia procedurii si care sunt ^folositi în interiorul procedurii sunt cunoscuti sub numele de parametri formali. In schimb, parametrii care sunt transferati procedurii si cei returnati de procedura sunt cunoscuti sub numele de parametri actuali.
Tipul parametrului actual trebuie sa fie compatibil cu tipul parametrului formal corespunzator. De exemplu, PL/SQL nu poate^converti un parametru actual de tip date într-un parametru formal de tip long. în acest caz, Oracle returneaza un mesaj de eroare. Aceeasi regula este valabila si pentru valorile returnate.
La transmiterea parametrilor, poate aparea o problema daca numele unui parametru este folosit de doua ori în apelul unei proceduri si ambele aparitii nu sunt formale, de exemplu, daca o variabila globala apare în' apelul procedurii si apoi este referita din procedura. Acest gen de operatii poate cauza rezultate nedeterminate.
Atunci când este apelata o procedura, trebuie sa transferati câte o valoare (parametru actual) pentru fiecare parametru formal al procedurii. Daca transferati parametrii formali prin valoare, aceste valori trebuie sa apara în aceeasi ordine în care apar parametrii formali în declaratia procedurii. Daca transferati parametrii prin numele lor (transfer prin referinta),'acestia pot sa apara în orice ordine. Daca pentru aceeasi procedura, o parte dintre parametri îi transferati prin valoare si o alta parte îi transferati prin nume, parametrii transferati prin valoare trebuie sa apara în aceeasi ordine ca si parametrii formali corespunzatori si trebuie sa preceada parametrii transferati prin nume.
Daca în declaratia procedurii apar valorile prestabilite ale parametrilor, puteti sa transferati procedurii un numar mai mic de parametri decât numarul celor care apar în declaratie. Daca omiteti sa transferati un parametru actual, valoarea acestuia va fi egala cu valoarea prestabilita din declaratia procedurii.
Variabilele, cursoarele si constantele îsi pot schimba valoarea în timp si au un anumit timp de viata. Aceasta durata de viata poate varia în functie de locul în care apare declaratia, în cazul procedurilor de sine-statatoare, variabilele, cursoarele si constantele persista numai pe durata apelului procedurii si dispar atunci când executia procedurii se încheie.
Daca variabilele, cursoarele si constantele sunt declarate în specificatia sau în corpul unui pachet, atunci valorile lor persista pe toata durata sesiunii utilizatorului. Valorile lor se pierd atunci când se termina sesiunea curenta sau când pachetul este recompilat.
Puteti crea sinonime pentru procedurile rezidente în urmatoarele scopuri:
Pentru ascunderea identitatii numelui procedurii si a proprietarului acesteia
Pentru a asigura transparenta localizarii procedurilor rezidente situate la distanta
Sinonimele pot fi folosite pentru invocarea procedurilor si altor subprograme. Puteti sa creati un sinonim care sa faca referire la un pachet, în schimb nu puteti crea sinonime pentru procedurile individuale definite în interiorul pachetului.
Dictionarul de date al sistemului Oracle poseda mai multe vederi care furnizeaza informatii despre proceduri:
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 |
elba 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 toate procedurile detinute de utilizatorul curent:
select line, type, name, text from user_errors;
Date de iesire: |
|||
LINE |
TYPE |
NAME |
TEXT |
PROC |
LST_CANT |
PL/SQL-00387: into variable cannot be a database object PL/SQL: SQL statement ignored |
Pentru a distruge o procedura, lansati instructiunea SQL drop procedura. Instructiunea urmatoare distruge procedura cant_articole: drop procedure cant_articole;
Pentru a distruge o procedura, aceasta trebuie sa se gaseasca în schema dumneavoastra; în caz contrar, trebuie sa posedati privilegiul de sistem drop any procedure.
Sistemul Oracle permite existenta în acelasi pachet a mai multor proceduri cu acelasi nume. Aceasta tehnica, cunoscuta sut) 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 Unii de iesire cu tipuri de date diferite.
Supraîncarcarea numelui unei proceduri este permisa numai într-un bloc, într-un subprogram sau într-un pachet. Nu puteti supraîncarca o procedura de sine-statatoare. Nu puteti supraîncarca doua proceduri ai caror parametri difera numai prin nume sau prin mod. Supraîncarcarea procedurii calcul retrib din exemplul urmator este incorecta. A doua procedura difera numii prin modul primului parametru.
procedura calcul_retrib (ore in number, rata number) is begin
end calcul_retrib
procedure calcul_retrib (ore out number, rata number) begin
end calcul_retrib
O procedura recursiva o procedura care se autoapeleazâ. Fiecare apel recursiv creeaza o noua instanta a fiecarui obiect declarat în procedura, inclusiv parametri, variabile, cursoare si exceptii. De asemenea, sunt create noi instante ale instructiunilor SQL pentru fiecare nivel al procedurii recursive.
O procedura recursiva trebuie sa fie capabila sa-si încheie executia la un moment predefinit, în caz contrar ea urmând sa functioneze la infinit. Acest punct final este definit printr-o conditie de încheiere. Exemplul urmator foloseste o instructiune conditionala pentru încheierea ciclului recursiv.
function calcul_inventar
begin
if cant >= :cant_max then - conditie de încheiere
return l
else
/* apel recursiv;*/
return cant * calcul_inventar (cant * :cant_articol)
end if
end calcul_inventar;
Fiti precaut în legatura cu utilizarea apelurilor recursive. Daca plasati un apel recursiv în interiorul unui cursor for-loop sau între instructiunile open si close, la fiecare apel este deschis un cursor. Acest lucru poate duce la deschiderea unui numar de cursoare care sa violeze numarul maxim de cursoare deschise, permise de parametrul de initializare open_cursor.
O procedura rezidenta reprezinta un grup de instructiuni SQL si PL/SQL pe care îl puteti apela cu ajutorul unui nume. In acest capitol, ati facut cunostinta cu partile componente ale unui proceduri si ati învatat sa creati si sa folositi proceduri. '
Procedurile se folosesc pentru a asigura structura modulara a unui program, pentru a promova reutilizarea codului si pentru a simplifica întretinerea.
Procedurile, asemeni multor alte subprograme PL/SQL, pot fi create cu obiecte de sine-statatoare ale schemei sau ca parti ale unui pachet. Procedurile pot fi apelate de functii, pachete sau alte proceduri.
|