Sunteți pe pagina 1din 44

CTLIN MIRONEANU

Baze de date orientate obiect - lucrri de laborator -

Baze de date orientate obiect lucrri de laborator

Cuprins
Laborator 1 Introducere n obiectele Oracle..................................................................................... 3 Avantajul lucrului cu obiecte Oracle................................................................................................ 3 Tipuri abstracte de date. Atribute i metode ................................................................................... 4 Referine........................................................................................................................................ 5 Folosirea tipurilor n cadrul tabelelor............................................................................................... 6 Laborator 2 Modul de lucru cu obiectele Oracle transmiterea prin valoare..................................... 7 Laborator 3 Modul de lucru cu obiectele Oracle transmiterea prin referin partea I...................11 Laborator 4 Modul de lucru cu obiectele Oracle transmiterea prin referin partea a II-a............16 Laborator 5 Test 1 laborator ...........................................................................................................19 Laborator 6 Referine spre obiecte n PL/SQL ................................................................................20 Pachetul UTL_REF .......................................................................................................................20 Laborator 7 ROWID, OID i REF. ...................................................................................................24 Tipul de dat ROWID....................................................................................................................24 Objects ID (OID) ..........................................................................................................................25 Folosirea lui REF ca operator sau ca modificator de tip .................................................................27 Laborator 8 Definirea tabelelor obiect i a coloanelor de tip tablou imbricat.....................................29 Laborator 9 Metode........................................................................................................................35 Definirea metodelor.......................................................................................................................35 Metode MEMBER .........................................................................................................................36 Metode pentru compararea obiectelor...........................................................................................37 Laborator 10 Metode statice i metode constructor.........................................................................41 Metode statice ..............................................................................................................................41 Metode constructor .......................................................................................................................42 Laborator 11 Test 2 laborator .........................................................................................................44

2 din 44

Baze de date orientate obiect lucrri de laborator

Laborator 1 Introducere n obiectele Oracle


Obiectele Oracle sunt tipuri definite de ctre utilizator. Tehnologia obiectual implementat de ctre Oracle reprezint de fapt un nivel de abstractizare construit peste tehnologia relaional a Sistemului de Gestiune a Bazelor de Date (SGBD) Oracle. Tipurile care pot fi create de ctre utilizator au la baz tipurile de date predefinite din Oracle sau oricare alt tip de date definit anterior. Datele sunt stocate n tabele, avantajul lucrului obiectual relaional fiind acela de a vedea aceste date sub o form obiectual. n modul de lucru orientat obiect din Oracle se schimb modul de gndire n sensul c nu se mai lucreaz cu termenul de tabele i coloane, ci cu obiecte. n modul de lucru intern Oracle, instruciunile care folosesc obiecte, folosesc de fapt tot tabele i coloane.

Avantajul lucrului cu obiecte Oracle


n general, modelul obiectual Oracle este similar ca mecanism cu modul de lucru obiectual din C++ i Java. Prin modul de lucru obiectual, aplicaiile dezvoltate pot accesa direct structurile de date. Tablele bazei de date conin doar date, pe cnd obiectele conin n plus, pe lng date, i operaiile aferente. De exemplu, un obiect vnzare poate include o metod de sumarizare a costului tuturor produselor vndute. O aplicaie poate doar s apeleze metoda i s obin rezultatul fr a mai fi nevoie de scrierea codului surs pentru aceste calcule. De fapt, acesta este i unul din marile avantaje ale modului de lucru orientat obiect. Obiectele i metodele lor sunt stocate mpreun cu datele n baza de date, fiind disponibile pentru utilizare n cadrul oricrei aplicaii. Dezvoltatorii beneficiaz de acest aspect prin faptul c nu mai este nevoie s re-creeze structuri similare pentru orice aplicaie nou care prelucreaz aceleai date. Pot fi obinute rezultate i se pot manipula obiectele printr-o singur operaie n sensul c la apelarea unui obiect, se apeleaz n mod automat i celelalte obiecte cu care este conectat.

3 din 44

Baze de date orientate obiect lucrri de laborator

Tipuri abstracte de date. Atribute i metode


