Documente Academic
Documente Profesional
Documente Cultură
Cuprins
Introducere in PL/SQL.............................................................................................1 Cuprins................................................................................................................... 2 Introducere............................................................................................................. 4 1.1 Definirea mediului PL/SQL............................................................................4 1.2 Caracteristici generale:.................................................................................5 Blocuri PL/SQL........................................................................................................5 2.1 Componentele unui bloc PL/SQL....................................................................5 2.3 Operatori in PL/SQL.......................................................................................6 Operator........................................................................................................... 6 2.4 Funcii SQL suportate n PL/SQL....................................................................7 2.5 Comenzi SQL suportate n PL/SQL.................................................................7 VARIABILE............................................................................................................... 8 3.1 Declarare i iniializare..................................................................................8 3.2 Tipuri de variabile:........................................................................................8 3.3 Atributul %TYPE.............................................................................................9 ..........................................................................................................................10 3.4 Variabile de mediu sau variabile de legtur ale aplicaiilor gazd (BIND VARIABLES)....................................................................................................... 10 3.5 Variabile de substituie................................................................................11 STRUCTURI FUNDAMENTALE DE PROGRAMARE.................................................11 4.1 Structuri alternative ...................................................................................11 4.2 Structuri repetitive......................................................................................13 4.3 Tipuri de date compuse...............................................................................14 CURSORUL N PL/SQL............................................................................................15 5.1 CURSORUL IMPLICIT....................................................................................16 5.2 CURSORUL EXPLICIT ...................................................................................16 5.3 Gestiunea implicit a cursorului prin utilizarea unui ciclu FOR....................18 5.4 Utilizarea unui cursor direct n cadrul instruciunii FOR...............................18 5.5 Utilizarea cursorului cu parametru..............................................................19 TRATAREA EXCEPIILOR.......................................................................................21 6.1 Tipuri de excepii.........................................................................................21 6.2 Tratarea excepiilor predefinite ale Serverului Oracle.................................22 6.3 Tratarea excepiilor non-predefinite Oracle Server.....................................23 6.4 Tratarea excepiilor definite de utilizator....................................................24 2
6.5 Propagarea excepiilor................................................................................25 Subprograme PL/SQL............................................................................................26 7.1 Proceduri..................................................................................................... 26 7.2 Functii......................................................................................................... 28 7.3 Pachete de subprograme............................................................................29 7.4 Supraincarcarea subprogramelor................................................................30 Triggeri pe baza de date......................................................................................31 8.1 Clauzele INSERTING, UPDATING, DELETING................................................32 8.2 Clauza INSTEAD OF.....................................................................................33 8.3 Gestiunea triggerilor: .................................................................................34 Aplicatie................................................................................................................ 35
Introducere
SQL (Structured Query Language - Limbaj Structurat de Interogare) este un limbaj de programare specific pentru manipularea datelor in sistemele de manipulare a bazelor de date relationale (RDBMS), iar la origine este un limbaj bazat pe algebra relationala. Acesta are ca scop inserarea datelor, interogatii, actualizare si stergere, modificarea si crearea schemelor, precum si controlul accesului la date. A devenit un standard n domeniu (standardizat ANSIISO), fiind cel mai popular limbaj utilizat pentru creearea, modificarea, regsirea i manipularea datelor de ctre SGBD-urile (Sistemele de Gestiune a Bazelor de Date) relaionale. Pe lng versiunile standardizate ale limbajului, exist o mulime de dialecte i variante, unele proprietare, fiind specifice anumitor SGBD-uri i de asemenea coninnd extensii pentru a suporta SBD-urile (Sistemele de Baze de Date) obiectuale (obiectualrelaionale). SQL permite att accesul la coninutul bazelor de date, ct i la structura acestora.
Figura 1 - Funcionarea mediului PL/SQL Principalele avantaje ale PL/SQL sunt: Integrarea construciilor procedurale cu SQL
4
Creterea performanelor prin nglobarea ntr-un singur bloc a mai multor instruciuni SQL. Aplicaia poate trimite blocul o singur dat ctre baza de date sau ctre serverul de aplicaii, reducnd semnificativ traficul n reea i numrul de apeluri ctre baza de date. Modularizarea programelor prin utilizarea de blocuri de program care pot fi secveniale sau mbricate. Este integrat n uneltele de dezvoltare Oracle, cum sunt Oracle Forms i Oracle Reports. Portabilitate Modulele PL/SQL pot fi executate pe toate platformele n care sunt instalate baze de date Oracle (WINDOWS, LINUX, UNIX). Se pot crea biblioteci de programe reutilizabile pe orice platform. Suport toate tipurile de date din SQL (cu cteva extensii), precum i toate funciile SQL. Interceptarea eficient a erorilor.
Construciile PL/SQL conin structuri de control procedurale i comenzi descriptive SQL; PL/SQL este un limbaj procedural structurat pe bloc, programele putnd fi mprite n blocuri logice; Blocurile PL/SQL sunt procesate de motorul PL/SQL care poate fi rezident pe ORACLE SERVER sau pe un instrument de dezvoltare (ex.: Oracle Forms, Reports, JDeveloper etc.); Multe instrumente ORACLE au propriul motor PL/SQL (ex.: Oracle Forms, Reports, JDeveloper etc.); Tipurile de date din SQL pot fi folosite n PL/SQL; Programarea n PL/SQL este modularizat se utilizeaz blocurile care grupeaz instruciunile.
Blocuri PL/SQL
Orice unitate PL/SQL conine unul sau mai multe blocuri, complet separate sau imbricate.
operaiile efectuate cu variabilele PL/SQL n cadrul instruciunilor procedurale nu presupun accesarea bazei de date; se folosete (;) dup fiecare instruciune SQL sau instruciune de control PL/SQL; blocul PL/SQL se termin cu (;); se folosete (/) pentru a lansa un bloc anonim n bufferul SQL; o eroare n PL/SQL este tratat ca o excepie;
Blocurile anonime sunt nedenumite, nu sunt stocate in baza de date. Acestea se declara inline, in locul in care se doreste executia lor si se executa in momentul rularii. Blocurile anonime imbricate constau in imbricarea mai multe blocuri si se pot eticheta cu <<eticheta_bloc>> , iar variabilele din cadrul blocurilor se pot utiliza astfel: eticheta_bloc.variabila. Procedurile si functiile sunt blocuri PL/SQL cu un nume. Acestea se pot stoca la nivel de ORACLE SERVER(proceduri/funcii stocate) sau la nivel de aplicaie (DEVELOPER Forms si Reports). Pachete de programe - grupeaz proceduri, funcii. Declanatori pe baza de date - blocuri PL/SQL asociate tabelelor (de baz sau virtuale) i lansate automat n execuie cnd are loc o comanda de manipulare. Declanatori de aplicaie - blocuri PL/SQL asociate unor evenimente din cadrul aplicaiei (de exemplu: deplasarea mouse-ului, apsarea unui buton) i lansate n execuie automat.
Conversii n blocurile PL/SQL PL/SQL convertete tipurile de date dinamic (de exemplu: o valoare numeric la o variabil char); conversii implicite: caracter <-> numeric si caracter <->data; conversii explicite: se utilizeaz funciile TO_DATE, TO_NUMBER, TO_CHAR.
PL/SQL permite folosirea comenzilor de manipulare a datelor (LMD): SELECT INSERT UPDATE DELETE PL/SQL permite folosirea comenzilor de control al tranzaciilor: COMMIT ROLLBACK SAVEPOINT
Not: Un bloc PL/SQL nu este o tranzacie. Comenzile Commit/ Rollback/ Savepoint sunt independente de bloc, dar pot s apar n cadrul acestuia. PL/SQL NU suport comenzile de definire a datelor (LDD) CREATE ALTER DROP RENAME TRUNCATE PL/SQL NU suport comenzile din cadrul limbajului pentru controlul datelor (Data Control Language - DCL) GRANT REVOKE
VARIABILE
3.1 Declarare i iniializare
Declararea variabilelor se realizeaz n zona declarativ (delimitat prin DECLARE) a blocului (sau sub-blocului) iar iniializarea se poate face la declarare sau n zona de execuie (ntre BEGIN i END). Variabilele vor fi vizibile n restul blocului, respectiv i n blocurile incluse n el, mai puin n sub-blocurile n care numele lor este redefinit (ca n majoritatea limbajelor de programare structurate, semnificaia unui nume definit de utilizator ntr-un bloc/sub-bloc este dat de cea mai apropiat declaraie anterioar locului folosirii). Toate variabilele PL/SQL au un tip de dat, restricii i un ir valid de valori; Declararea si initializarea se face astfe: nume_variabila [CONSTANT] TIP_DATA [NOT NULL] [:= | DEFAULT expresie] _Constantele trebuie obligatoriu iniializate, iar ulterior nu i vor putea schimba valoarea; variabilele NOT NULL trebuie obligatoriu iniializate, iar ulterior nu vor putea primi valoarea NULL;
Se utilizeaz comanda SELECT cu clauza INTO pentru popularea variabilelor PL/SQL cu valori ale atributelor din tabele; cererile SELECT din cadrul blocurilor PL/SQL trebuie s furnizeze o singur linie rezultat (n caz contrar se semnaleaz eroare).
Exemplul de mai jos este replicat pe baza tabelelor realizate si mentionate la sfarsitul lucrarii. In acest caz am creat un bloc anonim in care rezultatul unei operatii efectuate asupra bazei de date Clienti este stocat intr-o variabila de tip varchar2:
3.4 Variabile de mediu sau variabile de legtur ale aplicaiilor gazd (BIND VARIABLES)
sunt variabile de legtur cu aplicaia n care ruleaz motorul PL/SQL; trebuie declarate n aplicaie (n mediul gazd) i pot fi accesate i modificate n cadrul blocurilor PL/SQL; dup terminarea execuiei blocului PL/SQL, variabila rmne n mediul gazd cu valoarea primit n urma rulrii blocului (i poate fi pasat altui bloc, realiznd astfel transmiterea de valori ntre blocurile PL/SQL); nu pot fi utilizate n cadrul procedurilor, funciilor sau pachetelor; se declar n afara blocului PL/SQL cu ajutorul cuvntului cheie VARIABLE: VARIABLE g_numevariabil TIP pentru declararea unei variabile host de tip NUMBER nu se specific precizia i scala; pentru utilizarea lor n cadrul unui bloc PL/SQL sau ntr-o fraz SQL din afara blocului se prefixeaz cu : :host_variabila:=v_variabila; se afieaz n afara blocului cu ajutorul comenzii PRINT (la afiare variabila nu se va prefixa cu :) PRINT numevariabila
10
secvcom2 END IF; IF cond1 THEN secvcom1 ELSE IF cond2 THEN secvcom2 END IF; END IF;
Structura CASE ... WHEN... THEN... Sunt 2 variante: expresii CASE (CASE Expressions) care intorc un rezultat intr-o variabila. Se termina cu END sintaxa CASE (CASE Statement) care executa o anumita instructiune. Se termina cu END CASE, iar fiecare rand se termina cu ; CASE Expressions: Variabila:= CASE [Selector]
12
WHEN expression1 THEN result1 WHEN expression2 THEN result2 ----------------------------------------WHEN expressionN THEN resultN [ELSE result N+1] END;
(nume_cmp
TIP_DATA
[,nume_cmp
14
Pentru a defini un record pe baza coloanelor unei tabele se folosete %rowtype . In acest caz numele elementelor din record au acelai nume ca i coloanele tabelei, acelai tip de date i se gsesc n aceeai ordine. Tipuri de tabele INDEX BY TYPE nume_tab IS TABLE OF {TIP_DATA [variabila%type | tabela.coloana%type [NOT NULL]| tabela%rowtype} INDEX BY PLS_INTEGER|BINARY_INTEGER|VARCHAR2(dimensiune); v_tab nume_tab; Adresarea se realizeaz cu v_tab(index).cmp; Indexul este unic, dar n ordine aleatorie i poate fi negativ. Intervalul pt PLS_INTEGER este (-2147483647, 2147483647) Se pot utiliza urmatoarele proprieti i metode: v_tab.EXISTS(i) v_tab.COUNT v_tab. FIRST i v_tab.LAST v_tab. PRIOR(i) i v_tab.NEXT(i) v_tab.DELETE sau v_tab.DELETE(i) sau v_tab.DELETE(i,j)
CURSORUL N PL/SQL
Atunci cnd se execut o comand SQL, Oracle Server deschide o zon de memorie (context area) n care comanda este executat. Cursorul este un pointer ctre aceast zon n PL/SQL se utilizeaz dou tipuri de cursoare: implicit: declarat pentru toate instruciunile PL/SQL de tip LMD (INSERT/UPDATE/DELETE);
15
Exemplu: Se sterg intrari din tabelul Costuri si se contorizeaza numarul de randuri stere:
16
nume_cursor%ISOPEN - evaluat la TRUE n cazul n care cursorul este deschis; nume_cursor %NOTFOUND - evaluat la TRUE n cazul n care cel mai recent FETCH nu a returnat nici o linie; nume_cursor %FOUND - complementul lui %NOTFOUND; nume_cursor %ROWCOUNT - are ca valoare numrul liniilor returnate pn n momentul curent. Prelucrarea cursorului explicit presupune parcurgerea urmtoarelor etape:
se declar variabilele n care vor fi ncrcate valorile corespunztoare unei linii din cursor; se declar cursorul explicit, specificndu-se un nume pentru acesta i definindu-se interogarea de procesat n cadrul lui: DECLARE nume_cursor IS SELECT........................;
se deschide cursorul prin intermediul instruciunii OPEN, care execut interogarea i legarea tuturor variabilelor referite. nregistrrile returnate de interogare sunt desemnate drept set activ de date, care pot fi de acum ncrcate. OPEN nume_cursor; utilizndu-se instruciunea FETCH, se ncarc linia curent din cursor n variabile. Fiecare ncrcare determin mutarea pointerului cursorului la linia urmtoare din setul activ de date. FETCH nume_cursor INTO var1, var2,..............;
este nchis cursorul prin instructiunea CLOSE, care dezafecteaz setul activ de linii. Cursorul poate fi din nou deschis pentru a stabili un nou set activ de linii. CLOSE nume_cursor; Pentru a procesa liniile unui cursor explicit se definete de obicei o bucl pentru executarea unui FETCH n fiecare iteraie. n final, toate liniile din setul activ sunt procesate i un FETCH executat fr succes poziioneaz atributul %NOTFOUND pe TRUE. naintea primului FETCH, %NOTFOUND se evalueaz la NULL, ca i n cazul n care FETCH nu se execut niciodat cu succes. Un exemplu de cursor explicit se poate observa in figura de mai jos in care un tabel nou creat este populat cu valori stocate in cursor:
17
..................................................................................... END LOOP; Dezavantajul n acest caz este ca nu se pot utiliza atributele cursorului din cauza faptului c acesta nu are nume.
19
CURSOR C IS SELECT .... FROM.... FOR UPDATE [OF COLUMN_NAME] [NOWAIT|WAIT n]; se adaug clauza FOR UPDATE n interogarea asociat cursorului pentru a bloca liniile afectate atunci cnd cursorul este deschis. clauza NOWAIT - determin apariia unei erori dac liniile sunt blocate de o alt sesiune. cnd mai multe tabele sunt implicate n interogare, se poate folosi FOR UPDATE pentru a impune blocarea liniilor unei tabele anume. Liniile unei tabele sunt blocate numai n cazul n care clauza FOR UPDATE face o referire la o coloan din acea tabel.
Pentru manipularea ct mai uoar a comenzilor LMD UPDATE i DELETE se poate utiliza clauza WHERE CURRENT OF care permite actualizarea nregistrrilor pe baza liniei curente din cursor. UPDATE tabela SET camp=.... WHERE CURRENT OF nume_cursor; se poate referi linia din tabela originar, pentru actualizare sau tergere, prin intermediul liniei curente a cursorului (cea procesat de ultima instruciune FETCH). clauza FOR UPDATE trebuie inclus n definiia cursorului pentru a bloca liniile n momentul execuiei instruciunii OPEN.
20
TRATAREA EXCEPIILOR
O excepie este un identificator PL/SQL asociat unei condiii anormale aprute n timpul execuiei unui bloc PL/SQL. Invocarea unei excepii are ca efect terminarea blocului, deci ieirea din blocul PL/SQL. Pentru evitarea unor situaii de ntrerupere anormal, excepia poate fi captat si poate fi specificat o rutin de tratare a acesteia. O excepie poate fi invocata in doua moduri: a. Apare o eroare Oracle si excepia asociata ei este automat invocat b. Excepia poate fi invocat n mod explicit prin instruciunea RAISE in cadrul blocului. Captarea unei excepii Daca excepia este invocat n seciunea executabil a unui bloc se caut n cadrul seciunii de tratare a excepiilor o rutin de tratare asociata. Daca PL/SQL poate trata excepia, ea nu este propagat n blocul exterior sau n mediul apelant, caz n care se consider c execuia blocului s-a desfurat cu succes.
Propagarea unei excepii Daca nu exist o rutin pentru tratarea ei, excepia este propagat n mediul apelant, caz n care execuia blocului se termin cu eec.
Excepii pre-definite asociate erorilor care apar cel mai Nu trebuie declarate, serverul Oracle le frecvent n blocurile PL/SQL (de exemplu invoc n mod automat, dar trebuie NO_DATA_ FOUND, TOO_MANY_ROWS, tratate n seciune EXCEPTION. INVALID_CURSOR, ZERO_DIVIDE) Excepii non-predefine recunoscute de Oracle dar tratate de utilizator cu ajutorul codului de eroare returnat (de exemplu ORA- 01400). Trebuie declarate n seciunea declarativ. Serverul Oracle le invoc n mod automat, dar trebuie tratate n seciune EXCEPTION.
Excepii definite de utilizator, asociate unor condiii Trebuie declarate n seciunea specifice de prelucrare (de exemplu cazul n care declarativ, invocate de ctre utilizator valoarea stocului unui anumit produs este zero) i tratate n seciunea EXCEPTION.
Tratarea tuturor excepiilor se realizeaz n seciunea EXCEPTION a blocurilor PL/SQL astfel: EXCEPTION
21
WHEN exception1 [OR exception2 ] THEN statement1 ; statement2 ; [WHEN exception3 [OR exception4 ] THEN statement1 ; statement2 ; ] [WHEN OTHERS THEN statement1 ; statement2 ; ]
Descriere O instruciune SELECT care ar fi trebuit sa ntoarc o singura linie nu a returnat nici o linie. O instruciune SELECT care ar fi trebuit sa ntoarc o singura linie a returnat mai multe linii. Apariia unei operaii ilegale asupra unui cursor (de exemplu ncercarea de a deschide un cursor deja deschis).
Exemplul de mai jos trateaza eroarea in cazul afisarii unui client pe baza identificatorului de circuit. In cazul in care CID-ul respectiv nu exista se va afisa: Nu exista circuit cu acest identificator!
22
0 nu a aprut nici o excepie; 1 este o excepie definit de utilizator; +100 excepia NO_DATA_FOUND; un numr negativ o eroare Oracle Server; SQLERRM returneaz mesajul asociat erorii. Aceste atribute pot fi ncrcate n variabile i inserate ntr-o tabel de erori pentru vizualizare i verificare ulterioar. Exemplu: S se insereze n tabela Circuite un nou circuit cu ID-ul 555, fr a preciza Clientul. n acest caz va apare o eroarea cu codul ORA-01400 prin care programatorul este avertizat de nclcarea unei restricii de integritate. Aceast excepie poate fi tratat astfel:
RAISE nume_exceptie; 3. Se trateaz n rutina corespunztoare din seciunea de tratare a excepiilor: WHEN nume_exceptie THEN......
24
Erorile definite de utilizator pot fi tratate la nivelul aplicaiilor ca i erorile Oracle Server prin atribuirea de coduri cu ajutorul funciei: RAISE_APPLICATION_ERROR (NR_EROARE, MESAJ); unde NR_EROARE poate fi un numr negativ cuprins ntre -20000 si -20999. In acest caz tratarea se realizeaz asemntor cu erorile non-predefinite Oracle Server. Exemplu: S se invoce o eroare n cazul n care utilizatorul ncearc s execute blocul PL/SQL dup ora 15:
apelant apare o situaie de excepie nerezolvat, utilizator putnd observa mesajul de eroare care a ntrerupt execuia normal. Exemple de exceptii predefinite:
no_data_foundSingle row SELECT returned no data. too_many_rowsSingle row SELECT returned more than one row. invalid_cursorIllegal cursor operation was attempted. value_errorArithmetic, conversion, truncation, or constraint error occurred. invalid_numberConversion of a number to a character string failed. zero_divideAttempted to divide by zero. dup_val_on_indexAttempted to insert a duplicate value into a column that has a unique index. cursor_already_openAttempted to open a cursor that was previously opened. not_logged_onA database call was made without being logged into Oracle. transaction_backed_outUsually raised when a remote portion of a transaction is rolled back. login_deniedLogin to Oracle failed because of invalid username and password. program_errorRaised if PL/SQL encounters an internal problem. storage_errorRaised if PL/SQL runs out of memory or if memory is corrupted. timeout_on_resourceTimeout occurred while Oracle was waiting for a resource. value_errorArithmetic, conversion, truncation, or constraint error occurred. othersThis is a catchall. If the error was not trapped in the previous exception traps, the error will be trapped by this statement
Subprograme PL/SQL
Blocuri PL/SQL care au nume Pot fi proceduri /functii Se pot stoca la nivel de Oracle Server (proceduri/functii stocate) sau de aplicatie (Developer Suite) Se pot grupa in pachete de programe (PACKAGE) Variabilele declarate in zona declarativa a procedurii se numesc parametri formali (formal parameters). Pentru acestia se pot specifica valori implicite (DEFAULT) Variabilele utilizate in apelul procedurii/functiei se numesc parametri actuali (actual parameters) Cnd procedura/functia e apelata, variabilele din procedura sunt incarcate cu valorile variabilelor definite in zona declarativa a blocului anonim In corpul procedurilor/functiilor nu se pot utiliza variabile globale sau de substitutie, acestea vor fi transmise in subprograme cu ajutorul parametrilor Pentru afisarea erorilor aparute la compilare se utilizeaza SHOW ERRORS
7.1 Proceduri
Parametrii utilizati in procedura (parametri formali) pot fi de tip:
26
IN (valoarea parametrului actual este transferata in variabila definita in procedura. Aceasta variabila este considerata read-only). Cnd procedura se ncheie, controlul revine mediului apelant. Parametrul actual nu se modifica. Este modul implicit. OUT (valoarea parametrului formal este transferata in parametrul actual cnd procedura se incheie) IN OUT (valorile sunt transferate de la un tip de variabil la cellalt (la lansarea n execuie/terminarea procedurii)) un parametru IN poate apare numai n partea dreapta a (:=) un parametru OUT poate apare numai n partea stnga a (:=) un parametru IN OUT poate apare n ambele pri ale (:=) Sintaxa pentru crearea unei proceduri: CREATE [OR REPLACE] PROCEDURE NUME_PROC [(param1 [IN|OUT|IN OUT] TIP1, Param2[IN|OUT|IN OUT] TIP2, ....) ] -- tipul variabilelor este precizat fara dimensiune (ex: NUMBER sau VARCHAR2) IS|AS -- zona de declarare a variabilelor utilizate in subprogram -- NU se utilizeaza DECLARE BEGIN ---[EXCEPTION] -----END [NUME_PROC]; Pentru a sterge procedura: DROP PROCEDURE NUME_PROC; Apelul unei proceduri se poate realiza in urmatoarele moduri: prin nume dintr-un bloc PL/SQL anonim sau un alt subprogram; prin apel direct cu EXECUTE nume_proc sau EXEC nume_proc sau CALL nume_proc; din alt mediu Oracle (Oracle Developer Suite) In exemplul de mai jos procedura primete doi parametrii: CID i procent i majoreaz cu procentul specificat costul_lunar:
27
7.2 Functii
Sintaxa pentru crearea unei functii: CREATE [OR REPLACE] FUNCTION nume_functie [(param1 [IN] TIP1, Param2[IN] TIP2, ....) ] RETURN TIP_DATA -- tipul variabilelor este precizat fara dimensiune (ex: NUMBER sau VARCHAR2) IS|AS -- zona de declarare a variabilelor utilizate in subprogram -- nu se utilizeaza DECLARE BEGIN ---RETURN VALOARE; [EXCEPTION] -----END [NUME_FUNCTIE]; Pentru vizualizarea tipului returnat se utilizeaza:
28
DESCRIBE nume_functie; Pentru a sterge functia: DROP FUNCTION nume_functie; Observatii! Functiile utilizate in expresii SQL trebuie sa accepte doar parametrii de tip IN si sa returneze numai tipuri de date specifice PL/SQL. Functiile nu trebuie sa contina comenzi DML (update, delete, insert) sau comenzi DDL si nici comenzi pentru controlul tranzactiilor (commit, rollback) si nici nu trebuie sa apeleze alte subprograme care sa incalce aceste restrictii. Functiile apelate in cadrul expresiilor SQL pot fi continute in pachete. Ex. Functia de mai jos returneaza true/false daca circuitul are un cost de instalare mai mare de 1000 (Euro) si null daca circuitul nu exista:
Specificatia pachetului:
29
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 si private [BEGIN -- Este optional si se executa o singura data la primul apel si la incarcarea pachetului in memorie END [nume_pachet];
Observatie: In cadrul pachetelor pentru a utiliza o functie/procedura in cadrul unui subprogram, aceasta trebuie declarata inainte (principiul forward declarations); In zona de specificatii a pachetului se pot declara:
proceduri; funcii; variabile; cursoare; excepii.
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); Stergerea pachetului se realizeaza cu comenzile:
DROP PACKAGE nume_pachet; DROP PACKAGE BODY nume_pachet; 30
Vizualizarea specificatiilor pachetelor in dictionarul metadatelor se realizeaza prin: Select text From user_source Where name='NUME_PACHET' and type='PACKAGE' Iar pentru a vizualiza corpul pachetului: Select text From user_source Where name='NUME_PACHET' and type='PACKAGE BODY
centralizarea operatiilor. Nu se recomanda construirea in exces a triggerilor. Pentru fiecare trigger se stabilete: comanda care-l declaneaz (insert| update| delete) - Un trigger poate fi declanat de mai multe comenzi momentul de timp la care se declaneaz (before| after| instead of). Pentru view se utilizeaza instead of, actiunile DML vor fi inlocuite de corpul triggerului si vor fi afectate tabelele din care este construit view-ul. nivelul (row| statement) - dac triggerul este la nivel de rnd se execut pentru fiecare rnd afectat de comenzile: insert| update| delete. Daca nu este afectat nici un rand triggerul nu se executa. Dimensiunea unui trigger nu poate depasi 32 kb! Se poate include apelul unei proceduri in corpul triggerului pentru a micsora dimensiunea acestuia. Pentru a vedea erorile la compilare: SHOW ERRORS TRIGGER nume_trigger;
Sintaxa de creare a unui trigger:
CREATE [OR REPLACE] TRIGGER nume_trigger [BEFORE| AFTER| INSTEAD OF] [INSERT| [OR] | UPDATE [OF coloana,]| [OR] | DELETE]
31
ON tabela [FOR EACH ROW ] [WHEN conditie] corp_trigger Corp_trigger poate fi un bloc PL/SQL (BeginEnd) sau un apel de procedura. Procedura poate fi implementata in PL/SQL, C sau JAVA, iar apelul se realizeaza: CALL nume_proc (fara ; dupa numele sau!!!) Ex: Se creeaza un trigger care se declanseaza inaintea fiecarei operatii de inserare in tabela clienti: CREATE OR REPLACE TRIGGER clienti_trig BEFORE INSERT ON clienti BEGIN dbms_output.put_line('triggerul clienti s-a executat'); END; / commit;
valoare veche, anterioara lui valoare noua, modificata update valoare veche, anterioara lui NULL delete
(:OLD) nu este definit pentru INSERT i (:NEW) nu e definit pentru DELETE Dei sintactic sunt tratate ca tip de dat record, n realitate ele nu sunt i operaiile de
atribuire directa var_record:=:old ce 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.
32
Nu se recomanda realizarea de triggeri la nivel de rind care utilizeaza valori ale coloanelor
din tabele si care sunt supuse actualizarilor prin comenzile DML ce declanseaza triggerul (mutating table). Va apare aceeasi eroare ca la functii. Utilizarea clauzei WHEN pentru a conditiona executia unui trigger: clauza [when condiie] este valid pentru triggerii la nivel de rnd corpul triggerului va fi executat numai pentru acele rnduri ce indeplinesc condiia specificat Exemplu: Se creeaza un trigger care nu permite depasirea unei limite maxime a costului de instalare per circuit.
Nu permit utilizarea clauzelor BEFORE|AFTER Comparatie intre triggeri si proceduri Trigger codul sursa: USER_TRIGGERS Sunt declansati implicit de DML Nu sunt permise comenzile: COMMIT, ROLLBACK, SAVEPOINT, insa pot contine un apel de procedura in care apar aceste comenzi, dar nu se recomanda Procedure codul sursa: USER_SOURCE Sunt apelate in mod explicit Sunt permise comenzile: COMMIT, ROLLBACK, SAVEPOINT
cnd un trigger e creat, codul surs al triggerului este stocat n dicionarul de date in
user_triggers si se poate afisa: SELECT trigger_type, trigger_name, triggering_event FROM user_triggers WHERE table_name='PRODUSE';
ALTER TRIGGER nume_trigger DISABLE|ENABLE; Sau: ALTER TABLE nume_tabela DISABLE|ENABLE ALL TRIGGERS; Comparatie intre triggeri si proceduri Trigger codul sursa: USER_TRIGGERS Sunt declansati implicit de DML Nu sunt permise comenzile: COMMIT, ROLLBACK, SAVEPOINT, insa pot contine un apel de procedura in care apar aceste comenzi, dar nu se recomanda Procedure codul sursa: USER_SOURCE Sunt apelate in mod explicit Sunt permise comenzile: COMMIT, ROLLBACK, SAVEPOINT
cnd un trigger e creat, codul surs al triggerului este stocat n dicionarul de date in
user_triggers si se poate afisa: SELECT trigger_type, trigger_name, triggering_event FROM user_triggers WHERE table_name='PRODUSE
34
Aplicatie
Sa se implementeze o baza de date numita Data_BD ce va contine trei table: Circuite, Clienti si Costuri. Acestea vor fi create astfel incat sa reflecte informatii referitoare la circuitele de date, clientii companiei si costurile asociate fiecarui circuit in parte. Cerinte:
Crearea celor 3 tabele mentionate mai sus si popularea acestora cu date asupra carora
executant, data curenta) sunt declansate la operatiile INSERT, DELETE sau UPDATE pe tabela CLIENTI.
Sa se implementeze o procedura care realizeaza un discount cu 10% a facturilor ce
35
36
37
Vizualizarea tabelelor dupa introducerea unui numar de date conform printscreenurilor de mai sus:
38
2. Cerinta a fost realizata prin utilizarea unui trigger ce se declanseaza inaintea unei operatii de inserare, actualizare sau stergere asupra tabelei Clienti si va popula tabelul nou creat tabel_log cu informatiile solicitate.
Testarea cerintei am facut prin efectuarea unor astfel de operatii de catre diferiti utilizatori asupra tabelei respective. Oferirea de privilegii asupra acestei baze de date catre alti utilizatori am facut prin comanda: grant All on "CLIENTI" to ANGAJAT_1,ANGAJAT_2;
39
Rezultatul este crearea unui tabel in care sunt logate toate operatiile efectuate asupra tabelului in cauza:
40
41
Pentru exemplificarea procedurii am executat comenzile de mai jos pentru doua circuite diferite. Se observa aplicarea discount-ului in cazul unei facturi de valoarea mai mare de 3000.
select "Factura_lunara" from costuri where CID=1111; execute modifica_factura_2(1111,10); commit; select "Factura_lunara" from costuri where CID=1111; select "Factura_lunara" from costuri where CID=6666; execute modifica_factura_2(6666,10); commit; select "Factura_lunara" from costuri where CID=6666;
42
43