IDD Seminar

Embed Size (px)

DESCRIPTION

idd seminar

Citation preview

Seminar 1

Facultatea de Cibernetic, Statistic i Informatic EconomicSGBD Oracle, an II, IDD

Introducere n PL/SQL Procedural Language extension to SQL

1. Caracteristici generale: 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.

2. Blocuri PL/SQL:Orice unitate PL/SQL conine unul sau mai multe blocuri, complet separate sau imbricate.

Componentele unui bloc PL/SQL:

Un bloc PL/SQL este compus din pn la 3 seciuni: declarativ (opional), executabil (obligatorie) i de tratare a excepiilor (opional).

DECLARE (Opional)variabile, cursori, excepiiBEGIN (Obligatoriu)comenzi SQL (asigur accesul la baza de date)structuri de programare procedural PL/SQLEXCEPTION (Opional)aciuni ce se execut cnd apare o eroareEND; (Obligatoriu)

Observaii: comenzile SQL asigur accesul la baza de date; 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;

Tipuri de blocuri PL/SQL: Blocuri anonime; Funcii stocate i funcii de aplicaii; Proceduri stocate i proceduri de aplicaii; Pachete; Declanatoare (triggeri) pe baza de date / de aplicaii.

Blocurile anonime: sunt nedenumite; nu sunt stocate n baza de date; se declar inline, n locul n care se dorete execuia lor; se execut n momentul rulrii.

Blocuri anonime imbricate se pot imbrica mai multe blocuri; acestea se pot eticheta cu , iar variabilele din cadrul blocurilor se pot utiliza astfel: eticheta_bloc.variabila.

BEGIN.>DECLARE..BEGIN..END eticheta_bloc;END;/

Proceduri, funcii: blocuri PL/SQL cu un nume; 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.

3. Operatori n PL/SQL

OperatorCaracteristici

+, -, *, /, ** (op. exponenial)Operatori aritmetici

AND, OR, NOTOperatori logici

, =, >=, 5 OR c2%NOTFOUND;INSERT INTO mesaje VALUES (v_cod, v_nume);END LOOP;CLOSE c2;END;/SELECT * FROM mesaje;

Gestiunea implicit a cursorului prin utilizarea unui ciclu FOR:

FOR nume_record IN nume_cursor LOOP--------------------------------------------------------END LOOP;

n acest caz, tipul RECORD nu trebuie declarat. Se realizeaz n mod implicit deschiderea, ncrcarea i nchiderea cursorului.

Exemplu:--S se afieze firmele din regiunea Banat:SET SERVEROUTPUT ONDECLARECURSOR c_firme IS select codfirma, denfirma, loc from firme where zona='BANAT';

BEGINDBMS_OUTPUT.PUT_LINE('Lista cu firmele din Banat: ');

FOR rec_firme IN c_firme LOOPDBMS_OUTPUT.PUT_LINE('Firma ' ||rec_firme.denfirma|| ' este din localitatea: '||rec_firme.loc);END LOOP;END;/

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

1. PROCEDURIParametrii utilizati in procedura (parametri formali) pot fi de tip: 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 DECLAREBEGIN----[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)

Exemple:

-- adauga o inregistrare noua in tabela ProduseSET SERVEROUTPUT ON

-- crearea procedurii:CREATE OR REPLACE PROCEDURE adauga_produs(p_codp produse.codprodus%type,p_denp produse.denprodus%type,p_um produse.um%type,p_stoc produse.stoc%type)IS

BEGINinsert into produse values (p_codp, p_denp, p_um, p_stoc);exceptionwhen dup_val_on_index then dbms_output.put_line('Produs existent!');END;/

SHOW ERRORS

-- apelul procedurii prin bloc PL/SQL anonim:beginadauga_produs(100, 'cafea', 11, 10);end;/-- apelul direct:call adauga_produs(100, 'cafea', 11, 10);

-- mareste stocul unui produs specificat cu un procent dat. Daca produsul nu exista, se va invoca o exceptieSET SERVEROUTPUT ON

-- crearea procedurii:CREATE or REPLACE PROCEDURE mareste_stoc(codp IN produse.codprodus%type, procent IN number)ISv_stoc produse.stoc%type;produs_invalid EXCEPTION;BEGINUpdate produseSet stoc=stoc*(1+procent/100)Where codprodus=codp;

if SQL%notfound thenraise produs_invalid;end if;

dbms_output.put_line('S-au modificat '||SQL%rowcount||' inregistrari');

exceptionwhen produs_invalid then dbms_output.put_line('Nu exista produsul cu codul '||codp);END;/

-- apelul direct:call mareste_stoc(111, 10);--verificare executieselect * from produse where codprodus =111;

Stergerea unei proceduri se realizeaza prin comanda: DROP PROCEDURE nume_procedura;