Pentru a defini o clas n Oracle se creeaz un tip cu ajutorul instruciunii CREATE TYPE. Pe scurt, sintaxa instruciunii este: CREATE TYPE numeTip AS OBJECT ( lista de atribute i metode ); / Mai detaliat: CREATE TYPE numeTip AS OBJECT ( <atribut1 Tip>, .. <atributn Tip>, MEMBER FUNCTION Metoda1 [(p1 tip, ) RETURN Tip], [ MEMBER PROCEDURE Metoda2 [(p1 tip, )], ..); / Fiecare atribut membru poate fi un tip scalar (NUMBER, INTEGER, DATE, VARCHAR2) sau poate fi declarat ca aparinnd unui tip abstract definit anterior. Definirea comportamentului obiectelor (operaiile pe care le pot realiza acestea asupra datelor proprii) se realizeaz prin implementarea funciilor membru specificate la crearea tipului: CREATE TYPE BODY numeTip AS MEMBER FUNCTON Metoda1 IS <variabile locale> BEGIN <corpul metodei> END Metoda1; END; /

4 din 44

Baze de date orientate obiect lucrri de laborator

Exemplu: CREATE OR REPLACE TYPE BarType as OBJECT ( nume CHAR(20), addr CHAR(20) );

CREATE OR REPLACE TYPE BeerType AS OBJECT ( nume CHAR(20), manf CHAR(20) ); /

Referine
Dac T este un tip, atunci REF T reprezint un pointer ctre un obiect de tip T. n unele documentaii este denumit i object ID, dar fa de identificatorii de obiect care nu sunt vizibili n mod normal, aceste referine sunt vizibile n baza de date.

Exemplu: CREATE OR REPLACE TYPE MenuType as OBJECT ( bar REF BarType, beer REF BeerType, price FLOAT ); /

Un obiect MenuType se poate reprezenta astfel:

3.00
Pointer ctre un obiect BarType Pointer ctre un obiect BeerType

5 din 44

Baze de date orientate obiect lucrri de laborator

Folosirea tipurilor n cadrul tabelelor


O tabel poate fi definit ca o unitate de stocare a obiectelor. Sintaxa este: CREATE TABLE <nume tabel> OF <nume tip>; Exemple: CREATE TABLE Bars OF BarType; CREATE TABLE Beers OF BeerType; CREATE TABLE Sells OF MenuType;

Din punct de vedere obiectual, tabela Bars nu este constituit din dou coloane: nume i addr, ci dintr-o singur coloan (relaie unar) care are dou componente: nume i addr. Prin apelarea numelui de tip cu valori, se consider apelarea constructorului implicit: INSERT INTO Bars VALUES( BarType(Corso, str. Lapusneanu) ); /

6 din 44

Baze de date orientate obiect lucrri de laborator

Laborator 2 Modul de lucru cu obiectele Oracle transmiterea prin valoare


Orice metod primete un parametru implicit SELF care specific obiectul curent (instana obiectului asupra creia se efectueaz operaia). Exemplu: CREATE OR REPLACE TYPE Angajat AS OBJECT ( marca INTEGER, nume VARCHAR2(30), prenume VARCHAR2(30), ore_lucrate INTEGER, ore_co INTEGER, ore_cm INTEGER, sal_orar NUMBER(6,2), MEMBER FUNCTION CalculSalariu RETURN NUMBER, MEMBER PROCEDURE SetOre(v_ore_lucr INTEGER, v_ore_co INTEGER, v_ore_cm INTEGER) ); / CREATE OR REPLACE TYPE BODY Angajat AS MEMBER FUNCTION CalculSalariu RETURN NUMBER IS BEGIN RETURN (SELF.ore_lucrate+SELF.ore_co+SELF.ore_cm*0.85)*SELF.sal_orar; END CalculSalariu;

MEMBER PROCEDURE SetOre(v_ore_lucr INTEGER, v_ore_co INTEGER, v_ore_cm INTEGER) IS BEGIN SELF.ore_lucrate := v_ore_lucr; SELF.ore_co := v_ore_co; SELF.ore_cm := v_ore_cm; END SetOre; END; / 7 din 44

Baze de date orientate obiect lucrri de laborator

Utilizarea parametrului SELF este opional, dar recomandat pentru lizibilitatea codului sau n cazul operaiilor complexe care necesit i variabile locale (SELF.ore_lucrate este echivalent cu ore_lucrate). Prin sintaxa SELF.ore_lucrate se acceseaz datele stocate de atributul ore_lucrate pentru obiectul curent. Metoda CalculSalariu() este definit fr paranteze deoarece nu accept nici un parametru. Parantezele sunt ns obligatorii pentru apelul metodei. n exemplul de mai jos se construiete un obiect de tip Angajat i se afieaz salariul (acesta se calculeaz pornind de la premisa c pentru concedii medicale se acord un procent de 85% din valoarea salariului tarifar). Apoi se modific numrul de ore lucrate i petrecute n concediu medical prin intermediul metodei SetOre i se afieaz din nou salariul. Construirea unui obiect de un anume tip se realizeaz prin apelarea unui constructor implicit, cruia i sunt furnizate valori pentru fiecare atribut n parte: NEW DenumireTip (val1, val2, , valn) Exemplul de mai jos creeaz un obiect i apeleaz metodele sale ntr+un bloc PL/SQL: DECLARE obj_angaj1 Angajat; BEGIN obj_angaj1 := NEW Angajat(100, Ionescu, Ion, 160, 0, 0, 1000); DBMS_OUTPUT.PUT_LINE(obj_angaj1.nume || || obj_angaj1.prenume || are salar: || obj_angaj1.CalculSalariu() );

-- modific starea obiectului obj_angaj1.SetOre(100, 0, 60); DBMS_OUTPUT.PUT_LINE(obj_angaj1.nume || || obj_angaj1.prenume || are salariul dup modificare ore_cm cu 60: || obj_angaj1.CalculSalariu() ); END; /

Un aspect important n ceea ce privete manipularea obiectelor ntr-un limbaj de programare se refer la modul de transfer al acestora (ntre variabile sau ntre un modul program i altul). n Oracle, obiectele se transmit prin valoare, ca n exemplul de mai jos sau prin referin, prin operatorul REF. 8 din 44

Baze de date orientate obiect lucrri de laborator

DECLARE obj_angaj1 Angajat; obj_angaj2 Angajat; BEGIN obj_angaj1 := NEW Angajat(100, Ionescu, Ion, 160, 0, 0, 1000); obj_angaj2 := NEW Angajat(100, Popescu, Vasile, 0, 0, 0, 2000); DBMS_OUTPUT.PUT_LINE(Pasul 1: doua obiecte diferite: doua variabile); DBMS_OUTPUT.PUT_LINE(obj_angaj1.nume || || obj_angaj1.prenume || are salar: || obj_angaj1.CalculSalariu() ); DBMS_OUTPUT.PUT_LINE(obj_angaj2.nume || || obj_angaj2.prenume || are salar: || obj_angaj2.CalculSalariu() );

-- transfer de obiect: se creeaz automat unul nou, identic obj_angaj1 := obj_angaj2;

DBMS_OUTPUT.PUT_LINE(Pasul 2: dupa atribuire - doua obiecte identice: doua variabile); DBMS_OUTPUT.PUT_LINE(obj_angaj1.nume || || obj_angaj1.prenume || are salar: || obj_angaj1.CalculSalariu() ); DBMS_OUTPUT.PUT_LINE(obj_angaj2.nume || || obj_angaj2.prenume || are salar: || obj_angaj2.CalculSalariu() );

-- modific doar obiectul 2 obj_angaj2.ore_lucrate := 200; DBMS_OUTPUT.PUT_LINE(Pasul 3: modific doar unul din obiecte

(ore_lucrate = 200), celalalt ramane neschimbat); DBMS_OUTPUT.PUT_LINE(obj_angaj1.nume || || obj_angaj1.prenume || are salar: || obj_angaj1.CalculSalariu() ); DBMS_OUTPUT.PUT_LINE(obj_angaj2.nume || || obj_angaj2.prenume || are salar: || obj_angaj2.CalculSalariu() ); END; / Operaia de atribuire obj_angaj1 := obj_angaj2 va determina construirea unui obiect complet diferit, dar cu stare identic (valorile atributelor sunt identice). 9 din 44

Baze de date orientate obiect lucrri de laborator

Rezultatul rulrii este: Pasul 1: doua obiecte diferite: doua variabile Ionescu Ion are salar: 160000 Popescu Vasile are salar: 0 Pasul 2: dupa atribuire - doua obiecte identice: doua variabile Popescu Vasile are salar: 0 Popescu Vasile are salar: 0 Pasul 3: modific doar unul din obiecte (ore_lucrate = 200), celalalt ramane neschimbat Popescu Vasile are salar: 0 Popescu Vasile are salar: 400000

10 din 44

Baze de date orientate obiect lucrri de laborator

Laborator 3 Modul de lucru cu obiectele Oracle transmiterea prin referin partea I


Un obiect de tip referin (REF) este o adres logic (pointer) a unei linii obiect (spre un obiect existent), adres prin intermediul creia s fie gestionat exact obiectul respectiv, i nu o copie a acestuia. Tipul de date referin este predefinit n Oracle. De obicei, tipul de date REF i coleciile de obiecte de acest tip modeleaz relaiile dintre entiti (relaii unul la mai muli sau mai muli la unul) nlocuind necesitatea definirii cheilor externe relaionale. Referinele asigur un mecanism simplu pentru regsirea obiectelor stocate n tabelele obiect, utiliznd notaia cu punct. n acest caz sistemul gestioneaz automat legtura ctre tabelul obiect referit. O referin obiect identific n mod unic un obiect stocat ntr-un tabel sau vizualizare obiect. O valoare de tip referin este caracterizat de: Identificatorul unic al obiectului referit (OID Object IDentifier) Identificatorul unic asociat tabelului obiect referit Identificatorul liniei (ROWID) din tabelul obiect n care este stocat obiectul (identificatorul ROWID este de obicei folosit pentru accesul rapid la obiectele stocate) Din punctul de vedere al arhitecturii bazei de date, tabelele copil se construiesc pe baza referinelor spre obiectele din tabelele printe. Important de reinut: Un REF poate defini un pointer numai spre un obiect stocat ntr-o tabel de obiecte, i nu spre obiecte rezidente n memorie sau ca valori ale atributelor unei tabele relaionale clasice. Oracle furnizeaz dou tehnologii de stocare a obiectelor n baza de date: obiecte linie sunt stocate sub form de linii ale unei tabele construite pe baza tipului cruia i aparin respectivele obiecte; atributele unei asemenea tabele vor fi tocmai atributele din definiia tipului, iar un obiect va constitui o nregistrare. obiecte coloan persistena se asigur sub form de valori ale unui atribut declarat ntr-o tabel relaional clasic; pentru fiecare nregistrare, respectivul atribut va conine un obiect de tipul declarat. Corespunztor celor dou tehnologii de stocare a obiectelor, mai jos sunt prezentate cele dou modaliti de stocare a obiectelor n baza de date: 11 din 44

Baze de date orientate obiect lucrri de laborator

CREATE TABLE Angajati_ObjTbl OF ANGAJAT;

CREATE TABLE Angajati_RefTbl (id INTEGER, pers ANGAJAT);

Prima linie creeaz o tabel obiectual a crei nregistrri vor fi obiecte de tip Angajat, iar a doua linie de cod definete o tabel relaional n care atributul pers este de tip Angajat i va stoca obiecte. Inserarea n tabela obiectual nu difer de modelul relaional clasic.

INSERT INTO Angajati_ObjTbl VALUES (111, Popescu, Vasile, 0,0,0,2000); sau INSERT INTO Angajati_ObjTbl VALUES (NEW Angajat(112, Popa, Viorel, 0,0,0,1500));

INSERT INTO Angajati_RefTbl VALUES (1, NEW Angajat (111, Popescu, Vasile, 0,0,0,2000)); INSERT INTO Angajati_RefTbl VALUES (2, NEW Angajat (112, Popa, Viorel, 0,0,0,1500));

n cazul tabelei relaionale Angajati_RefTbl, pentru a extrage datele stocate de atributele obiectelor, se va utiliza notaia specific modelului de programare orientatobiect (cu punct). Este obligatorie utilizarea unui alias pentru tabela n cauz, pentru a putea manipula obiectele dup ablonul: aliasTabel.atributTabel.atributObiect. n caz contrar se obine eroarea ORA-00904.

La rularea: SELECT pers.nume FROM Angajati_RefTbl; se va obine mesajul de eroare: SELECT pers.nume FROM Angajati_RefTbl * ERROR at line 1: ORA-00904: "PERS"."NUME": invalid identifier

12 din 44

Baze de date orientate obiect lucrri de laborator

La rularea: SELECT A.pers.nume FROM Angajati_RefTbl A; se va obine rezultatul:


PERS.NUME -----------------Popescu Popa

Actualizarea se face n felul urmtor: UPDATE Angajati_RefTbl A SET A.pers.sal_orar=2400 WHERE A.pers.marca=111;

SELECT * FROM Angajati_RefTbl; va avea ca rezultat:


ID ---------PERS(MARCA, NUME, PRENUME, ORE_LUCRATE, ORE_CO, ORE_CM, SAL_ORAR) ------------------------------------------------------------------------1 ANGAJAT(111, 'Popescu', 'Vasile', 0, 0, 0, 2400) 2 ANGAJAT(112, 'Popa', 'Viorel', 0, 0, 0, 1500)

Pn acum s-au prezentat tehnici de actualizare i interogare a datelor obiectelor (valorile stocate de atribute). Uneori este necesar ca n urma unei interogri s se obin chiar obiecte sau s nlocuim n tabela obiectual un obiect cu un altul. Pentru aceasta se folosete funcia VALUE(alias_tabela_ob) care returneaz obiecte noi, identice cu obiectele din tabela obiectual specificat prin alias_tabela_ob.

Important de reinut: Funcia poate fi folosit numai n fraze SQL i numai pentru tabele obiectuale.

13 din 44

Baze de date orientate obiect lucrri de laborator

SELECT VALUE(A) FROM Angajati_ObjTbl A; va avea ca rezultat:


VALUE(A)(MARCA, NUME, PRENUME, ORE_LUCRATE, ORE_CO, ORE_CM, SAL_ORAR) ---------------------------------------------------------------------ANGAJAT(111, 'Popescu', 'Vasile', 0, 0, 0, 2400) ANGAJAT(112, 'Popa', 'Viorel', 0, 0, 0, 1500)

Prin intermediul interogrii de mai sus se obin obiecte i nu valori ale atributelor sale!

DECLARE obj Angajat; BEGIN SELECT VALUE(A) INTO obj FROM Angajati_ObjTbl A WHERE marca=112; obj.nume := 'test'; END; Variabila obj din blocul PL/SQL preia o copie a obiectului cu marca 112 din tabela Angajati_ObjTbl. Tot aici se modific valoarea atributului nume al noului obiect prin linia de comand: obj.nume := 'test'; Rularea comenzii: SELECT VALUE(A) FROM Angajati_ObjTbl A; va avea ca rezultat:
VALUE(A)(MARCA, NUME, PRENUME, ORE_LUCRATE, ORE_CO, ORE_CM, SAL_ORAR) ---------------------------------------------------------------------ANGAJAT(111, 'Popescu', 'Vasile', 0, 0, 0, 2400) ANGAJAT(112, 'Popa', 'Viorel', 0, 0, 0, 1500)

Acest rezultat al interogrii denot faptul c obiectul cu marca 112 din tabela Angajati_ObjTbl a rmas neschimbat.

Cu ajutorul aceleiai funcii VALUE se poate nlocui obiectul pentru care marca este 112 cu un alt obiect: UPDATE Angajati_ObjTbl A SET VALUE(A) = NEW Angajat(115, Vasilescu, Grigore, 0,0,0,1200) WHERE A.marca = 112;

Orice modificare de genul celei de mai sus va lsa intact adresa logic a obiectului.

14 din 44

Baze de date orientate obiect lucrri de laborator

Rularea comenzii: SELECT VALUE(A) FROM Angajati_ObjTbl A; va avea ca rezultat:


VALUE(A)(MARCA, NUME, PRENUME, ORE_LUCRATE, ORE_CO, ORE_CM, SAL_ORAR) ---------------------------------------------------------------------ANGAJAT(111, 'Popescu', 'Vasile', 0, 0, 0, 2000) ANGAJAT(115, 'Vasilescu', 'Grigore', 0, 0, 0, 1200)

Pentru oricare din cele dou tabele se poate defini o cheie primar relativ la atributul marca: ALTER TABLE Angajati_ObjTbl ADD PRIMARY KEY (marca); ALTER TABLE Angajati_RefTbl ADD PRIMARY KEY (pers.marca);

15 din 44

Baze de date orientate obiect lucrri de laborator

Laborator 4 Modul de lucru cu obiectele Oracle transmiterea prin referin partea a II-a
Revenind la exemplul din laboratorul anterior, se va crea o tabel

SPORURI_REFTBL pentru gestionarea orelor lucrate de angajai: CREATE TABLE Sporuri_RefTbl ( ref_angajat REF ANGAJAT REFERENCES Angajati_ObjTbl, an INTEGER, luna INTEGER, oreSporNoapte INTEGER, oreSporNocive INTEGER );

Atributul ref_angajat al tabelei va stoca referine numai spre obiecte de tip Angajat existente n tabela Angajati_ObjTbl, restricie implementat n modelul relaional prin cheia strin (restricia referenial). Obinerea unei referine spre un obiect se realizeaz cu ajutorul funciei REF(obiect), care poate fi folosit numai n fraze SQL. Aspecte eseniale referitoare la tipurile REF: o referin reprezint adresa, identificatorul unic (OID Object IDentifier) generat de sistem la crearea obiectului (este atribuit automat la momentul iniializrii obiectului i este unic n baza de date) prin intermediul referinelor se manipuleaz obiectele folosind notaia cu punct REF(A).nume returneaz datele stocate de atributul nume al obiectelor din tabela Angajati_ObjTbl

SELECT REF(A) FROM Angajati_ObjTbl A; va avea ca rezultat:


REF(A) -------------------------------------------------------------------------------0000280209518E21BCCB6D41C482B20DA4B0BAA511B525806AA1584C8BB2DB1D1E5B781A26010003 F40000 0000280209140F056F60BB4D70B48090F376D9EC4EB525806AA1584C8BB2DB1D1E5B781A26010003 F40001

16 din 44

Baze de date orientate obiect lucrri de laborator

SELECT (REF(A)).nume FROM Angajati_ObjTbl A; va avea ca rezultat:


(REF(A)).NUME -------------------Popescu Vasilescu

Pentru c o referin se poate obine numai prin intermediul unei fraze SELECT, adugarea de nregistrri n tabela Sporuri_RefTbl se face astfel: INSERT INTO Sporuri_RefTbl (SELECT REF(A), 2003, 03, 0, 0 FROM Angajati_ObjTbl A ); Vor fi inserate attea nregistrri cte linii sunt n tabela Angajati_ObjTbl, respectiv n cazul nostru, 2 nregistrri.

SELECT * FROM Sporuri_RefTbl; va avea ca rezultat:


REF_ANGAJAT -------------------------------------------------------------------------------AN LUNA ORESPORNOAPTE ORESPORNOCIVE ---------- ---------- ------------- ------------0000220208518E21BCCB6D41C482B20DA4B0BAA511B525806AA1584C8BB2DB1D1E5B781A26 2003 3 0 0 0000220208140F056F60BB4D70B48090F376D9EC4EB525806AA1584C8BB2DB1D1E5B781A26 2003 3 0 0

SELECT S.ref_angajat.nume, oreSporNoapte, oreSporNocive FROM Sporuri_RefTbl S; va avea ca rezultat:


REF_ANGAJAT.NUME ORESPORNOAPTE ORESPORNOCIVE ------------------------------ ------------- ------------Popescu 0 0 Vasilescu 0 0

Este posibil ca un obiect identificat de o referin s devin la un moment dat indisponibil (de exemplu prin tergerea obiectului sau prin schimbarea privilegiilor). Un astfel de obiect referin se numete izolat. n acest sens, pentru testarea validitii referinelor se folosete predicatul IS DANGLING. Varianta IS NOT DANGLING poate fi utilizat pentru a identifica referinele valide.

17 din 44

Baze de date orientate obiect lucrri de laborator

CREATE TYPE t_adresa AS OBJECT ( cod_adresa NUMBER, strada nr oras ); VARCHAR2(50), NUMBER, VARCHAR2(40)

CREATE TABLE tab_adrese OF t_adresa;

INSERT INTO tab_adrese VALUES (1, Dimitrie Mangeron, 53, Iasi); INSERT INTO tab_adrese VALUES (2, Tudor Vladimirescu, 41, Iasi);

CREATE TYPE t_student AS OBJECT ( cod_s nume NUMBER, VARCHAR2(50),

prenume VARCHAR2(50), adresa ); REF t_adresa

CREATE TABLE tab_studenti OF t_student;

INSERT INTO tab_studenti SELECT 101, Popescu, Vasile, REF(a) FROM tab_adrese a WHERE a.cod_adresa = 2; INSERT INTO tab_studenti SELECT 102, Popa, Viorel, REF(a) FROM tab_adrese a WHERE a.cod_adresa = 1;

SELECT nume, prenume FROM tab_studenti WHERE adresa IS DANGLING;

18 din 44

Baze de date orientate obiect lucrri de laborator

Iniial, aceast comand nu va returna nici un rezultat deoarece toate legturile sunt corecte. n urma execuiei comenzii: DELETE FROM tab_adrese WHERE cod_adresa = 1; i se execut din nou comanda SELECT de mai sus, va rezulta studentul Popa Viorel deoarece referinele ctre adresa avnd codul 1 au devenit izolate, ele referind aceeai linie obiect de tip t_adresa din tabelul tab_adrese, care a fost ters. Accesarea obiectului adresat de o referin se numete derefereniere i este realizat cu ajutorul funciei DEREF(expresie_referin). Dac argumentul funciei DEREF este o referin ctre un obiect, aceasta returneaz instana obiect referit. Cnd nu se aplic DEREF asupra referinelor selectate de o cerere, sistemul returneaz identificatorul obiect al referinei. SELECT DISTINCT adresa FROM tab_studenti; SELECT DEREF(adresa) FROM tab_studenti; Se observ din rezultate diferena dintre cele dou abordri ale unei referine, fr i cu derefereniere (fizic, respectiv logic). n cel de-al doilea SELECT, unde s-a folosit DEREF, nu se poate specifica operatorul DISTINCT pentru c nu este definit o metod de ordonare pentru tipul t_adresa i atunci sistemul ar returna eroarea ORA-22950 cannot ORDER objects without MAP or ORDER method. Explicaia este c operatorul care face proiecia fr dubluri (DISTINCT) presupune o ordonare a listei de linii rezultat. Dereferenierea referinelor izolate duce la obinerea unui obiect cu valoarea null. Sistemul Oracle asigur dereferenierea implicit a referinelor atunci cnd este necesar. Oracle nu reutilizeaz OID-urile, astfel c la tergerea unui obiect i inserarea imediat a altuia cu aceleai valori, obiectul va primi un alt OID. n schimb, din punct de vedere relaional, linia inserat avnd aceleai valori cu linia tears, este ca i cum nimic nu s-ar fi ntmplat. Aceasta este marea diferen ntre sistemele relaionale i cele orientate obiect. Funcia MAKE_REF creeaz o referin ctre o linie a unui tabel a crei identificator obiect este bazat pe cheia primar.

Laborator 5 Test 1 laborator

19 din 44

Baze de date orientate obiect lucrri de laborator

Laborator 6 Referine spre obiecte n PL/SQL Pachetul UTL_REF


Posibilitatea obinerii unei referine spre un obiect deja existent are importan asupra codului unei aplicaii orientate-obiect din urmtoarele perspective: referina spre un obiect existent ofer posibilitatea manipulrii acestuia de ctre mai multe programe; eventuala modificare a strii obiectului se efectueaz ntr-un singur loc, programele care fac referire la acesta avnd disponibil schimbarea fcut; referinele ofer o modalitate de gestionare mai riguroas a memoriei.

PL/SQL nu suport navigarea ntre obiecte prin intermediul referinelor, dei permite declararea variabilelor de tip REF care s conin adrese de obiecte. Fie urmtorul bloc PL/SQL: SET SERVEROUTPUT ON; DECLARE angajat_ref REF Angajat; BEGIN SELECT REF(A) INTO angajat_ref FROM Angajati_ObjTbl A WHERE A.marca = 112; DBMS_OUTPUT.PUT_LINE(angajat_ref.nume); END; / La rularea codului de mai sus se obine mesajul de eroare:
DBMS_OUTPUT.PUT_LINE(angajat_ref.nume); *

ORA-06550: line ., column ..: PLS-00536: Navigation through REF variables is not supported in PL/SQL. Oracle ofer posibilitatea de gestionare a referinelor n PL/SQL prin intermediul pachetului UTL_REF. Spre deosebire de comenzile Limbajului de Manipulare a Datelor (LMD) INSERT, UPDATE, DELETE, MERGE, etc, procedurile din pachetul UTL_REF prezint avantajul c nu necesit specificarea tabelului obiect din care face parte obiectul referit. UTL_REF poate fi utilizat att de subprogramele i pachetele PL/SQL stocate pe server, ct i n aplicaiile PL/SQL de la client (Oracle Forms).

20 din 44

Baze de date orientate obiect lucrri de laborator

Pachetul conine urmtoarele proceduri: 1. UTL_REF.SELECT_OBJECT ( reference IN REF "<typename>", object IN OUT "<typename>");

extrage obiectul adresat de parametrul reference i paseaz valoarea variabilei object. Se va obine un obiect nou, copie identic a obiectului surs. Fraza SQL echivalent este: SELECT VALUE(t) INTO object FROM object_table t WHERE REF(t) = reference;

2. UTL_REF.UPDATE_OBJECT ( reference IN REF "<typename>", object IN "<typename>");

nlocuiete obiectul de la adresa specificat prin parametrul reference cu unul nou. Adresa OID rmne neschimbat, doar c va fi un alt obiect identificat prin intermediul ei. Fraza SQL echivalent este: UPDATE object_table SET VALUE(t) = object WHERE REF(t) = reference;

3. UTL_REF.DELETE_OBJECT ( reference IN REF "<typename>"); terge obiectul identificat prin referina reference. Fraza SQL echivalent este: DELETE FROM object_table WHERE REF(t) = reference;

4. UTL_REF.LOCK_OBJECT ( reference IN REF "<typename>");

UTL_REF.LOCK_OBJECT ( reference IN REF "<typename>", object IN OUT "<typename>");

21 din 44

Baze de date orientate obiect lucrri de laborator

Procedura blocheaz un obiect identificat prin referina reference pentru a nu fi modificat de alt tranzacie. Fraza SQL echivalent este: SELECT VALUE(t) INTO object FROM object_table t WHERE REF(t) = reference FOR UPDATE; Dup cum se observ, procedura este suprancrcat astfel nct, opional, obiectul s poat fi reinut ntr-o variabil. Aici se poate vedea cel mai bine avantajul c nu este necesar specificarea tabelului obiect din care face parte obiectul referit. Nu este necesar blocarea unui obiect nainte de a se efectua un UPDATE sau DELETE. Pentru exemplificare, se d urmtoarea procedur: CREATE OR REPLACE PROCEDURE test_utl_ref (v_ref REF Angajat) IS obj_clona_angajat Angajat; BEGIN -- pasul 1 UTL_REF.SELECT_OBJECT (v_ref, obj_clona_angajat); DBMS_OUTPUT.PUT_LINE(pasul1 - || obj_clona_angajat.marca || || obj_clona_angajat.nume);

-- pasul 2 UTL_REF.UPDATE_OBJECT (v_ref, NEW Angajat(120, test2, null, 0,0,0,1200 )); DBMS_OUTPUT.PUT_LINE(pasul2 - || obj_clona_angajat.marca || || obj_clona_angajat.nume);

-- pasul 3 UTL_REF.SELECT_OBJECT (v_ref, obj_clona_angajat); DBMS_OUTPUT.PUT_LINE(pasul3 - || obj_clona_angajat.marca || || obj_clona_angajat.nume); -- pasul 4 UTL_REF.DELETE_OBJECT (v_ref); END; / 22 din 44

Baze de date orientate obiect lucrri de laborator

Pasul 1 obinerea obiectului. ntr-o variabil local, obj_clona_angajat de tip Angajat, se preia valoarea obiectului a crui referin a fost obinut prin parametrul v_ref Pasul 2 nlocuirea obiectului. Se modific obiectul identificat prin referina v_ref prin nlocuirea lui cu altul complet nou avnd marca 120. nlocuirea de va petrece n tabela surs. Textul afiat demonstreaz c variabila local deine o copie. Pasul 3 obinerea obiectului dup modificare. Se reiniializeaz variabila local cu obiectul nou de la aceeai referin. Pasul 4 tergerea obiectului. Obiectul se terge din tabela surs. Se observ la ultimul SELECT de mai jos c au rmas doar 2 obiecte n tabela Angajati_ObjTbl.

INSERT INTO Angajati_ObjTbl VALUES (NEW Angajat(119, test, t, 0,0,0,0));

SELECT * FROM Angajati_ObjTbl;


MARCA ----111 115 119 NUME -----------Popescu Vasilescu test PRENUME ORE_LUCRATE ORE_CO ORE_CM SAL_ORAR ---------- ----------- ---------- ---------- ---------Vasile 0 0 0 2000 Grigore 0 0 0 1200 t 0 0 0 0

DECLARE ref_a REF Angajat; BEGIN SELECT REF(A) INTO ref_a FROM Angajati_ObjTbl A WHERE A.marca = 119; test_utl_ref(ref_a); END; /
pasul1 - 119 test pasul2 - 119 test pasul3 - 120 test2

SELECT * FROM Angajati_ObjTbl;


MARCA ----111 115 NUME -----------Popescu Vasilescu PRENUME ORE_LUCRATE ORE_CO ORE_CM SAL_ORAR ---------- ----------- ---------- ---------- ---------Vasile 0 0 0 2000 Grigore 0 0 0 1200

23 din 44

Baze de date orientate obiect lucrri de laborator

Laborator 7 ROWID, OID i REF. Tipul de dat ROWID


ROWID este un tip de dat standard n Oracle, precum CHAR, VARCHAR2, DATE sau NUMBER. Acest tip de dat este reprezentat sub forma unui ir hexazecimal reprezentnd adresa unic a unei linii ntr-o tabel.

Structura unui ROWID este urmtoarea: OOOOOO


Data object number

FFF
Relative file number

BBBBBB
Block number

RRR
Row Number

Valorile de tip ROWID nu sunt stocate n mod explicit ca valori n coloanele tabelelor la care se refer. O valoare de tip ROWID ocup 10 bytes pe hard disk i este afiat folosind 18 caractere. Data object number este asignat la crearea fiecrui obiect Oracle care stocheaz valori (tabele sau indeci) i este unic n baza de date Relative file number este o valoare unic a fiecrui fiier din care este format tablespace-ul Block number reprezint poziia blocului, n fiier, care conine linia Row number reprezint poziia din header-ul blocului

Intern, data object number ocup 32 bii, relative file number ocup 10 bii, block number ocup 22 bii i row number ocup 16 bii, avnd n total 80 de bii sau 10 bytes. ROWID este afiat folosind o schem de codare base-64 care folosete caracterele: A-Z, a-z, 0-9, +, i / n total 64 caractere. n aceast schem de codare base-64, data object number se afieaz pe 6 poziii, relative file number se afieaz pe 3 poziii, block number se afieaz pe 6 poziii i row number se afieaz pe 3 poziii.

24 din 44

Baze de date orientate obiect lucrri de laborator

Objects ID (OID)
Relund explicaiile din Laboratorul 3, o referin obiect identific n mod unic un obiect stocat ntr-un tabel sau vizualizare obiect. O valoare de tip referin este caracterizat de: Identificatorul unic al obiectului referit (OID Object IDentifier) Identificatorul unic asociat tabelului obiect referit Identificatorul liniei (ROWID) din tabelul obiect n care este stocat obiectul (identificatorul ROWID este de obicei folosit pentru accesul rapid la obiectele stocate) Dei pn acum doar am vizualizat valori OID, trebuie tiut de la nceput c acestea nu se pot modifica de ctre utilizator sau administratorul bazei de date, fiind gestionate intern de ctre Oracle. Atunci cnd utilizatorul creeaz o tabel de obiecte, Oracle adaug o coloan ascuns care va stoca OID-ul pentru fiecare obiect introdus. OID are urmtoarele proprieti: Opacitatea programele nu folosesc acest OID n mod direct i nu este n mod normal nevoie de a fi folosit n codul unui program; n principiu este unic la nivel global n orice baz de date Oracle instalat. Practic, sunt 2128 valori posibile. n acest fel, chiar pe maini identice pe care este instalat Oracle, nu este posibil a se genera acelai OID. Conservarea valorii dup o operaiune de import/export, ceea ce la ROWID nu se ntmpl. Aceast proprietate permite distribuirea obiectelor ntre baze de date, fa de ROWID care este dependent de baza de date din care face parte. Schimbarea OID-ului pentru un obiect nu se poate face dect prin tergerea lui i recrearea lui cu aceleai valori, moment n care Oracle genereaz un alt OID. Nu toate obiectele au OID. Obiectele stocate n variabile PL/SQL nu au OID i nici obiectele coloan. Un obiect coloan are sens n contextul liniei stocate, iar linia stocat are OID. Practic, un programator trebuie s aleag ntre a introduce obiectul ntr-o coloan sau a-l face refereniabil. Numele coloanei ascunse este SYS_NC_OID$. Aceasta este de lungime de 16 bytes. ROWID este de 10 bytes. Numele altei coloane ascunse este

SYS_NC_ROWINFO$, care furnizeaz constructorul obiectului.

25 din 44

Baze de date orientate obiect lucrri de laborator

SELECT SYS_NC_OID$ FROM Angajati_ObjTbl A; va avea ca rezultat:


SYS_NC_OID$ -------------------------------518E21BCCB6D41C482B20DA4B0BAA511 140F056F60BB4D70B48090F376D9EC4E

SELECT SYS_NC_ROWINFO$ FROM Angajati_ObjTbl A; va avea ca rezultat:


SYS_NC_ROWINFO$(MARCA, NUME, PRENUME, ORE_LUCRATE, ORE_CO, ORE_CM, SAL_ORAR) -------------------------------------------------------------------------------ANGAJAT(111, 'Popescu', 'Vasile', 0, 0, 0, 2000) ANGAJAT(115, 'Vasilescu', 'Grigore', 0, 0, 0, 1200)

Nu este necesar folosirea SYS_NC_ROWINFO$ att timp ct Oracle furnizeaz posibilitatea folosirii lui REF( ) i VALUE( ):

SELECT REF(A) FROM Angajati_ObjTbl A; va avea ca rezultat:


REF(A) -------------------------------------------------------------------------------0000280209518E21BCCB6D41C482B20DA4B0BAA511B525806AA1584C8BB2DB1D1E5B781A26010003 F40000 0000280209140F056F60BB4D70B48090F376D9EC4EB525806AA1584C8BB2DB1D1E5B781A26010003 F40001

SELECT VALUE(A) FROM Angajati_ObjTbl A; va avea ca rezultat:


VALUE(A)(MARCA, NUME, PRENUME, ORE_LUCRATE, ORE_CO, ORE_CM, SAL_ORAR) -------------------------------------------------------------------------------ANGAJAT(111, 'Popescu', 'Vasile', 0, 0, 0, 2000) ANGAJAT(115, 'Vasilescu', 'Grigore', 0, 0, 0, 1200)

26 din 44

Baze de date orientate obiect lucrri de laborator

Folosirea lui REF ca operator sau ca modificator de tip


ntr-o instruciune SQL, REF se folosete pentru obinerea OID-ului obiectului din tabel, sau cu alte cuvinte a adresei logice a liniei obiect. n acest caz REF opereaz pe o linie obiect, acceptnd ca i argument aliasul tabelei. Aa cum se subnelege din explicaiile date pentru OID, REF nu poate opera pe obiecte coloan sau tablele imbricate (nested tables), deoarece aceste tipuri de obiecte nu au OID. Obinerea adresei logice nu este de ajutor n nici un fel, fiind mai mult o chestiune de imagine, de a dovedi c exist acel ir lung n hexa. Se mai ntmpl ca REF s fie folosit ca un fel de cheie strin, dup cum se poate vedea n exemplul de mai jos: SELECT s.cod_s, s.nume, s.prenume, a.strada, a.nr, a.oras FROM tab_studenti s, tab_adrese a WHERE s.adresa = REF(a);

Dar i acest mod de lucru prin folosirea lui REF ca un fel de cheie strin poate avea o alternativ: SELECT s.cod_s, s.nume, s.prenume, s.adresa.strada, s.adresa.nr, s.adresa.oras FROM tab_studenti s;

Cele dou instruciuni SELECT de mai sus demonstreaz modul n care Oracle suport navigarea prin obiecte fr folosirea lui REF, ceea ce nu mai merge i n PL/SQL. Este mult mai intuitiv i mai uoar folosirea punctului dect folosirea unui join explicit. De remarcat c cele dou instruciuni SELECT de mai sus nu sunt identice ca i concept de returnare a rezultatelor deoarece prima instruciune execut un equi-join, ceea ce nseamn c dac n tab_studenti am referine izolate sau null (a se vedea explicaiile de la DANGLING), n al doilea SELECT am un outer-join.

Important de reinut: REF nu sunt chei strine!

27 din 44

Baze de date orientate obiect lucrri de laborator

Valoarea returnat de REF poate fi stocat ntr-o variabil local declarat ca fiind de tip REF nume_obiect. Aceast variabil local poate primi valoare prin intermediul unui fetch sau dintr-o alt variabil declarat ca fiind de tip REF de acelai nume de obiect, aa cum se poate vedea n exemplul de mai jos: DECLARE ref_obj_angaj1 REF Angajat; ref_obj_angaj2 REF Angajat; BEGIN -- exemplu de atribuire prin fetch SELECT REF(a) INTO ref_obj_angaj1 FROM Angajati_ObjTbl a WHERE... -- exemplu de atribuire directa ref_obj_angaj2 := ref_obj_angaj1;

Nu se poate obine referina la o variabil obiect care exist ntr-un bloc PL/SQL: DECLARE obj_angaj1 Angajat := Angajat (111, 'Popescu ' , 'Vasile', 0, 0, 0, 2000); ref_obj_angaj1 REF Angajat; BEGIN ref_obj_angaj1 := REF(obj_angaj1); -- invalid ..

REF sunt doar pentru OID-uri! Obiectele temporare nu au un asemenea pointer. Dup cum s-a dovedit, REF nu ar fi folositor nici ntr-un astfel de caz.

n programarea avansat Oracle, singura situaie n care REF este folosit este n cazul n care dorim folosirea obiectului ntr-o alt baz de date prin pasarea referinei obiectului ca parametru, deci n cazurile de reutilizare a obiectelor.

28 din 44

Baze de date orientate obiect lucrri de laborator

Laborator 8 Definirea tabelelor obiect i a coloanelor de tip tablou imbricat


Prin adugarea caracteristicilor obiectuale n Oracle, comanda CREATE TABLE a fost extins cu opiuni care permit crearea tabelelor obiectuale i a tabelelor relaionale care conin coloane de tipul obiect, referin sau colecie. Pentru a crea un tabel, utilizatorul trebuie s dein privilegiul CREATE TABLE (pentru a putea crea o tabel n schema lui) sau privilegiul sistem CREATE ANY TABLE (pentru a putea crea o tabel n schema altui utilizator). n cazul tabelelor obiect, proprietarul tabelului obiectual sau relaional cu o coloan de tip obiect trebuie s dein n plus privilegiul obiect EXECUTE sau privilegiul sistem EXECUTE ANY TYPE pentru a putea accesa tipurile referite de tabel. Sintaxa comenzii CREATE TABLE pentru crearea tabelelor obiectuale este: CREATE TABLE [schema].nume_tabel OF [schema].tip_obiect [ [ NOT ] SUBSTITUTABLE AT ALL LEVELS ] [ ( { { coloana | atribut } [ DEFAULT expr] [ constr_linie [constr_linie ]] | constr_line_ref ] | { constr_tabel | constr_tabel_ref } } ) ] [clauza_OID] [proprietati_colectie]