Vizualizarea procedurilor in dictionarul metadatelor se realizeaza prin:Select object_nameFrom user_objectsWhere object_type='PROCEDURE';

Iar pentru a vizualiza corpul procedurii:Select textFrom user_sourceWhere name='NUME_PROC' and type='PROCEDURE';

Exemplu:

Select textFrom user_sourceWhere name='MARESTE_STOC' and type='PROCEDURE';

2. FUNCII:

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 DECLAREBEGIN----RETURN VALOARE; [EXCEPTION]------END [NUME_FUNCTIE];

Pentru vizualizarea tipului returnat se utilizeaza:DESCRIBE nume_functie;

Pentru a sterge functia:DROP FUNCTION nume_functie;

Exemplu: -- afiseaza denumirea unui produs al carui cod este precizat drept parametru:CREATE OR REPLACE FUNCTION afiseaza_denumire(p_codp produse.codprodus%type)RETURN varchar2ISv_denp produse.denprodus%type;

BEGINselect denprodus into v_denpfrom produsewhere codprodus=p_codp;return v_denp;

EXCEPTIONwhen no_data_found thendbms_output.put_line('Nu exista produsul cu codul specificat!');when too_many_rows thendbms_output.put_line('Prea multe produse cu acest cod!');

END;/show errors;

-- vizualizarea tipului returnat:describe afiseaza_denumire;-- apelul functiei:declarev_nume varchar2(20);beginv_nume:= afiseaza_denumire(111);dbms_output.put_line(v_nume);end;

Utilizarea functiilor PL/SQL in expresii SQL

CREATE OR REPLACE FUNCTION tva (valoare IN NUMBER)RETURN NUMBERISBEGINRETURN (valoare*0.19);END;/

--apelul funcieiSELECT codprodus, cant * pret as valoare, tva (cant * pret) as tvaFROM rindcom;

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.

Stergerea unei functii se realizeaza utilizand comanda:DROP FUNCTION nume_functie;

Vizualizarea functiilor in dictionarul metadatelor se realizeaza prin:Select object_nameFrom user_objectsWhere object_type='FUNCTION';

Iar pentru a vizualiza corpul functiei:Select textFrom user_sourceWhere name='NUME_FUNCTIE' and type=' FUNCTION 'ORDER BY line;

Exemplu:Select textFrom user_sourceWhere name='TAX' and type='FUNCTION'ORDER BY line;

Pachete de subprograme

Grupeaza variabile, subprograme, tipuri de date PL/SQL care sunt corelate logic.Sunt formate din 2 parti: specificatia pachetului zona publica corpul pachetului zona privata

Specificatia pachetului:CREATE [OR REPLACE] PACKAGE nume_pachet IS|AS--declaratii de variabile si tipuri publice, sunt initializate cu NULL implicit--specificatii ale subprogramelor publiceEND [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.Corpul pachetului defineste complet procedurile, functiile si cursoarele.

Supraincarcarea subprogramelor Se poate realiza numai pentru functii/proceduri din cadrul pachetelor, nu si pentru 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);

Exemplu:CREATE OR REPLACE PACKAGE actualizare_produse ISprocedure adauga_produs(p_codp produse.codprodus%type,p_denp produse.denprodus%type,p_um produse.um%type,p_stoc produse.stoc%type);

procedure modifica_produs(p_codp produse.codprodus%type,p_denp produse.denprodus%type,p_um produse.um%type,p_stoc produse.stoc%type);

procedure modifica_produs(p_codp produse.codprodus%type,p_stoc produse.stoc%type);

procedure sterge_produs(p_codp produse.codprodus%type);

function exista_cod(p_codp produse.codprodus%type)return boolean;

exceptie exception;

END;/

CREATE OR REPLACE PACKAGE BODY actualizare_produs ISprocedure adauga_produs(p_codp produse.codprodus%type,p_denp produse.denprodus%type,p_um produse.um%type,p_stoc produse.stoc%type)isbeginif exista_cod(p_codp) thenraise exceptie;elseinsert into produse values (p_codp, p_denp, p_um, p_stoc);end if;exceptionwhen exceptie then dbms_output.put_line('Produs existent!');end;

procedure modifica_produs(p_codp produse.codprodus%type,p_denp produse.denprodus%type,p_um produse.um%type,p_stoc produse.stoc%type)isbeginif exista_cod(p_codp) thenupdate produseset denprodus=p_denp, um=p_um, stoc=p_stocwhere codprodus=p_codp;elseraise exceptie;end if;exceptionwhen exceptie then dbms_output.put_line('Produsul cu aceast cod nu exista!');end;

procedure modifica_produs(p_codp produse.codprodus%type,p_stoc produse.stoc%type)isbeginif exista_cod(p_codp) thenupdate produseset stoc=p_stocwhere codprodus=p_codp;elseraise exceptie;end if;exceptionwhen exceptie then dbms_output.put_line('Produsul cu aceast cod nu exista!');end;