Comanda creeaz un tabel obiect n schema curent sau n cea precizat. Clauza OF specific tipul (tip_obiect) corespunztor tabelului obiect. Fiecare linie va conine o instan obiect, creia i se va asocia la inserare cte un identificator obiect generat de sistem (OID). Clauza DEFAULT permite specificarea unei valori implicite. Aceasta va fi atribuit coloanei la execuia unei comenzi de inserare care omite o valoare explicit pentru coloana respectiv. Pentru o coloan de tip definit de ctre utilizator, clauza DEFAULT trebuie s conin o invocare literal a constructorului obiectului sau coleciei respective. Expresia DEFAULT poate include orice funcie SQL care nu returneaz un argument literal, o referin ctre o coloan sau apelul unei funcii imbricat. De asemenea, o expresie implicit nu poate conine referine ctre funcii PL/SQL sau alte coloane, pseudocoloanele LEVEL, PRIOR sau ROWNUM, constante de tip dat calendaristic nespecificate n totalitate.

29 din 44

Baze de date orientate obiect lucrri de laborator

O invocare literal a unei metode de tip constructor este apelul metodei constructor n care argumentele sunt fie valori, fie la rndul lor alte invocri literale de metode constructor. Nu sunt permise variabile sau funcii. Avnd dat clasele t_artist i t_adresa: CREATE TYPE t_artist AS OBJECT ( nume prenume anul_nasterii anul_mortii nationalitate observatii ); / CREATE TYPE t_adresa AS OBJECT ( cod_adresa strada cod_postal oras judet tara ); / Adaug un atribut adresa de tip t_adresa: ALTER TYPE t_artist ADD ATTRIBUTE adresa t_adresa CASCADE; / Definim un tip tablou imbricat, t_artisti_ti de obiecte de tip t_artist: CREATE TYPE t_artisti_ti AS TABLE OF t_artist; / O invocare literal a constructorului pentru tipul tabel imbricat t_artisti_ti este urmtoarea: NUMBER, VARCHAR2(50), VARCHAR2(7), VARCHAR2(40), VARCHAR2(30), VARCHAR2(40) VARCHAR2(30), VARCHAR2(30), VARCHAR2(4), VARCHAR2(4), VARCHAR2(40), VARCHAR2(2000)

30 din 44

Baze de date orientate obiect lucrri de laborator

t_artisti_ti ( t_artist(Brancusi, Constantin, 1876, 1957, NULL, NULL, t_adresa(NULL, NULL, NULL, Tg. Jiu, NULL, Romania), t_artist(Dali, Salvador, 1904, 1989, NULL, NULL, NULL), t_artist(Picasso, Pablo, 1881, 1973, NULL, NULL, t_adresa(2, Rue des Ecoles 13, 12345, Paris, Paris, Franta) ); Se mai definete t_polite_ti de tip tablou imbricat i t_dim_v un vector de dimensiune 3. Fiecare linie din tabloul imbricat t_polite_ti este un obiect de tip t_polita_asigurare. CREATE TYPE t_polita_asigurare AS OBJECT ( cod_polita descriere firma valoare data_contract ); / CREATE TYPE t_polite_ti AS TABLE OF t_polita_asigurare; / CREATE TYPE t_dim_v AS VARRAY(3) OF NUMBER; / VARCHAR2(30), VARCHAR2(200), VARCHAR2(50), NUMBER, DATE

Referin bibliografic: http://psoug.org/reference/nested_tab.html

Un exemplu de invocare literal de metode constructor pentru a specifica valori implicite ale coloanelor unui tabel relaional care conine informaii despre operele de art:

31 din 44

Baze de date orientate obiect lucrri de laborator

CREATE TABLE opere_de_arta ( cod_opera tip titlu artist NUMBER, VARCHAR2(40), VARCHAR2(200), t_artist

DEFAULT t_artist (A, A, NULL, NULL, NULL, NULL, NULL), data_crearii data_achizitiei valoare polite dimensiuni DATE, DATE DEFAULT SYSDATE, NUMBER, t_polite_ti DEFAULT t_polite_ti(), t_dim_v DEFAULT t_dim_v(-1, -1, -1) )

NESTED TABLE polite STORE AS polite_store;

t_polite_ti() este invocarea literal a metodei constructor pentru un tablou imbricat vid de acest tip, iar t_dim_v(-1, -1, -1) instaniaz un obiect vector de tip t_dim_v cu elementele implicite -1, -1, -1 alese astfel nct s se indice c nu au fost introduse dimensiunile operei respective. Opiunea clauza_OID are urmtoarea form: OBJECT IDENTIFIER IS { SYSTEM GENERATED | PRIMARY KEY} Clauza permite s se specifice dac identificatorul obiect al tabelului obiectual este generat de sistem sau este bazat pe cheia primar a tabelului. Opiunea implicit este SYSTEM GENERATED. Un identificator cheie primar este unic la nivel local (dar nu n mod necesar i la nivel global). Dac se cere un identificator obiect care s fie unic la nivel global, atunci trebuie verificat faptul c i cheia primar este unic la acest nivel. Restriciile legate de clauza referitoare la identificatorul obiect sunt: Se poate specifica OBJECT IDENTIFIER IS PRIMARY KEY doar dac s-a definit o constrngere de cheie primar; Clauza nu poate fi folosit pentru tablouri imbricate;

Proprietile tabelelor obiect sunt similare celor ale tabelelor relaionale, cu diferena c n loc s se specifice coloane, se specific atribute. Numele atributului trebuie s fie precedat de numele coloanei de tip obiect din care face parte. Clauza de substituibilitate [ NOT ] SUBSTITUTABLE AT ALL LEVELS se utilizeaz pentru a preciza dac pot fi inserate linii obiect corespunztoare 32 din 44

Baze de date orientate obiect lucrri de laborator

subtipurilor tipului declarat al tabelului obiect asupra cruia se face specificaia. Varianta negat indic faptul c tabelul obiect nu este substituibil. n acest caz, substituia este dezactivat pentru toate atributele obiectelor i elementele coleciilor integrate n cadrul liniei. Opiunea implicit este cea de substituibilitate. Proprietile coloanelor de tip tablou imbricat se pot seta cu ajutorul urmtoarelor opiuni: NESTED TABLE {elem_imbricat | COLUMN_VALUE} [clauza_col_substituibila] STORE AS tabel_stocare [( (propr_obiect) [propr_fizice] [propr_coloana] )] [RETURN AS {LOCATOR | VALUE}] Aceste clauze permit specificarea unor caracteristici de stocare separate pentru un tablou imbricat (de exemplu, definirea unui tablou imbricat ca tabel organizat pe baz de index). Clauza NESTED TABLE este obligatorie atunci cnd se creeaz tabele care conin coloane (propriu-zise sau ascunse) de tip tablou imbricat. Clauzele clauza_col_substituibila, propr_obiect, propr_fizice, propr_coloana din cadrul

opiunilor pentru tablouri imbricate funcioneaz n acelai fel ca i pentru tabelul printe. Atributul elem_imbricat specific numele coloanei de tip tablou imbricat sau al unui atribut tablou imbricat al tipului obiectului asociat tabelului. Cuvntul cheie COLUMN_VALUE este folosit n cazul coleciilor pe mai multe niveluri, atunci cnd tabloul imbricat sau vectorul referit nu are nume. Opiunea STORE AS tabel_stocare specific numele tabelului care va conine liniile coloanei de tip tablou imbricat. Asupra tabelului de stocare exist restricia c nu se pot executa comenzi de interogare sau prelucrare a datelor n mod direct. Clauza RETURN AS specific tipul rezultatului returnat de cererile asupra coloanelor de tip tablou imbricat. Exist dou opiuni: VALUE, care permite returnarea unei copii a tabloului imbricat stocat n cadrul coloanei referite de clauza NESTED TABLE LOCATOR, care permite obinerea unei adrese (locator) ctre valoarea propriu-zis a tabloului imbricat. Locatorul este propriu unei sesiuni i nu poate fi reutilizat de la o sesiune la alta. Exemplu: S se creeze un declanator asupra tabelului obiectual opere_de_arta, care va insera o nou nregistrare n tabelul cumparari pentru fiecare oper de art cumprat. S se insereze o nregistrare i s se constate efectul declanatorului. 33 din 44

Baze de date orientate obiect lucrri de laborator

Tabela cumparari i tipul t_opera_arta este definit dup cum urmeaz: CREATE TYPE t_opera_arta AS OBJECT ( cod_opera tip titlu artist data_crearii data_achizitiei valoare polite dimensiuni NUMBER, VARCHAR2(10), VARCHAR2(200), REF t_artist, DATE, DATE, NUMBER, t_polite_ti, t_dim_v,

MEMBER FUNCTION get_titlu RETURN VARCHAR2 ); / CREATE TABLE cumparari ( opera t_opera_arta,

data_cumpararii DATE, pret vanzator NUMBER, VARCHAR2(100) )

NESTED TABLE opera.polite STORE AS tstoc_polite;

CREATE OR REPLACE TRIGGER t_ai_on_opere AFTER INSERT ON opere_de_arta FOR EACH ROW BEGIN INSERT INTO cumparari VALUES (t_opera_arta(:NEW.cod_opera, :NEW.tip, :NEW.titlu, NULL, :NEW.data_crearii, :NEW.data_achizitiei, :NEW.valoare, :NEW.polite, :NEW.dimensiuni), SYSDATE, 100, Matache ); END; / INSERT INTO opere_de_arta (cod_opera, tip, titlu) VALUES (1, tip_fictiv, titlu_fictiv); 34 din 44

Baze de date orientate obiect lucrri de laborator

Laborator 9 Metode
Metodele sunt funcii sau proceduri declarate n cadrul definiiei unui tip obiect pentru implementarea comportamentului obiectelor de acel tip. O aplicaie interacioneaz cu un obiect prin intermediul metodelor definite de tipul acestuia. Metodele pot fi scrise n PL/SQL sau n alt limbaj de programare acceptat de baza de date Oracle. Cele scrise n PL/SQL sau Java sunt stocate n baza de date, iar cele scrise n alte limbaje de programare, cum ar fi C, sunt stocate extern. n definiia unui tip pot fi declarate metode MEMBER sau statice. Metodele MEMBER pot fi metode obinuite sau funcii de ordonare. De asemenea, pentru fiecare tip obiect, sistemul definete automat o metod constructor. Constructorul unui tip este utilizat pentru crearea obiectelor de tipul respectiv.

Definirea metodelor
Pentru implementarea metodelor unui tip se utilizeaz comanda CREATE TYPE BODY. Dac este creat un tip SQLJ pentru care metodele sunt definite n clasa Java asociat, atunci nu este necesar comanda CREATE TYPE BODY. Acelai lucru este valabil i pentru metodele care sunt declarate ca proceduri sau funcii externe. Pentru a crea sau nlocui corpul unui tip din propria schem sunt necesare privilegiile sistem CREATE TYPE sau CREATE ANY TYPE (pentru a crea corpul unui tip din schema altui utilizator), iar pentru a nlocui corpul unui tip din schema altui utilizator trebuie avut privilegiul sistem DROP ANY TYPE. Comanda are urmtoarea sintax: CREATE [OR REPLACE] TYPE BODY [schema.]nume_tip {IS | AS} {MEMBER | STATIC} {declar_proc | declar_functie | declar_cosntructor} [{MEMBER | STATIC} {declar_proc | declar_functie | declar_cosntructor} ] [ {MAP | ORDER} MEMBER declar_functie] END; n cadrul unui tip se poate defini fie o metod de tip MAP, fie una de tip ORDER. n acest fel este posibil compararea instanelor tipului obiect respectiv, n cadrul comenzilor SQL. Dac nu este declarat nici una din metodele de ordonare, atunci se poate verifica doar egalitatea a dou obiecte de acel tip.

35 din 44

Baze de date orientate obiect lucrri de laborator

Opiunile MEMBER sau STATIC specific tipul metodei implementate, care poate fi procedur, funcie sau constructor. Sintaxa corespunztoare celor 3 tipuri de metode este: PROCEDURE nume_proc ([ parametru tip_de_date ]) {IS | AS} {bloc_PL/SQL | specificatie_apel}

FUNCTION nume_functie ([ parametru tip_de_date ]) RETURN tip_de_date {IS | AS} {bloc_PL/SQL | specificatie_apel}

[FINAL] [INSTANTIABLE] CONSTRUCTOR FUNCTION tip_obiect [ ( [SELF IN OUT tip_obiect, ] parametru tip_de_date [, parametru tip_de_date ] )] RETURN SELF AS RESULT {IS | AS} {bloc_PL/SQL | specificatie_apel}

Metode MEMBER
Metodele MEMBER reprezint modalitatea prin care o aplicaie acceseaz datele unei instane de tip obiect. n cadrul tipului obiect este posibil implementarea cte unei metode pentru fiecare operaie care poate fi executat asupra obiectelor de tipul respectiv. Exemplu: crearea unei metode get_titlu(), care acceseaz informaiile despre o anumit oper de art i returneaz titlul acesteia:

CREATE OR REPLACE TYPE BODY t_opera_arta AS MEMBER FUNCTION get_titlu RETURN VARCHAR2 IS BEGIN RETURN SELF.titlu; END get_titlu; END; / SELECT c.opera.get_titlu() FROM cumparari c;

36 din 44

Baze de date orientate obiect lucrri de laborator

Orice metod are un parametru predefinit SELF care identific instana obiect asupra creia este invocat metoda la un moment dat. Pentru simplitate, metodele MEMBER pot defini atributele i metodele parametrului SELF fr calificativ (de exemplu SELF.titlu sau titlu au aceeai valoare). Nu este obligatoriu ca parametrul SELF s fie declarat n mod explicit, dar dac este declarat, el trebuie s fie primul parametru transmis metodei. Dac parametrul SELF nu este declarat, n funciile MEMBER el este considerat n mod implicit IN, iar n procedurile MEMBER de tip IN OUT. O metod se invoc utiliznd notaia cu punct (obiect.metoda()). Prefixul notaiei specific obiectul asupra cruia se invoc metoda. Parantezele sunt obligatorii chiar dac metoda nu are parametri.

Metode pentru compararea obiectelor


Valorile unui tip de date scalar au o ordine predefinit care permite folosirea acestora n comparaii. Un tip obiect este o structur complex i neuniform, format din mai multe atribute cu tipuri de date diferite, care nu are o regul predefinit de comparare. Pentru a putea ordona i compara variabile de tip obiect trebuie specificat o regul de comparare. n acest sens, exist dou tipuri de metode MEMBER care pot fi definite: Metode de mapare (MAP) Metode de ordonare (ORDER)

O metod de tip MAP permite compararea obiectelor prin asocierea dintre o instan obiect i o valoare scalar (DATE, VARCAHR2, NUMBER, etc) Clauza MAP MEMBER din comenzile CREATE TYPE i CREATE TYPE BODY permite implementarea unei funcii MEMBER de tip MAP care returneaz poziia relativ a unei instane date n domeniul ordonat al tuturor instanelor tipului obiect respectiv. O astfel de metod este apelat n mod implicit de sistem i induce o ordonare a instanelor obiect, utiliznd ordinea predefinit a valorilor scalare asociate. Limbajul PL/SQL utilizeaz metodele MAP pentru a evalua expresiile de tip boolean i pentru comparaii directe (de tip ob1 > ob2) sau indirecte (generate de clauzele DISTINCT, GROUP BY i ORDER BY). Dac tipul va fi referit n cereri care 37 din 44

Baze de date orientate obiect lucrri de laborator

implic sortri, atunci este obligatorie o funcie MAP. Dac argumentul metodei MAP este null, atunci aceasta returneaz valoarea null i nu mai este invocat. Dac ob1 i ob2 sunt dou obiecte care pot fi comparate utiliznd o metod de mapare denumit map(), atunci comparaia ob1 > ob2 este echivalent cu: ob1. map() > ob2. map() O specificaie a unui tip obiect poate conine o singur metod MAP, care trebuie s fie o funcie cu un singur argument (parametrul implicit SELF). Tipul rezultatului trebuie s fie un tip scalar SQL predefinit. Un subtip poate suprascrie metoda MAP motenit de la supertip.

Exemplu: definirea unei metode de tip MAP, perimetru() care implementeaz un mod de comparare a obiectelor de tip t_dreptunghi, utiliznd perimetrul acestora:

CREATE TYPE t_dreptunghi AS OBJECT ( lungime NUMBER, latime NUMBER ,

MAP MEMBER FUNCTION perimetru RETURN NUMBER ); / CREATE TYPE BODY t_dreptunghi AS MAP MEMBER FUNCTION perimetru RETURN NUMBER IS BEGIN RETURN 2*( lungime+ latime); END perimetru; END; /

Metodele de tip ORDER permit compararea direct a obiectelor. Spre deosebire de metodele de tip MAP, ele specific dac obiectul asupra cruia se face invocarea este mai mic, egal sau mai mare dect obiectul cu care este comparat, conform unui criteriu prestabilit i implementat de metod. Un obiect poate declara cel mult o metod de ordonare. Clauza ORDER MEMBER specific o funcie membru de tip ORDER care accept instana unui obiect ca argument explicit, SELF ca argument implicit i returneaz un ntreg. 38 din 44

Baze de date orientate obiect lucrri de laborator

Rezultatul reflect dac argumentul implicit SELF este mai mic (rezultat negativ), egal (rezultat zero) sau mai mare (rezultat pozitiv) dect argumentul explicit. Dac argumentul metodei ORDER este null, atunci metoda returneaz valoarea null i nu mai este invocat. n cadrul unei ierarhii de tipuri, un subtip nu poate nici s declare i nici s suprascrie o metod de tip ORDER. Similar metodelor MAP, o metod ORDER este apelat automat ori de cte ori trebuie comparate obiecte de tipul respectiv. De exemplu, dac o coloan de tip obiect apare ntr-o clauz ORDER BY, atunci se invoc metoda ORDER. Metodele de ordonare sunt necesare atunci cnd semnificaia comparrii obiectelor devine prea complex pentru a putea utiliza metodele de mapare. De exemplu, pentru compararea unor obiecte binare (imagini) se poate crea o metod de ordonare care s ia n considerare luminozitatea i numrul de pixeli.

Problem: s se defineasc o metod de ordonare care compar artitii dup numele lor. n cazul numelor identice, compararea se face dup prenumele acestora i apoi descresctor dup anul naterii. S se verifice modul de funcionare al metodei.

ALTER TYPE t_artist ADD ORDER MEMBER FUNCTION comparare (a t_artist) RETURN INTEGER CASCADE; /

CREATE OR REPLACE TYPE BODY t_artist AS ORDER MEMBER FUNCTION comparare (a t_artist) RETURN INTEGER IS v_nume_complet v_return BEGIN . RETURN v_return; END comparare; END; / VARCHAR2(60); INTEGER;

39 din 44

Baze de date orientate obiect lucrri de laborator

DECLARE v_artist1 v_artist2 v_rezultat BEGIN SELECT v_artist1.comparare(v_artist2) INTO v_rezultat FROM dual; DBMS_OUTPUT.PUT_LINE(Rezultat : || v_rezultat); DBMS_OUTPUT.PUT_LINE(Rezultat invers: || v_artist2.comparare(v_artist1)); END; t_artist := t_artist(..); t_artist := t_artist(..); INTEGER;

Dac se declar una din metodele de comparare, atunci obiectele pot fi comparate n cadrul instruciunilor SQL sau n comenzi procedurale. Dac nu s-a definit nici una din metodele de ordonare, nu se pot face comparaii dect n SQL, pentru a verifica egalitatea a dou instane (dou obiecte de acelai tip sunt egale dac valorile atributelor lor sunt egale). Atunci cnd se sorteaz sau se interclaseaz un numr mare de obiecte, este preferabil o metod de mapare. Metoda MAP este mai eficient dect una ORDER, care poate compara doar cte dou obiecte la un moment dat. n schimb, o metod de ordonare poate implementa o semantic mult mai complex a lumii reale.

40 din 44

Baze de date orientate obiect lucrri de laborator

Laborator 10 Metode statice i metode constructor

Metode statice
O metod static implementeaz un comportament global la nivel de tip, invariabil relativ la instanele tipului obiect respectiv. Ea nu necesit referine la datele unei instane particulare. Prin urmare, metoda este invocat relativ la tipul obiect care o definete i nu relativ la instanele acestuia. O metod static nu are parametrul SELF. Invocarea se face prin utilizarea notaiei cu punct, prefixnd apelul metodei cu numele tipului obiect asociat (nume_tip.metoda()). Exemplu: metoda static ins a tipului tip_a insereaz o nou nregistrare n tabelul a. nregistrarea este format din dou coloane. Prima reprezint identificatorul dat ca prim parametru, iar a doua are ca valoare o referin la obiectul linie din tabelul b, identificat prin codul dat ca al doilea parametru. Operaia nu depinde de instanele tipului i de aceea a fost declarat static. Care este rezultatul cererii?

CREATE OR REPLACE TYPE tip_b AS OBJECT ( id NUMBER ); /

CREATE OR REPLACE TYPE tip_a AS OBJECT ( id NUMBER, b REF tip_b, STATIC PROCEDURE ins (p_a_id NUMBER, p_b_id NUMBER) ); /

CREATE TABLE b OF tip_b;

CREATE TABLE a OF tip_a;

41 din 44

Baze de date orientate obiect lucrri de laborator

CREATE OR REPLACE TYPE BODY tip_a AS STATIC PROCEDURE ins (p_a_id NUMBER, p_b_id NUMBER) IS BEGIN INSERT INTO a SELECT p_a_id, REF(alias) FROM b alias WHERE alias.id = p_b_id; END ins; END; / INSERT INTO b VALUES (tip_b(1)); INSERT INTO b VALUES (tip_b(2)); INSERT INTO b VALUES (tip_b(3)); EXEC tip_a.ins(1,2);

SELECT tab_a.id, tab_b.id FROM a tab_a, b tab_b WHERE REF(tab_b) = tab_a.b;

Metode constructor
n mod implicit, fiecare tip obiect are o metod constructor definit de sistem, adic o metod prin care se poate crea o instan, setnd valorile atributelor acesteia. Metoda constructor este o funcie care are cte un parametru corespunztor fiecrui atribut al tipului obiect i care returneaz o nou instan creat. Numele metodei constructor este acelai cu numele tipului obiect. Parametrii lui au numele i tipurile de date ale atributelor tipului obiect. Clauza CONSTRUCTOR permite definirea constructorilor utilizator. La definirea unui constructor este obligatorie clauza RETURN SELF AS RESULT. Acest lucru indic faptul c cel mai specific tip al valorii returnate de constructor corespunde celui mai specific tip al argumentului SELF. Funcia constructor trebuie s conin o comand RETURN simpl care nu specific explicit valoarea returnat. n acest fel, sistemul returneaz noua instan SELF definit de constructorul respectiv. 42 din 44

Baze de date orientate obiect lucrri de laborator

Un constructor definit de utilizator nu poate fi utilizat n cadrul clauzei DEFAULT dintr-o comand CREATE TABLE sau ALTER TABLE, dei metodele constructor implicite sunt permise. n SQL, parantezele sunt necesare chiar i pentru constructorii care nu au argumente, n timp ce n PL/SQL acestea sunt opionale. Pentru a fi n concordan cu limbajele orientate pe obiecte existente, a fost introdus cuvntul cheie NEW. Acesta, ns, nu este obligatoriu. Exemplu: se definete un tip t_organizator care s conin atributele cod, nume, telefon i adresa. Se va implementa un constructor care permite specificarea doar a codului i numelui organizatorului. Se va crea un bloc PL/SQL n care se vor utiliza ambii constructori (implicit i definit de utilizator).

CREATE OR REPLACE TYPE t_organizator AS OBJECT ( cod nume telefon adresa NUMBER, VARCHAR2(20), VARCHAR2(30), t_adresa,

CONSTRUCTOR FUNCTION t_organizator ( p_cod NUMBER, p_nume VARCHAR2) RETURN SELF AS RESULT );

CREATE OR REPLACE TYPE BODY t_organizator AS CONSTRUCTOR FUNCTION t_organizator ( p_cod NUMBER, p_nume VARCHAR2) RETURN SELF AS RESULT IS BEGIN SELF.cod := p_cod; SELF.nume := p_nume; SELF.telefon := 1234567; SELF.adresa := t_adresa(-1, nici o strada, NULL, NULL, NULL, NULL); RETURN; END; END; / 43 din 44

Baze de date orientate obiect lucrri de laborator

DECLARE v_org1 t_organizator; v_org2 t_organizator; BEGIN -- constructorul definit de utilizator v_org1 := NEW t_organizator(1, ABC); DBMS_OUTPUT.PUT_LINE(v_org1.adresa.strada || to_char(v_org1.cod) || v_org1.nume || v_org1.telefon); -- constructorul implicit v_org2 := t_organizator(1, XYZ, 0808080, NULL); DBMS_OUTPUT.PUT_LINE(v_org2.adresa.strada || to_char(v_org2.cod) || v_org2.nume || v_org2.telefon); END; /

Studiu individual: Tipuri colecie Motenirea tipurilor Motenirea, suprancrcarea i suprascrierea metodelor Substituirea tipurilor n ierarhia de tipuri. Ierarhii de obiecte

Laborator 11 Test 2 laborator

44 din 44

S-ar putea să vă placă și