procedure sterge_produs(p_codp produse.codprodus%type)isbeginif exista_cod(p_codp) thendelete from produsewhere codprodus=p_codp;dbms_output.put_line('Produsul cu codul '||p_codprodus||' a fost sters!');elseraise exceptie;end if;exceptionwhen exceptie thendbms_output.put_line('Produsul cu aceast cod nu exista!');end;

function exista_cod(p_codp produse.codprodus%type)return booleanisv_unu number;beginselect 1 into v_unufrom produsewhere codprodus=p_codprodus;return true;exceptionwhen no_data_found thenreturn false;end;

END;/

Apelul procedurilor / functiilor din cadrul pachetului:execute actualizare_produse.adauga_produs(449,'ceai', 12, 200);select * from produse;

execute actualizare_produse.modifica_produs(449,'gogosi', 10, 200);select * from produse;

execute actualizare_produse.modifica_produs(444, null);select * from produse;

execute actualizare_produse.sterge_produs(449);select * from produse;

Stergerea pachetului se realizeaza cu comenzile:DROP PACKAGE nume_pachet;DROP PACKAGE BODY nume_pachet;

Vizualizarea specificatiilor pachetelor in dictionarul metadatelor se realizeaza prin:Select textFrom user_sourceWhere name='NUME_PACHET' and type='PACKAGE'

Iar pentru a vizualiza corpul pachetului:Select textFrom user_sourceWhere name='NUME_PACHET' and type='PACKAGE BODY'

Exemplu:Select textFrom user_sourceWhere name='ACTUALIZARE_PRODUSE' and type='PACKAGE BODY';

Triggeri pe baza de date

Sunt asociati cu o tabela, view, schema sau database Sunt stocai n baza de date Se execut cnd are loc un eveniment. Tipuri de evenimente: operatii LMD pe o tabela (insert/ update/ delete) operatii LMD pe o tabela virtuala (view) cu clauza INSTEAD OF operatii LDD (Create, Alter, Drop) la nivel de database sau schema evenimente la nivelul schemei sau bazei de date (shutdown sau logon/off) Se folosesc pentru gestionarea restriciilor de integritate complexe, monitorizare, 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. Din acest motiv, o tabel poate avea 12 tipuri de triggeri. 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] 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!!!)

Exemplu:--Se creeaz un trigger care se declaneaz naintea fiecrei operaii de inserare n tabela PRODUSE.

CREATE OR REPLACE TRIGGER produse_trigBEFORE INSERT ON produse

BEGIN dbms_output.put_line('triggerul s-a executat');END; /

Triggeri la nivel de rand FOR EACH ROWIn triggerul la nivel de rnd se poate accesa rndul curent procesat folosind doua pseudo-records ( :old, :new). Tipul lor este:nume_tabela_pe_care_actioneaza_triggerul%ROWTYPE Valorile pentru :old si :newOperatieValoare pt Old Valoare pt New

INSERTNULLvaloarea noua, inserata

UPDATEvaloare veche, anterioara lui updatevaloare noua, modificata

DELETEvaloare veche, anterioara lui deleteNULL

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

Exemple:--Se creeaz un trigger care asigur unicitatea codului produsului folosind valorile generate de o secvenCREATE SEQUENCE produse_secvSTART WITH 1INCREMENT BY 1MAXVALUE 100NOCYCLE;

CREATE OR REPLACE TRIGGER generare_codprodusBEFORE INSERT ON produseFOR EACH ROWBEGINSELECT produse_secv.nextval INTO :new.codprodus FROM dual;END;/show errors;

--Trigger care sa actualizeze cod client si in COMENZI cand el e modificat in FIRME.

CREATE OR REPLACE TRIGGER inlocuieste_codAFTER UPDATE OF codfirma ON firmeFOR EACH ROWBEGINupdate comenziset codfirma = :new.codfirmawhere codfirma = :old.codfirma;END;/

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_eventFROM user_triggersWHERE table_name='PRODUSE';

Gestiunea triggerilor:

Un trigger poate fi dezactivatALTER TRIGGER nume_trigger DISABLE|ENABLE;Sau:ALTER TABLE nume_tabelaDISABLE|ENABLE ALL TRIGGERS;

Exemplu:ALTER TABLE produseENABLE ALL TRIGGERS;

Recompilarea unui trigger se realizeaza prin:ALTER TRIGGER nume_trigger COMPILE;

Un trigger se terge cu:DROP TRIGGER nume_trigger;

Observatie: In momentul stergerii unei tabele se sterg automat toti triggerii asociati acelei tabele. PL/SQL stocheaz triggerii n forma compilat la fel ca procedurile, funciile i pachetele. Aceasta permite triggerilor s fie apelai fr recompilare.

- 35 -