Sunteți pe pagina 1din 137

Universitatea din Bucureti

Facultatea de Matematic i Informatic


Master Baze de date i programare Web

Sisteme de gestiune a bazelor de date


relaionale orientate pe obiecte
-
Orientare pe obiecte n ORACLE9i

Curs
2 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Cuprins
Cuprins............................................................................................................... 2
Schi general .................................................................................................. 3
1. Introducere.................................................................................................... 4
1.1. Obiecte i tipuri obiect Oracle ................................................................................... 4
1.2. Avantajele utilizrii obiectelor................................................................................... 5
1.3. Modelul relaional orientat pe obiecte ....................................................................... 7
2. Ce aduce nou Oracle9i? ............................................................................. 11
3. Componente de baz n Oracle Objects ..................................................... 14
3.1. Noiuni relaionale orientate pe obiecte ................................................................... 14
3.2. Definirea tipurilor obiect i colecie......................................................................... 16
3.3. Tipul de date referin .............................................................................................. 22
3.4. Definirea tabelelor obiect......................................................................................... 28
3.5. Metode ..................................................................................................................... 39
3.6. Tipuri colecie .......................................................................................................... 47
3.7. Motenirea tipurilor.................................................................................................. 57
4. Gestiunea obiectelor n Oracle................................................................... 72
4.1. Modificarea dinamic a tipurilor.............................................................................. 72
4.2. Eliminarea tipurilor obiect ....................................................................................... 80
4.3. Dependene i tipuri incomplete............................................................................... 81
4.4. Privilegii asupra tipurilor obiect i a metodelor lor ................................................. 84
4.5. Utilitare .................................................................................................................... 87
4.6. Tipuri generice i tranzitorii..................................................................................... 87
4.7. Stocarea obiectelor ................................................................................................... 91
4.8. Indeci ...................................................................................................................... 93
4.9. Partiionarea tabelelor care conin obiecte ............................................................... 96
4.10. Funcii i predicate utile ......................................................................................... 97
5. Vizualizri obiect ...................................................................................... 102
5.1. Definirea vizualizrilor obiect................................................................................ 103
5.2. Utilizarea vizualizrilor obiect n aplicaii............................................................. 106
5.3. Ierarhii de vizualizri obiect................................................................................... 116
5.4. Modificarea vizualizrilor obiect ........................................................................... 122
6. Large Objects............................................................................................ 124
Bibliografie ....................................................................................................137
Orientare pe obiecte n Oracle9i 3

Schi general
1. Prezentarea general a unui sistem de gestiune a bazelor de date relaionale orentate pe
obiecte. ([6])
2. Principalele caracteristici ale tehnologiei obiectuale (tipuri, obiecte, referine, date
complexe, ncapsulare, motenire, polimorfism).([7])
3. Tehnici de proiectare ale bazelor de date relaionale orientate obiect. Direcii de abordare.
Comparaie cu modelul relaional.([8])
4. Tipuri abstracte de date. Referine. Colecii. ([1])
5. Tehnici de abordare obiectual a aplicaiilor pstrnd modelul de date relaional.
Vizualizri obiect. ([1])
6. Gesiunea i manipularea obiectelor. ([1])
7. Gestiunea datelor nestructurate. Large Objects.([1])
4 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

1. Introducere

Combinarea a dou tehnologii, tehnologia bazelor de date relaionale si cea a programrii


orientate pe obiecte, a permis generarea conceptului de Sistem de gestiune a bazelor de date
Relationale Orientate pe Obiecte (SGBDROO Object-Relational Database Management Systems
ORDBMS). Aceste sisteme se pot realiza fie prin adugarea de caracteristici obiectuale unui sistem
relaional, fie prin adugarea de caracteristici relaionale unui sistem obiectual. Scopul este de a obine
un sistem care s ofere att simplitatea i generalitatea modelului relaional, ct i eficiena i
intuititvitatea unui model obiectual.
Tehnologia relaional a aprut in anii 70 o dat cu lucrrile lui E.F.Codd ([2]). Succesul
acestei tehnologii, confirmat de succesul sistemelor relaionale de pe piaa software (Oracle,
Microsoft SQL Server, IBM DB2, Sybase, Informix, Ingres, MySQL etc.) este datorat mai ales
faptului ca se bazeaz pe principii simple, dar riguroase din punct de vedere matematic i permite
totui modelarea datelor complexe.
ncepnd cu versiunea 8, Oracle a devenit un sistem de gestiune a bazelor de date relaional
orientat pe obiecte (SGBDROO). n Oracle8i caracteristicile obiectuale nu mai reprezint o opiune
separat ce trebuie activat dup instalare, ci fac parte din produsul de baz. Unul dintre principalele
motive pentru care aceste tehnologii nu au fost nc folosite pe scar larg a fost lipsa implementrii
unei importante caracteristici, motenirea. Aceast caracteristic este o noutate adus de Oracle9i,
ceea ce face ca tehnologia obiectual Oracle s devin mai puternic.

1.1. Obiecte i tipuri obiect Oracle


Tehnologia obiectual Oracle reprezint un nivel de abstractizare construit peste modelul
relaional deja existent. Principalele scopuri urmrite n crearea acestei tehnologii au fost:
posibilitatea crerii de tipuri definite de utilizator care s modeleze ct mai fidel obiectele
proprii unei aplicaii i care s fie tratate ca orice tip predefinit n cadrul bazei de date;
asigurarea unei infrastructuri care s permit accesul obiectual la datele stocate n baza
Oracle i minimizarea diferenelor dintre modelul de date utilizat n aplicaii i cel folosit
n baza de date;
asigurarea de pachete predefinite pentru prelucrarea noilor tipuri de date n aplicaii
multimedia, financiare i spaiale;
crearea unui cadru pentru extensibilitatea bazei de date, astfel nct tipurile de date
complexe s poat fi gestionate nativ.
Comitetele de standardizare ANSI i ISO au adugat celui mai recent standard, SQL3
(cunoscut i sub numele SQL99), caracteristici pentru gestiunea datelor complexe obiectuale. Aceste
faciliti implic definirea de extensii asupra tipurilor de date i, implicit, asupra tabelelor care
stocheaz datele de aceste tipuri. Au fost introduse structuri de control pentru a completa limbajul
SQL din punct de vedere computaional. Acestea sunt destinate crerii, prelucrrii i interogrii
structurilor de date obiectuale ce sunt stocate persistent ntr-o baz de date.
Orientare pe obiecte n Oracle9i 5

Tipurile de date folosite n modelarea bazelor de date care sunt definite de standardul SQL92
(SQL2) se numesc tipuri simplu structurate. Tehnologia obiectual a fost implementat n SQL3 prin
introducerea tipurilor complex structurate (tipuri obiect, referin i colecie) i a tipurilor
nestructurate LOB (Large OBjects).
Noile tipuri pot fi create folosind orice tip structurat sau nestructurat, predefinit sau definit de
utilizator. Tipurile definite de utilizator pot fi utilizate n aceeai manier ca i cele predefinite (de
exemplu, pentru definirea coloanelor n cadrul tabelelor relaionale). Definiia unui astfel de tip
trebuie s ncapsuleze atribute i operaii ntr-o singur entitate. n SQL3, un tip de date trebuie definit
prin specificarea:
atributelor care reprezint valoarea tipului;
relaiilor de egalitate i ordine dintre obiectele de acel tip;
operaiilor care i definesc comportamentul.
Tipurile abstracte de date pot fi extinse prin intermediul subtipurilor, care motenesc structura
i comportamentul de la supertip. Instanele tipurilor pot fi stocate persistent n baza de date doar prin
intermediul coloanelor din tabele.
Metadatele (informaiile din dicionarul datelor) pentru tipurile definite de utilizator sunt
stocate ntr-o schem care este disponibil interfeelor de programare existente (SQL, PL/SQL, Java
etc.).
Tipurile obiect Oracle sunt tipuri de date definite de utilizator care fac posibil modelarea
unor entiti complexe din lumea real, astfel nct s fie considerate entiti unitare (obiecte) n baza
de date.
Tipurile i caracteristicile obiect asigur metode eficiente de organizare i accesare a
informaiilor din baza de date. n spatele nivelului obiectual, n reprezentarea intern, informaiile sunt
stocate n coloane i tabele. Avantajul este c utilizatorul poate lucra cu acestea n termeni de entiti
ale lumii reale, fapt ce d mai mult semnificaie datelor. Poate fi abordat att varianta relaional de
interogare a tabelelor, care caracterizeaz o entitate prin valorile atributelor ei, ct i varianta
obiectual, care consider entitatea ca fiind un obiect unitar.
ntr-un sistem relaional orientat pe obiecte sunt posibile trei modaliti de abordare a
modelrii bazei de date:
utilizarea n paralel a caracteristicilor obiectuale i a celor relaionale, prin crearea de
vizualizri obiect asupra datelor relaionale existente, pentru a le reprezenta i accesa n
concordan cu un model obiectual;
abordarea relaional, prin tehnici clasice de proiectare care utilizeaz exclusiv tipurile
simplu structurate pentru stocarea datelor;
abordarea orientat pe obiecte, prin stocarea datelor n cadrul tabelelor obiect unde fiecare
linie reprezint un obiect.

1.2. Avantajele utilizrii obiectelor


Tipul obiect este similar mecanismului de clas existent n C++ i Java. Ca i clasele, tipurile
obiect faciliteaz proiectarea entitilor i logicii unor modele complexe din lumea real, iar gradul de
reutilizare al structurilor obiectuale asigur dezvoltarea rapid i eficient a aplicaiilor de baze de
date. Integrnd nativ tipurile obiect n baza de date, sistemul Oracle permite dezvoltatorilor de
6 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

aplicaii s acceseze n mod direct structurile de date utilizate. Nu este necesar un nivel intermediar de
asociere ntre obiectele client/server i coloanele sau tabelele bazei de date relaionale. Abstractizarea
obiectelor i ncapsularea comportamentului acestora fac aplicaiile uor de neles i de ntreinut,
acestea rspunznd n mod eficient la modificri sau extinderi ulterioare.

ncapsularea operaiilor i a datelor


Tabelele bazei nu pot conine dect date. Obiectele fac posibil stocarea operaiilor care pot fi
executate asupra datelor respective. ncapsularea permite limitarea i controlul accesului la un obiect
prin intermediul metodelor definite de tipul obiectului respectiv.
De exemplu, ntr-o aplicaie de gestiune a operelor de art dintr-un muzeu, un tip obiect
corespunztor entitii galerie poate include o metod de nsumare a valorilor tuturor operelor de art
expuse n cadrul acelei galerii. Un tip obiect asociat entitii opera poate defini metode pentru
obinerea titlului, a numelui artistului corespunztor, a dimensiunilor acesteia sau pentru generarea
unui raport al surselor bibilografice care au menionat-o.

Eficiena
ntr-un tip obiect, metodele sunt stocate mpreun cu datele, fiind disponibile oricrei aplicaii
care trebuie s le utilizeze. Dezvoltatorii pot beneficia de funcionalitatea tipurilor, deja implementat
la nivelul bazei de date. n acest fel nu este necesar crearea de structuri similare n fiecare modul al
aplicaiei.
Mai multe obiecte nrudite pot fi ncrcate i prelucrate ca un ntreg. O singur cerere ctre
server pentru ncrcarea unui obiect poate returna i alte obiecte care sunt legate de acesta prin
referine obiect. De exemplu, se selecteaz un obiect galerie i se invoc metoda de obinere a
numelui acesteia, a cldirii din care face parte i a mai multor componente ale obiectului adresa
corespunztor. Toate aceste informaii sunt obinute printr-o singur transmisie de la server-ul de baze
de date ctre maina client.

Modaliti de reprezentare a relaiilor de incluziune


ntr-un sistem relaional este dificil reprezentarea relaiilor complexe de tip parte din
(incluziune). De exemplu, un piston i un motor au acelai statut ntr-un tabel relaional de produse.
Pentru a reprezenta pistoanele ca fcnd parte din motoare, trebuie creat o schem relativ complicat
coninnd tabele avnd constrngeri de integritate referenial. Pe de alt parte, tipurile obiect
constituie o modalitate simpl pentru descrierea relaiilor de acest tip. Un obiect poate avea alte
obiecte ca atribute, iar atributele obiect pot avea la rndul lor atribute de tip obiect. n acest fel, se
poate crea o list ierarhic de pri prin simpla ntreptrundere a tipurilor obiect.

Modaliti de captare a proprietilor de integritate a datelor


Tipurile obiect permit captarea unor proprieti specifice ale unei entiti cum ar fi faptul c
atributele sale formeaz un ntreg. De exemplu, o adres trebuie s conin strada, numrul, oraul,
judeul, codul potal i ara. Dac lipsete unul dintre aceste elemente, atunci adresa este incomplet.
Spre deosebire de un tip obiect, un tabel relaional nu poate implementa la nivel de baz de date faptul
c mai multe coloane ale unui tabel formeaz mpreun un ntreg.
Orientare pe obiecte n Oracle9i 7

1.3. Modelul relaional orientat pe obiecte


Sistemul Oracle implementeaz tehnologia obiectual ca o extensie a modelului relaional.
Interfaa obiectual suport funcionalitatea standard pentru date relaionale: interogri,
permanentizare, arhivare i recuperare de date, conectivitate scalabil, blocare la nivel de linie,
consisten la citire, partiionare de tabele, cereri paralelizate, definirea de grupri, indeci sau
sinonime, export/import de date, ncrcare de date etc. SQL i interfeele de programare ale sistemului
Oracle (PL/SQL, Java, OCI, Pro*C/C++, OO4O) au fost extinse pentru a prelucra obiectele.
Rezultatul este un model relaional orientat pe obiecte, care ofer o interfa obiectual eficient i
intuitiv, pstrnd concurena i generalitatea dintr-o baz de date relaional.

Motenirea tipurilor
Sistemul Oracle suport motenirea simpl. Dintr-un tip se pot deriva unul sau mai multe
subtipuri. Motenirea simpl a tipurilor presupune crearea ierarhiilor de tipuri, prin definirea de
niveluri succesive de subtipuri specializate care deriv dintr-un tip printe comun. Numrul de
niveluri dintr-o ierarhie este nelimitat.
Subtipurile derivate motenesc proprietile tipului obiect printe pe care l extind. De
exemplu, din tipul obiect general organizator se pot deriva tipuri specializate de organizatori,
organizator_particular i organizator_de_stat, fiecare cu atribute i metode specifice. Tipurile
specializate pot adauga noi atribute sau redefini metode motenite de la tipul printe. Ierarhia de
tipuri rezultat furnizeaz un nivel ridicat de abstractizare pentru gestiunea complexitii unui model
de date.
n sistemul Oracle, motenirea la nivel de client se realizeaz prin integrarea de cod C++ i
Java n baza de date. Pentru C++ se folosete Object Modelling Option din Oracle Designer n
vederea producerii de comenzi LDD i de cod C++ bazat pe diagramele de clase specificate n UML
(Universal Modelling Language). Pentru Java se folosete caracteristica custom datum din driver-ul
Oracle JDBC. Metoda de motenire la nivel de server este asigurat n Java de ctre Oracle 9iJVM.

Modificarea dinamic a tipurilor


n Oracle9i, modificarea unui tip definit de utilizator (type evolution) se poate face dinamic i
cu propagarea schimbrilor. Obiectele care depind de tipul modificat sunt validate utiliznd comanda
iniial de creare. Dac tipul respectiv sau oricare dintre tipurile dependente de el nu trec de validrile
respective, atunci comanda de modificare este abandonat. n acest caz, nu este creat noua versiune
de tip i schema de dependen a obiectelor rmne neschimbat.
Metadatele asociate tabelelor i coloanelor care utilizeaz un tip modificat sunt actualizate n
concordan cu noua definiie a tipului, astfel nct noile obiecte s fie stocate n noul format. Datele
existente pot fi convertite la noul format simultan sau treptat, pe msur ce sunt modificate. Ele sunt
prezentate n formatul noii definiii a tipului, chiar dac sunt nc stocate n vechiul format.
8 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Vizualizri obiect
O vizualizare obiect este o modalitate de a accesa datele relaionale utiliznd metode
caracteristice modelului obiectual. Vizualizrile obiect sunt tabele obiect virtuale. Aceste obiecte ale
schemei dau posibilitatea de a dezvolta aplicaii orientate pe obiecte fr a schimba schema relaional
iniial.
Pe lng stocarea nativ a datelor obiectuale pe server, sistemul Oracle permite crearea unei
abstractizri obiectuale a datelor relaionale existente, prin mecanismul vizualizrilor obiect. Liniile
obiect care aparin unei vizualizri obiect pot fi accesate n aceeai manier ca i liniile dintr-un tabel
obiect. Pot fi create vizualizri obiect corespunztoare tipurilor definite de utilizator, care se refer la
datele stocate n schema relaional.
Vizualizrile obiect permit valorificarea polimorfismului implementat n cadrul ierarhiilor de
tipuri. O expresie polimorfic poate lua o valoare de tipul declarat al expresiei sau de orice subtip al
tipului respectiv. Se poate construi o ierarhie de vizualizri obiect care oglindete o parte sau ntreaga
structur a unei ierarhii de tipuri. n acest context, se pot executa cereri asupra unei vizualizri din
ierarhie pentru a accesa date, la nivelul de specializare dorit. De asemenea, dac se interogheaz o
vizualizare obiect care are subvizualizri, se obin date polimorfice (linii obiect din vizualizarea
interogat i din subvizualizrile sale).

Extensii obiectuale SQL


Pentru suportul noilor caracteristici relaionale orientate pe obiecte, au fost adugate extensii
ale limbajului de definire a datelor:
pentru crearea, modificarea i suprimarea tipurilor obiect (CREATE TYPE, CREATE
TYPE BODY, ALTER TYPE, DROP TYPE);
pentru stocarea tipurilor obiect n tabele;
pentru crearea, modificarea i tergerea vizualizrilor obiect (CREATE VIEWAS
OBJECT).
De asemenea, pentru a facilita lucrul cu tipuri obiect, referine i colecii au fost create
extensii specifice ale limbajului de prelucrare i interogare a datelor.

Extensii obiectuale PL/SQL


PL/SQL este limbajul de programare al bazei de date Oracle, strns integrat cu SQL. Acesta
opereaz att cu tipuri predefinite, ct i cu tipuri definite de utilizator. Dezvoltatorii pot folosi
PL/SQL pentru a implementa logica aplicaiei prin intermediul operaiilor asociate tipurilor obiect.
Astfel, execuia se realizeaz pe server-ul de baze de date obinnd un plus de eficien.

Suport Java pentru obiectele Oracle


Oracle Java Virtual Machine este strns integrat cu sistemul Oracle i suport accesul la
obiectele Oracle prin SQL dinamic, utiliznd extensiile obiect Java Database Conectivity (JDBC), sau
prin SQL static, utiliznd SQLJ. Similar limbajului PL/SQL, Java permite implementarea logicii
aplicaiilor utiliznd operaii proprii tipurilor obiect. Versiunea Oracle9i permite crearea de tipuri SQL
asociate unor clase Java existente, asigurnd stocare persistent a obiectelor Java.
Orientare pe obiecte n Oracle9i 9

Translatorul de tipuri obiect


Translatorul de tipuri obiect (Oracle Type Translator) permite crearea de imagini (mapping)
ale tipurilor obiect pe maina client. Utiliznd informaiile din dicionarul datelor, se pot genera fiiere
de tip header ce conin clase Java, structuri i indicatori C. Fiierele generate pot fi utilizate de
programe n limbaj main pentru accesul transparent la obiectele bazei de date.

Proceduri externe
Funciile, procedurile sau metodele unui tip obiect pot fi implementate n limbajul procedural
PL/SQL, dar i n Java sau C ca subprograme externe. Procedurile externe sunt potrivite pentru sarcini
care pot fi executate mai rapid sau implementate mai uor n alt limbaj de programare. De exemplu,
limbajul C este eficient la calcule n dubl precizie, astfel nct anumite operaii care necesit vitez
de calcul, precum transformarea Fourier sau conversia formatului unei imagini, sunt mai eficiente n
programe C. Procedurile externe sunt executate n condiii de maxim securitate n afara adreselor
server-ului Oracle.
Tipul generic este predefinit i permite unei proceduri s lucreze cu date de orice tip,
predefinit sau definit de utilizator. Se pot scrie proceduri externe generice care s declare unul sau mai
muli parametri de tip generic.

Memoria virtual client


Sistemul Oracle rezerv un spaiu de memorie virtual pentru a asigura accesul eficient la
obiectele stocate persistent n baza de date. n acest spaiu se pot stoca copii ale obiectelor stocate n
baza de date. Astfel, aplicaiile pot consulta informaiile la o vitez superioar. Orice modificri fcute
asupra obiectelor din memoria virtual pot fi permanentizate n baza de date utiliznd extensiile
obiectuale ale interfeei de programare OCI.

Extensii obiectuale Oracle Call Interface


OCI (Oracle Call Interface) asigur o interfa pentru programarea de aplicaii adaptat
pentru dezvoltatorii i utilitarele care folosesc posibilitile obiectuale ale sistemului. Este furnizat un
mediu de rulare cu funcii de conectare la server-ul Oracle i de control al tranzaciilor care acceseaz
obiectele de pe server. Dezvoltatorii de aplicaii pot accesa i prelucra obiectele din memoria virtual
client n mod navigaional (traversnd un graf de obiecte interconectate) sau n mod asociativ
(specificnd natura datelor printr-o comand LMD declarativ). De asemenea, OCI asigur funcii
pentru accesarea metadatelor referitoare la tipurile obiect definite pe server, existente la momentul
rulrii. Acest set de funcii faciliteaz accesul dinamic la informaiile despre obiecte i la datele
obiectuale stocate n baza de date.

Extensii obiectuale Pro*C/C++


Precompilatorul Pro*C/C++ este o interfa de programare care permite integrarea de
comenzi SQL n programe C sau C++, oferind un nivel mai nalt de abstractizare dect OCI. Cu
referire la tehnologia obiectual, Pro*C are urmtoarele caracteristici:
permite dezvoltatorilor de aplicaii s foloseasc memoria virtual obiect de pe maina
client i utilitarul Oracle Type Translator;
suport utilizarea variabilelor de legtur C pentru tipurile obiect;
10 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

asigur o sintax simplificat pentru alocarea i eliberarea spaiului de stocare a obiectelor


i accesarea lor prin comenzi LMD sau prin interfaa navigaional.
Pro*C aduce dezvoltatorilor de aplicaii multiple beneficii. Dintre acestea se remarc:
verificarea variabilelor de legtur de pe maina client relativ la schema de pe server, la
momentul compilrii;
asocierea automat a datelor obiectuale dintr-un server Oracle cu variabilele de legtur
de pe maina client;
modaliti simple de gestiune i prelucrare a obiectelor bazei de date n cadrul unui proces
client.

Extensii obiectuale Oracle Objects for OLE


OO4O (Oracle Objects for OLE) este un set de interfee/obiecte COM Automation pentru
conectarea la server-ele Oracle, executarea de cereri i prelucrarea rezultatelor. Interfeele de
automatizare n OO4O asigur un acces simplu i eficient la caracteristicile Oracle9i. Ele pot fi
utilizate practic din orice limbaj de programare sau n fiierele script care suport tehnologia
Microsoft COM Automation (Visual Basic, Visual C++, VBA n Excel, VBScript i JavaScript n IIS
ActiveServerPages).
Orientare pe obiecte n Oracle9i 11

2. Ce aduce nou Oracle9i?

Tehnologia obiectual reprezint una dintre principalele preocupri ale proiectanilor i


dezvoltatorilor sistemului de gestiune a bazelor de date Oracle. ncepnd cu versiunea Oracle9i, au
fost introduse caracteristici importante care dau for acestei tehnologii, ncurajnd i facilitnd
abordarea obiectual a aplicaiilor de baze de date. n continuare sunt prezentate principalele
caracteristici relative la orientarea pe obiecte aduse de versiunea Oracle9i.

Sinonime de tipuri
ncepnd cu versiunea Oracle9i, se pot defini sinonime pentru tipurile definite de utilizator.
Acestea ofer aceleai avantaje ca i sinonimele asociate celorlalte obiecte ale unei scheme, i anume
simplitatea i flexibilitatea referirii unui tip obiect. Astfel, aplicaiile care utilizeaz sinonime de tipuri
pot funciona cu modificri minime n diferite scheme de obiecte.

Constructori definii de utilizator


Funciile constructor permit iniializarea instanelor obiect. Constructorii definii de utilizator
faciliteaz modificarea tipurilor. Definirea mai multor constructori nltur necesitatea schimbrii
tuturor liniilor de cod existente care apeleaz constructori, doar pentru a reflecta modificarea de
structur respectiv (de exemplu, inserarea unui nou atribut).

Motenirea tipurilor SQL


Modelarea ct mai fidel a entitilor lumii reale i a relaiilor dintre acestea reprezint primul
pas n valorificarea caracteristicilor obiectuale. Se pot defini versiuni specializate de tipuri obiect sub
forma subtipurilor. Acestea pot fi organizate ntr-o ierarhie de tipuri ce are la baz un tip comun
(rdcin). n cadrul ierarhiei se poate particulariza implementarea i executarea metodelor, n funcie
de nivelul de abstractizare al fiecrui tip.

Ierarhii de vizualizri obiect


Se pot crea ierarhii de vizualizri obiect, bazate pe o parte sau pe toate tipurile dintr-o ierarhie
de tipuri. Ierarhiile de vizualizri obiect simplific extragerea obiectelor de un anumit tip (i eventual
de subtipuri ale lui) n cadrul cererilor i a operaiilor LMD. De asemenea, aceste ierarhii permit
trecerea la un model obiectual complex, pstrnd structura relaional existent.

Modificarea dinamic a tipurilor


Tipurile SQL definite de utilizator pot fi modificate dinamic (type evolution). n versiunile
anterioare, pentru modificarea unui tip era necesar exportarea tuturor datelor dependente, recrearea
tipului, importarea datelor dependente i revalidarea tuturor obiectelor dependente invalidate de
tergerea temporar a tipului. n Oracle9i, toate obiectele schemei care sunt dependente de tipul
modificat sunt revalidate automat la prima referire, utiliznd noua definiie a tipului respectiv.
12 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Funcii agregat definite de utilizator


Funciile agregat predefinite nu se pot folosi dect n lucrul cu date scalare. ncepnd cu
versiunea Oracle9i este permis crearea de implementri proprii ale funciilor agregat existente i
definirea funciilor agregat complet noi, astfel nct acestea s poat fi folosite mpreun cu tipurile
definite de utilizator.

Tipuri de date generice i tranzitorii


Procedurile externe pot accepta parametri de tip generic care s conin valori de orice tip
scalar sau definit de utilizator. n acest fel, nu este necesar s se implementeze mai multe versiuni ale
aceleiai proceduri externe doar pentru a putea accepta mai multe tipuri de date.

Indeci bazai pe funcii


Indecii bazai pe funcii pot folosi metode ale tipurilor obiect. Aceti indeci apar atunci cnd
este folosit frecvent o anumit condiie care folosete o metod a unui tip obiect. Pentru a avea sens
crearea acestui tip de index, metoda respectiv trebuie s fie determinist, n sensul c pentru aceleai
argumente, ea trebuie s furnizeze acelai rezultat, n orice moment.

Colecii pe mai multe niveluri


Coleciile (vectori i tablouri imbricate) pot conine elemente care sunt la rndul lor colecii
sau obiecte avnd atribute de tip colecie. n acest fel apar structuri complexe de date reprezentate prin
colecii pe mai multe niveluri care pot modela n mod optim anumite entiti din lumea real.

Oracle C++ Call Interface


Noua interfa Oracle corespunztoare limbajului C++ (OCCI), construit pe baza Oracle
Call Interface (OCI), permite utilizarea caracteristicilor obiectuale, a claselor native i a metodelor
limbajului C++ cu scopul de a accesa informaiile din baza de date Oracle. OCCI este o colecie de
clase C++, care permit unui program C++ s se conecteze la o baz de date Oracle, s execute
comenzi SQL, s obin rezultatul unei cereri, s execute proceduri stocate n baza de date sau s
acceseze metadate relativ la obiectele unei scheme.

Stocarea persistent a obiectelor Java


Pentru a asigura stocarea persistent a obiectelor Java, este posibil crearea de tipuri SQL
asociate unor clase Java existente. Acestea se numesc tipuri SQL ale limbajului Java sau tipuri SQLJ.

Large Objects
Sistemul Oracle9i aduce mbuntiri semnificative tipurilor de date LOB i modalitilor de
utilizare a acestora.
Pentru a asista utilizatorii n procesul de migrare de la datele stocate n format LONG la cele
n format LOB, au fost introduse o serie de faciliti. Au fost extinse comenzile ALTER TABLE i
ALTER INDEX, tranziia avnd implicaii minime asupra datelor stocate n tabele. Aplicaiile care
utilizeaz coloane migrate necesit modificri minore. Majoritatea subprogramelor predefinite ce
acioneaz asupra obiectelor de tip LONG au fost extinse s accepte tipul LOB.
Orientare pe obiecte n Oracle9i 13

n Oracle9i, obiectele LOB persistente se pot accesa folosind funciile i operatorii standard
corespunztori tipului VARCHAR2 (SUBSTR, INSTR etc.). Aceti operatori sunt recomandai mai ales
atunci cnd valorile LOB sunt de dimensiune redus (ntre 10 i 100 KB).
Interfeele OCCI, JDBC i OLE DB au fost mbuntite astfel nct s suporte accesul i
prelucrarea datelor de tip LOB.
n ceea ce privete pachetul predefinit DBMS_LOB, au fost introduse proceduri care permit
ncrcarea difereniat a obiectelor de tip BLOB, respectiv CLOB din fiiere ale sistemului de operare,
care sunt accesate folosind tipul BFILE. De asemenea, sistemul Oracle9i elimin multe restricii
asupra tipurilor LOB, existente n versiunile precedente
14 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

3. Componente de baz n Oracle Objects

Abordarea relaional orientat pe obiecte introduce noi funcionaliti, concepte i resurse. n


cele ce urmeaz se vor prezenta aceste noi concepte, mpreun cu modalitile de implementare
disponibile n Oracle9i.

3.1. Noiuni relaionale orientate pe obiecte


Tehnologia obiectual Oracle implic existena unor tehnici specifice pentru definirea,
prelucrarea i gestiunea tipurilor obiect, referin i a coleciilor. De asemenea, sunt necesare mijloace
de implementare pentru extinderea tipurilor i organizarea acestora n ierarhii.

Tipuri obiect
Un tip obiect este o abstractizare a unei entiti din lumea real. El reprezint un tip de date
complex structurat, stocat ntr-o schem a bazei de date. Tipurile obiect au urmtoarele componente:
un nume, care identific n mod unic tipul respectiv n cadrul schemei;
atribute, care modeleaz structura i starea entitii reprezentate;
metode, care implementeaz comportamentul entitii respective.
Atributele conin informaii referitoare la caracteristicile obiectelor de tipul respectiv (de
exemplu, un tip obiect opera poate avea atributele nume, tip, autor, data_achizitiei etc.). Tipul de date
declarat al unui atribut poate fi tot un tip obiect. Atributele instanei unui obiect constituie datele
obiectului respectiv.
Metodele sunt proceduri sau funcii care implementeaz comportamentul obiectelor,
permind aplicaiilor s execute operaiile necesare asupra atributelor unui obiect. Spre deosebire de
atribute, metodele nu sunt obligatorii.
Tipurile obiect se pot utiliza n acelai fel n care sunt utilizate i tipurile de date simplu
structurate (NUMBER, VARCHAR2, DATE etc.). De exemplu, aceste tipuri pot fi folosite pentru
definirea coloanelor ntr-un tabel relaional sau pentru declararea de variabile. O valoare de tip obiect
se numete instan a acelui tip sau, simplu, obiect.
Exist cteva diferene ntre tipurile obiect i celelalte tipuri de date specifice unei baze
relaionale:
nu exist tipuri obiect predefinite incluse la instalarea bazei, ele putnd fi definite de ctre
utilizatori;
tipurile obiect au o structur complex, neuniform (atribute, metode);
tipurile obiect sunt mai puin generice dect tipurile native, acesta fiind unul dintre marile
avantaje.
Tipurile obiect pot fi imaginate ca un plan de structur, iar obiectul ca fiind produsul concret
construit conform planului. Aceste tipuri sunt obiecte persistente ale schemei bazei de date, subiect al
acelorai categorii de controale administrative ca i celelalte obiecte ale schemei.
Orientare pe obiecte n Oracle9i 15

Prin crearea tipurilor obiect se poate modela structura unor entiti din lumea real, cu care
programele de aplicaii s lucreze n mod direct. Aceast abordare permite gestiunea simplificat i
intuitiv a datelor.
O schem relaional, cu tabele i coloane de tipuri native, proiecteaz modelul ntr-un cadru
bidimensional.
Tipurile obiect permit captarea relaiilor structurale interne dintre obiecte i atribute. Cu
ajutorul tipurilor obiect se pot stoca pri nrudite de date, mpreun cu operaiile specifice acestora. n
cadrul aplicaiilor, obiectele pot fi captate i prelucrate ca nite uniti atomice.

Motenirea tipurilor
Un tip obiect poate fi specializat prin crearea de subtipuri. Un subtip adaug unele
caracteristici care l difereniaz de tipul iniial i anume, atribute sau metode adiionale. Operaia de
creare a subtipurilor se numete derivare, iar tipul obiect printe poart numele de supertip sau
generalizare a subtipului derivat.
Subtipurile, fiind versiuni specializate ale printelui lor, conin att atributele i metodele
printelui, ct i pe cele definite local. Subtipurile i supertipurile sunt conectate prin relaia de
motenire i definesc n acest fel o ierarhie de tipuri.

Obiecte
La iniializarea unei variabile de tip obiect se creeaz o instan a acelui tip sau, altfel spus, se
instaniaz un obiect. Un obiect conine atributele i metodele definite de tipul su. Spre deosebire de
tipul obiect care reprezint schia unui model de date, instana este o structur concret care conine
informaii. Obiectele sunt stocate n baza de date. Prin urmare, atributele unei instane au valori, iar
metodele ei pot fi apelate n concordan cu acestea.
Obiectele sunt gestionate nativ de ctre server-ul de baze de date. Tipurile obiect pot fi
folosite ca tipuri de coloane (pentru stocarea coloanelor obiect) sau ca tipuri de tabele obiect (pentru
stocarea liniilor obiect). Atunci cnd sunt folosite pentru coloane obiect, tipurile obiect se comport ca
nite domenii relaionale clasice n cadrul unor tabele relaionale. n plus, fiecare linie obiect are
asociat un identificator unic, numit identificator obiect (Object IDentifier), care poate fi folosit pentru
referirea oricrui obiect stocat ntr-un tabel obiect.
Obiectele sunt componente ale schemei i sunt integrate complet mpreun cu celelalte
obiecte din cadrul acesteia. Ele pot fi indexate i partiionate. De asemenea, cererile care implic
obiecte pot fi paralelizate i sunt optimizate de ctre optimizorul pe baz de costuri, care utilizeaz
statisticile meninute de sistem.
Fundamentate n cadrul server-ului de baze de date Oracle, obiectele sunt gestionate la
acelai nivel ridicat de fiabilitate, disponibilitate i scalabilitate ca i datele relaionale.

Metode
Metodele sunt funcii sau proceduri declarate n definiia unui tip obiect pentru a implementa
un anumit comportament.
Una dintre principalele utilizri a metodelor este aceea de a asigura accesul la date. n acest
fel este furnizat un control sporit asupra accesului la informaii i un grad ridicat de securitate.
Atunci cnd sunt definite metode pentru operaiile previzibile asupra obiectelor, aplicaiile nu
mai trebuie s implementeze n mod redundant acelai comportament n mai multe module, ci doar s
apeleze metoda corespunztoare unui anumit obiect. n acest fel, pe lng posibilitatea reutilizrii
16 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

codului, se ctig i eficien deoarece metodele se execut direct pe server.


Se pot defini metode pentru compararea instanelor unui tip obiect (metode de comparare).
Pentru executarea operaiilor care nu folosesc date particulare din obiecte i care sunt globale la nivel
de tip obiect se implementeaz metode statice.

Colecii
Pentru modelarea relaiilor one-to-many, sistemul Oracle asigur dou tipuri colecie, vector
i tablou imbricat. Tipurile colecie pot fi utilizate la fel ca i celelalte tipuri de date pentru a defini
tipul atributelor, coloanelor etc. De exemplu, se poate asocia unui obiect de tip t_opera_de_arta un
atribut de tip tablou imbricat care s conin colecia de polie de asigurare corespunztoare sau un
atribut de tip vector de dimensiune trei care s conin dimensiunile obiectului respectiv.

Tabele obiect
Un tabel obiect este un tabel special n care fiecare linie reprezint un obiect. Obiectele
stocate trebuie s existe n cadrul schemei curente sau ntr-una asupra creia utilizatorul are
privilegiile necesare. Tabelul obiect are o singur coloan de tip obiect.
Tabelele obiect pot fi privite din dou puncte de vedere diferite:
obiectual, ca un tabel cu o singur coloan n care fiecare linie este o instan a tipului
obiect asociat;
relaional, ca un tabel multicoloan n care fiecare atribut al tipului asociat reprezint o
coloan.
Obiectele care ocup linii complete n tabelele obiect se numesc linii obiect. Obiectele care
ocup coloane n cadrul tabelelor relaionale sau sunt atribute de tip obiect se numesc coloane obiect.

Tipul de date referin


n modelul relaional, relaiile one-to-many sunt implementate prin intermediul cheilor
externe. Tipurile obiect asigur o modalitate mai eficient de a exprima aceste relaii atunci cnd
obiectul corespunztor cardinalitii one este o linie obiect. Mai exact, sistemul Oracle asigur un tip
de date predefinit (referin) numit REF, care ncapsuleaz referinele la liniile obiect de un tip obiect
specificat.
Din perspectiva modelrii, referinele fac posibil captarea relaiei dintre dou linii obiect.
Pentru a construi referine, sistemul utilizeaz identificatorii obiect. O referin poate fi utilizat
pentru a consulta sau modifica obiectul pe care l refer. De asemenea, o referin se poate folosi
pentru a obine o copie a obiectului referit. Singurele schimbri care pot fi fcute asupra unei valori de
tip referin sunt de a nlocui coninutul coloanei de tipul respectiv cu un alt obiect de acelai tip sau
cu valoarea null.

3.2. Definirea tipurilor obiect i colecie


Pentru crearea tipurilor obiect i a celor colecie se utilizeaz comenzile CREATE TYPE i
CREATE TYPE BODY. Comanda CREATE TYPE creeaz specificaia unui tip obiect, SQLJ, colecie
sau incomplet. Prin intermediul acestei comenzi se specific numele tipului, atributele sale, metodele
i alte proprieti suplimentare. Comanda CREATE TYPE BODY permite implementarea metodelor
care au fost declarate n comanda CREATE TYPE. Procedeul este asemntor crerii pachetelor
PL/SQL.
Dac se creeaz un tip obiect pentru care specificaia tipului declar doar atribute, nu i
Orientare pe obiecte n Oracle9i 17

metode, atunci nu mai este necesar o comand CREATE TYPE BODY. Acelai lucru este valabil i la
crearea unui tip obiect SQLJ, implementarea tipului fiind specificat de ctre o clas Java sau de o
structur C.
n mod implicit, sistemul Oracle definete o metod constructor pentru fiecare tip definit de
utilizator. Un constructor este o funcie furnizat de sistem care este folosit n comenzi SQL sau
blocuri PL/SQL pentru a construi o instan a unui tip obiect. Numele constructorului este acelai cu
numele tipului asociat. Sistemul permite utilizatorului s defineasc propriul constructor.
Parametrii metodei constructor a tipului obiect corespund atributelor tipului respectiv i
respect ordinea acestora din definiia tipului. n cazul unui tip colecie, parametrii constructorului
reprezint elementele coleciei respective.
Un tip incomplet este un tip creat nainte de a i se specifica definiia, pentru a putea fi referit
n alte structuri. Se numete incomplet pentru c are un nume, dar nu are atribute sau metode. Acest
tip poate fi referit de alte tipuri i este folosit la definirea tipurilor care se refer unul pe cellalt (cross
reference). De remarcat c este obligatorie specificarea n ntregime a definiiei unui tip, nainte de a-l
utiliza la crearea unui tabel sau a unei coloane obiect.
Pentru crearea unui tip obiect se utilizeaz urmtoarea sintax1:
CREATE [OR REPLACE] TYPE [schema.]nume_tip
[AUTHID {CURRENT_USER | DEFINER}
{ {IS | AS} OBJECT | UNDER [schema.]nume_supertip}
( {atribut1 tip_de_date1 | spec_metoda1}
[, {atribut2 tip_de_date2 | spec_metoda2] )
[ [NOT] FINAL]
[ [NOT] INSTANTIABLE];
La recrearea unui tip, cu ajutorul clauzei OR REPLACE, sistemul dezactiveaz indecii bazai
pe funcii ce depind de tipul respectiv.
Dac se omite numele schemei, sistemul creeaz tipul n schema curent. Eventualele erori
aprute la crearea tipului pot fi consultate cu ajutorul comenzii SHOW ERRORS din SQL*Plus.
Clauzele referitoare la drepturile de invocare (AUTHID) specific dac metodele tipului
obiect se execut cu privilegiile i n schema utilizatorului curent (CURRENT_USER) sau cu
privilegiile i n schema proprietarului (DEFINER). Corespunztor celor dou opiuni disponibile
tipul este creat cu drepturi de apelant, respectiv cu drepturile proprietararului. Aceast specificaie se
aplic i pentru corpul tipului. De asemenea, clauza determin modalitatea n care sistemul Oracle
identific numele externe din cererile, operaiile LMD i comenzile SQL dinamice aflate n metodele
membre ale tipului.
Restriciile referitoare la clauza de invocare sunt urmtoarele:
se poate specifica doar pentru tipuri obiect, nu i pentru tipurile colecie (tablouri
imbricate sau vectori);
se poate specifica n definiia subtipurilor, dar numai pentru claritate cu aceeai valoare
din supertip, deoarece subtipurile motenesc modelul de acordare de drepturi al
supertipului lor (schimbarea acestei opiuni n cadrul subtipului duce la eroarea PLS-
00722: supertypes's AUTHID is different than subtype's AUTHID);
dac supertipul a fost creat cu drepturi DEFINER, subtipurile trebuie create n aceeai

1
Pentru a ctiga claritate i simplitate au fost eliminate elementele de sintax proprii caracteristicilor SQLJ ce permit
asocierea claselor Java i structurilor C cu tipuri obiect persistente Oracle.
18 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

schem ca i supertipul.
Clauza AS OBJECT permite crearea unui tip obiect rdcin, iar UNDER se utilizeaz pentru
a defini un subtip al unui tip specificat. n acest ultim caz, supertipul existent trebuie s fie un tip
obiect care s permit crearea de subtipuri (NOT FINAL), altfel este returnat eroarea PLS-00590:
attempting to create a subtype UNDER a FINAL type. Un subtip motenete caracteristicile
supertipului su i, pentru a se distinge de acesta, trebuie s suprascrie sau s adauge proprieti.
Atributele care formeaz structura obiectului sunt cmpuri de date caracterizate prin nume i
tip. Pentru orice tip obiect trebuie specificat cel puin un atribut. Dac se creeaz un subtip, numele
noilor atribute nu pot fi identice cu numele atributelor sau metodelor din supertip.
Tipurile de date ale atributelor pot fi predefinite sau definite de utilizator. Restriciile relative
la atribute sunt:
nu sunt permise atribute de tip ROWID, LONG, LONG RAW sau UROWID;
pentru un atribut de tip referin, obiectul int trebuie s aib un identificator obiect;
la crearea unui tip colecie nu se pot specifica elemente de tip generic2.
Clauza NOT FINAL permite extinderea tipului respectiv (valoarea implicit este FINAL).
Clauza NOT INSTANTIABLE specific dac pot fi construite instane ale obiectului respectiv
(valoarea implicit este INSTANTIABLE). Se specific NOT INSTANTIABLE dac nu exist
constructor (definit de utilizator sau implicit) pentru tipul respectiv. Trebuie specificate aceste cuvinte
cheie pentru tipurile care au toate metodele neinstaniabile (motenite sau specificate n definiie) sau
care nu definesc nici un atribut nou.
Sintaxa detaliat pentru specificaia unei metode (spec_metoda) este:
[ [ [NOT] OVERRIDING] [ [NOT] FINAL] [ [NOT] INSTANTIABLE]
{ {MEMBER | STATIC}
{PROCEDURE nume_proc
[ (parametru tip_de_date [, parametru tip_de_date] ) ]
[ {IS | AS} specificaie_apelare]
| FUNCTION nume_functie
[ (parametru tip_de_date [, parametru tip_de_date] ) ]
RETURN tip_de_date [ {IS | AS} specificaie_apelare] }
| [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} specificaie_apelare] }
| {MAP | ORDER} MEMBER FUNCTION nume_funcie
[ (parametru tip_de_date [, parametru tip_de_date] ) ]
RETURN tip_de_date [ {IS | AS} specificaie_apelare] }
[, {clauze_subprogram | specif_map_order}]
[, PRAGMA RESTRICT_REFERENCES
( {nume_metoda | DEFAULT}, lista_constrngeri) ]
Clauzele de motenire specificate la nivel de tip (FINAL, INSTANTIABLE) permit stabilirea
relaiei dintre supertipuri i subtipuri. La definirea metodelor exist opiuni de motenire similare,
intervenind n plus clauza OVERRIDING.

2
Tipurile generice vor fi prezentate ntr-o seciune special a acestui capitol.
Orientare pe obiecte n Oracle9i 19

OVERRIDING specific dac metoda suprascrie o metod definit n supertip. Acest


cuvnt cheie este necesar doar dac metoda redefinete o metod a supertipului. Valoarea
implicit este NOT OVERRIDING.
FINAL indic faptul c metoda nu poate fi suprascris n subtipuri. Spre deosebire de
clauza asemntoare pentru crearea tipurilor obiect, valoarea implicit este NOT FINAL.
INSTANTIABLE indic dac se d o implementare pentru metoda respectiv. Valoarea
implicit este INSTANTIABLE.
Dac o metod este declarat neinstaniabil (NOT INSTANTIABLE), atunci nu pot fi
specificate clauzele FINAL sau STATIC. n acest caz, trebuie s existe cel puin un subtip care
implementeze metoda respectiv.
Clauza MEMBER specific o funcie sau procedur asociat tipului obiect. Tipul poate fi
referit n cadrul subprogramului respectiv cu ajutorul cuvntului cheie SELF, acesta fiind parametrul
implicit al tuturor metodelor nestatice. De exemplu, orice apel de tipul ob.metoda() al unei metode
nestatice presupune existena unui parametru implicit, i anume, a obiectului ob referit ca SELF.
Spre deosebire de metodele MEMBER, cele de tip STATIC nu au parametrul implicit SELF.
Ele sunt invocate prin prefixarea cu numele tipului (nume_tip.metoda()) i implementeaz
funcionaliti care nu depind de instanele tipului. Pentru toate metodele declarate n definiia tipului
trebuie definite implementri n corpul tipului.
Directiva de compilare PRAGMA RESTRICT_REFERENCES nu permite metodelor accesul
pentru citire/scriere la tabele ale bazei de date i/sau variabile din pachete. Prin urmare, acest lucru
este util pentru evitarea efectelor laterale3. Dac se specific DEFAULT, lista de constrngeri este
aplicat tuturor metodelor din tipul respectiv. Restricia se aplic unei metode, iar constrngerile pot
fi:
RNDS - Read No Database State (nu poate consulta tabelele bazei de date folosind
comanda SELECT);
WNDS - Write No Database State (nu poate modifica tabelele bazei de date folosind
comenzi LMD);
RNPS - Read No Package State (nu poate referi valoarea variabilelor publice dintr-un
pachet);
WNPS - Write No Package State (nu poate modifica valoarea variabilelor publice dintr-un
pachet);
TRUST (restriciile din lista de constrngeri sunt presupuse adevrate).
Pentru a putea compara instanele unui tip, n cadrul comenzilor SQL, trebuie definit o
metod de ordonare de tip MAP sau ORDER, nefiind permis existena amndurora. Aceste metode
nu se pot defini pentru subtipuri.
Crearea unui tip vector se realizeaz cu urmtoarea comand:
CREATE [OR REPLACE] TYPE [schema.]nume_tip_vector
{AS | IS} {VARRAY | VARYING ARRAY} (limit)
OF tip_de_date;
Aceast comand permite crearea unui tip vector ce permite stocarea unui set de elemente

3
n Oracle nu este recomandat folosirea clauzei PRAGMA, n afara cazurilor n care este absolut necesar pentru
compatibilitate cu aplicaiile mai vechi. Ea va fi depreciat, pentru c ncepnd cu Oracle9i, acest tip de verificri se fac
automat la momentul execuiei.
20 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

avnd acelai tip de date. Trebuie specificate un nume i o limit pozitiv a numrului de elemente.
Limita trebuie s fie un literal ntreg. Sistemul Oracle nu suport vectori anonimi, adic fr nume.
Numele tipului de date al obiectelor coninute n vector poate fi un tip predefinit, referin sau un tip
definit de utilizator.
Crearea unui tip tablou imbricat se face cu ajutorul comenzii urmtoare:
CREATE [OR REPLACE] TYPE [schema.]nume_tip_tabimbricat
{AS | IS} TABLE OF tip_de_date;
Atunci cnd tipul elementelor este un tip obiect, tipul tablou imbricat descrie un tablou ale
crui coloane sunt n coresponden cu numele i atributele tipului obiect. Dac tipul elementelor este
scalar, atunci tipul tablou imbricat descrie un tablou cu o singur coloan de tip scalar, numit
COLUMN_VALUE.
Exemplu:
S se defineasc tipurile obiect t_artist, t_polita_asigurare, t_polite_ti, t_dim_v i
t_opera_de_arta. Tipul t_polite_ti este un un tip tablou imbricat. Dintre atributele tipului
t_opera_de_arta, se remarc artist care este de tip referin la un obiect de tip t_artist, polite de tip
tabel imbricat t_polite_ti i dimensiuni de tip t_dim_v, un vector de dimensiune trei. Fiecare linie din
tabloul imbricat t_polite_ti este un obiect de tip t_polita_asigurare.
CREATE TYPE t_artist AS OBJECT (
nume VARCHAR2(30),
prenume VARCHAR2(30),
anul_nasterii VARCHAR2(4),
anul_mortii VARCHAR2(4),
nationalitate VARCHAR2(40),
observatii VARCHAR2(2000));
/
CREATE TYPE t_polita_asigurare AS OBJECT (
cod_polita VARCHAR2(30),
descriere VARCHAR2(200),
firma VARCHAR2(50),
valoare NUMBER,
data_contract DATE);
/
CREATE TYPE t_polite_ti AS TABLE OF t_polita_asigurare;
/
CREATE TYPE t_dim_v AS VARRAY(3) OF NUMBER;
/
CREATE TYPE t_opera_de_arta AS OBJECT (
cod_opera NUMBER,
tip VARCHAR2(10),
titlu VARCHAR2(200),
artist REF t_artist,
data_crearii DATE,
data_achizitiei DATE,
valoare NUMBER,
polite t_polite_ti,
dimensiuni t_dim_v,
MEMBER FUNCTION get_titlu RETURN VARCHAR2);
Orientare pe obiecte n Oracle9i 21

/
Acest exemplu este prezentat ntr-o manier simplificat. El nu conine specificarea
implementrii metodei get_titlu, care trebuie creat prin comanda CREATE OR REPLACE TYPE
BODY. Definirea corpului unui tip va fi detaliat n seciunea dedicat metodelor.
De remarcat c definirea unui tip obiect nu implic alocarea unui spaiu de stocare (ulterior,
instanierea tipurilor implic alocare de spaiu). Odat definite tipurile obiect, ele pot fi utilizate n
comenzi SQL la fel ca tipurile de date native.
Noile tipuri obiect definite de utilizator pot fi utilizate pentru crearea de tabele relaionale sau
obiect. Comanda CREATE TABLE a fost completat cu noi opiuni n acest sens. Cu ajutorul acestei
comenzi se pot crea tabele obiect asociate tipurilor obiect existente. Sintaxa simplificat a unei
comenzi de creare a unui tabel obiect este urmtoarea:
CREATE TABLE [schema.]tabel OF [schema.]tip_obiect;
Exemplu:
S se creeze un tabel obiect tab_artisti destinat artitilor care expun lucrri n cadrul
muzeului. S se insereze nregistrri n acesta, abordnd tabelul att din punct de vedere obiectual, ct
i relaional. De asemenea, s se creeze un tabel relaional cumparari pentru a menine o istorie a
achiziiilor de opere de art.
CREATE TABLE tab_artisti OF t_artist;
INSERT INTO tab_artisti
VALUES (t_artist ('Francisco', 'Goya', 1746, 1828,
'spaniola', NULL));
INSERT INTO tab_artisti
VALUES ('Henri', 'Matisse', 1869, 1954, 'franceza', NULL);
CREATE TABLE cumparari (
opera t_opera_de_arta,
data_cumpararii DATE,
pret NUMBER,
vanzator VARCHAR2(100))
NESTED TABLE opera.polite STORE AS tstoc_polite;
Tabelul cumparari este un tabel relaional cu o coloan de tip obiect. Dac nu se specific
tabelul de stocare pentru tabloul imbricat din componena tipului t_opera_de_arta, opera.polite de tip
t_polite_ti, atunci apare eroarea ORA-22913: must specify table name for nested table column or
attribute.
O coloan a unui tabel, un obiect, un atribut al unui obiect, o colecie sau un element al unei
colecii are valoarea null dac a fost iniializat cu null sau dac nu a fost iniializat deloc.
Un obiect a crui valoare este null se numete obiect automat null. Un astfel de obiect este
diferit de unul ale crui atribute au valoarea null. Atunci cnd toate atributele unui obiect sunt null, ele
pot fi modificate i metodele sale pot fi apelate. n schimb, un obiect automat null nu permite aceste
operaii.
Exemplu:
Comenzile urmtoare ilustreaz comentariile referitoare la valorile null. Ele furnizeaz
rezultate diferite. Prima comand INSERT introduce o valoare diferit de null pentru coloana opera,
iar a doua introduce o valoare null.
INSERT INTO cumparari
22 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

VALUES (t_opera_de_arta (NULL, NULL, NULL, NULL,


NULL, NULL, NULL, NULL, NULL),
'24-May-2003', 2000, 'Manole Saizescu' );
INSERT INTO cumparari
VALUES (NULL, '24-May-2003', 2000, 'Manole Saizescu' );
n ambele cazuri, sistemul aloc spaiu n tabelul cumparari pentru o nou linie i seteaz
coloanele de tip scalar la valorile furnizate. n primul caz, sistemul aloc spaiu pentru un obiect n
coloana opera i seteaz fiecare dintre atributele obiectului la valoarea null.
n cel de-al doilea caz ns, chiar cmpul opera ia valoarea null i nu este alocat spaiu pentru
acesta. Cu alte cuvinte, doar n prima comand este instaniat obiectul.
Uneori se pot omite verificrile pentru valorile null (predicatul IS NULL). De exemplu, o linie
a unui tabel obiect (o linie obiect) nu poate fi null, iar un tablou imbricat de obiecte nu poate conine
un element a crui valoare este null. ns un tablou imbricat sau un vector, luate atomic, pot avea
valoarea null, aa c este necesar tratarea acestor condiii. O colecie null este diferit de una vid,
aceasta reprezentnd o colecie instaniat, care nu conine nici un element.
Exemple:
a) S se afieze preul i titlul operelor de art cumprate n ultimele 3 luni. Dac valoarea
coloanei opera este null s se afieze Incorect (se observ necesitatea alias-ului, fr de care nu se
poate face referirea titlului operei de art).
SELECT c.pret, NVL2(c.opera, c.opera.titlu ,'Incorect') Opera
FROM cumparari c
WHERE ADD_MONTHS (c.data_cumpararii, 3) > SYSDATE;
b) S se modifice valoarea operelor de art nregistrate n tabelul cumparari, astfel nct s
fie egal cu preul asociat. S se elimine nregistrrile referitoare la operele de art care au artistul
nespecificat.
UPDATE cumparari c
SET pret = c.opera.valoare;
DELETE FROM cumparari c
WHERE c.opera.artist IS NULL;
Tipurile definite de utilizator stocate persistent4 pot fi utilizate doar pentru o singur baz de
date. Nu se poate folosi o legtur ntre baze de date (database link) pentru a executa una dintre
urmtoarele aciuni:
conectarea la o baz de date distant pentru interogarea, crearea sau modificarea datelor
de un tip definit de utilizator sau a unui obiect referin dintr-un tabel distant;
declararea de variabile PL/SQL avnd un tip definit de utilizator care aparine unei baze
de date distante;
comunicarea unui argument avnd un tip definit de utilizator sau returnarea unei valori,
ntr-un apel de procedur PL/SQL la distan.

3.3. Tipul de date referin


Un obiect de tip referin (REF) este o adres logic a unei linii obiect. Tipul de date referin
4
Tipurile persistente sunt cele declarate cu o comand CREATE TYPE, spre deosebire de cele declarate n cadrul blocurilor
PL/SQL care sunt temporare.
Orientare pe obiecte n Oracle9i 23

este predefinit n Oracle. De obicei, tipul de date REF i coleciile de obiecte de acest tip modeleaz
relaiile dintre entiti (relaiile many-to-one sau one-to-many) 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.
De obicei, 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).
Similar cheilor externe, referinele obiect sunt utile n modelarea relaiilor complexe dintre
entiti. Ele sunt mai flexibile dect cheile externe deoarece:
sunt puternic tipizate, asigurnd o verificare mai riguroas i mai rapid a tipului, la
momentul compilrii;
permit modelarea optim (spaiu de stocare i timp de acces) a relaiilor one-to-many, prin
intermediul coleciilor de referine obiect;
asigur referirea i obinerea eficient a obiectelor fr a construi comenzi SQL complexe;
permit evitarea join-urilor multitabel;
permit aplicaiilor s obin toate obiectele care sunt n relaie, prin intermediul unei
singure cereri ctre server.
Pentru ca referinele obiect s poat implementa chei externe, trebuie ca obiectele referite s
fac parte din vizualizri sau tabele obiect cu identificatori bazai pe cheia primar. Atunci cnd se
definesc vizualizri obiect pe baza tabelelor relaionale, identificatorii obiectelor construite sunt de
obicei bazai pe cheile primare ale tabelelor relaionale de la care s-a pornit. De asemenea, la definirea
unui tabelul obiect, sistemul Oracle permite utilizarea valorilor cheii primare ca identificatori obiect
ai liniilor obiect, n locul identificatorilor implicii, generai de sistem.

Tipuri referin cu domeniu


n declaraia de tip referin a unei coloane, a unui element al unei colecii sau a unui atribut
al unui tip obiect se poate include constrngerea de a accesa doar referine ctre un anume tip obiect
specificat. Aceste tipuri referin se numesc tipuri referin cu domeniu. Ele necesit mai puin spaiu
de stocare i asigur un acces mai eficient dect cele fr domeniu.
n general, o coloan poate conine referine ctre obiecte de un anumit tip de date declarat,
fr ca acest lucru s depind de tabelul obiect n care sunt stocate obiectele referite. n particular, o
coloan de tip referin poate fi constrns s conin doar referine ctre obiecte aparinnd unui tabel
specificat. Aceste referine ar trebui folosite ori de cte ori este posibil, deoarece au o dimensiune mai
mic dect referinele fr domeniu, sistemul nefiind constrns s stocheze identificatorul tabelului.
De asemenea, cererile ce conin referine cu domeniu pot fi optimizate n join-uri.
Exemplu:
S se defineasc un tabel ce conine informaii despre specialitii care studiaz operele de art
din muzeu. Acest tabel va folosi pentru atributul adresa o referin cu domeniu. Se presupune c
obiectele de tip t_adresa sunt stocate ntr-un tabel obiect separat, tab_adrese. Ultimele dou comenzi
arat modalitatea n care primesc valori coloanele de tip referin din tabelul tab_specialisti.
24 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

CREATE TYPE t_adresa AS OBJECT (


cod_adresa NUMBER,
strada VARCHAR2(50),
cod_postal VARCHAR2(10),
oras VARCHAR2(40),
judet VARCHAR2(30),
tara VARCHAR2(40));
/
CREATE TABLE tab_adrese OF t_adresa;
INSERT INTO tab_adrese VALUES
(1,'N Balcescu 55','7200','Bucuresti','Sector 3','Romania');
INSERT INTO tab_adrese VALUES
(2,'V Manu 16','1700','Braila',NULL,'Romania');
CREATE TYPE t_specialist AS OBJECT (
cod NUMBER,
nume VARCHAR2(30),
prenume VARCHAR2(40),
autorizatie VARCHAR2(5),
adresa REF t_adresa);
/
CREATE TABLE tab_specialisti OF t_specialist
(SCOPE FOR (adresa) IS tab_adrese);
INSERT INTO tab_specialisti
SELECT 3, 'Liiceanu', 'Aurora', 'LA345', REF(a)
FROM tab_adrese a
WHERE a.cod_adresa = 1;
INSERT INTO tab_specialisti
SELECT 4, 'Liiceanu', 'Gabriel', 'LG123', REF(a)
FROM tab_adrese A
WHERE a.cod_adresa = 1;
O referin definit prin constrngerea SCOPE are ca raz de aciune un anumit tabel obiect
de tipul specificat sau de orice subtip al acestuia. n exemplul analizat, coloana adresa are ca valori
doar obiecte din tabelul obiect tab_adrese de tip t_adresa. Constrngerea se specific n comanda de
creare sau modificare a unui tabel i are urmtoarea sintax:
SCOPE FOR (coloana | atribut) IS tabel_obiect
Dac raza de aciune a referinei este un tabel obiect de un subtip al tipului declarat, atunci
coloana referin este efectiv constrns s conin numai referine la instanele subtipului (i ale
subtipurilor acestuia, dac au fost definite) din tabel.
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.
Exemplu:
S se afieze specialitii care au adresa incorect nregistrat n tabelul obiect tab_specialisti.
SELECT prenume||' '||nume "Fara adresa"
FROM tab_specialisti
WHERE adresa IS DANGLING;
Orientare pe obiecte n Oracle9i 25

DELETE FROM tab_adrese


WHERE cod_adresa = 1;
Prima comand selecteaz liniile care, din diferite motive, au pierdut referina ctre adres.
Iniial, aceasta nu va returna nici o linie rezultat, legturile fiind corecte. Dac se execut comanda
DELETE care urmeaz i apoi se reexecut cererea, se observ c 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 urmtoarei funcii:
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.
Exemplu:
S se ilustreze diferena dintre cele dou abordri ale unei referine, fr i cu derefereniere
(fizic, respectiv logic).
SELECT DISTINCT adresa FROM tab_specialisti;
SELECT DEREF(adresa) FROM tab_specialisti;
n cea de-a doua cerere, 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. De
asemenea, sistemul Oracle asigur dereferenierea implicit a referinelor atunci cnd este necesar.
Exemplu:
Se consider tipul t_angajat ce conine dou atribute, numele i referina ctre directorul
angajatului respectiv. Directorul trebuie s fie, ca i subalternul, un obiect de tip t_angajat.
CREATE TYPE t_angajat AS OBJECT (
nume VARCHAR2(40),
director REF t_angajat);
Dac X este un obiect de tip t_angajat, atunci expresia X.director.nume urmrete automat
legtura de la o persoan X la alt persoan, directorul lui X, i returneaz numele acestuia. De
remarcat c aceast referire este permis n SQL, dar nu i n PL/SQL.
CREATE TABLE tab_angajati OF t_angajat;
-- directorul general este Georgescu
INSERT INTO tab_angajati(nume)
VALUES ('Georgescu');
--doi subalterni de-ai lui, Ionescu si Alecu
INSERT INTO tab_angajati
SELECT 'Ionescu', REF(a)
FROM tab_angajati a
WHERE LOWER(a.nume) = 'georgescu';
INSERT INTO tab_angajati
SELECT 'Alecu', REF(a)
26 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

FROM tab_angajati a
WHERE UPPER(a.nume) = 'GEORGESCU';
S se selecteze numele directorului salariatului Alecu.
SELECT a.director.nume "Directorul lui Alecu este"
FROM tab_angajati a
WHERE INITCAP(a.nume) = 'Alecu';
Aflarea valorii referin ce adreseaz o linie obiect se face prin selectarea instanei din tabelul
obiect care conine obiectul de refereniat i aplicarea operatorului REF.
Exemplu:
S se obin o referin ctre specialistul cu numele Gabriel Liiceanu. De remarcat c cererea
trebuie s returneze exact o linie.
SET SERVEROUTPUT ON
DECLARE
v_SpecRef REF t_specialist;
BEGIN
SELECT REF(s) INTO v_SpecRef
FROM tab_specialisti s
WHERE LOWER(s.nume) = 'liiceanu'
AND LOWER(s.prenume) = 'gabriel';
DBMS_OUTPUT.PUT_LINE('Exista o singura intrare' ||
' cu acest nume.');
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE ('Nu exista in baza de date');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE ('Exista mai multi cu acest nume');
END;
/
Funcia MAKE_REF creeaz o referin ctre o linie a unui tabel sau vizualizare obiect al
crei identificator obiect este bazat pe cheia primar. Pentru fiecare linie rezultat a unei cereri,
pseudocoloana ROWNUM returneaz un numr ce indic ordinea n care sistemul Oracle selecteaz
liniile dintr-un tabel sau dintr-o mulime de linii ale unui join. Numerotarea ncepe de la 1.
Exemplu:
S se adauge un nou atribut (cod) tipului t_angajat i s se completeze valoarea acestuia
utiliznd instanele deja existente n tabelul tab_angajati. S se adauge tabelului o constrngere de
cheie primar care s includ coloanele cod i nume. S se creeze o vizualizare obiect asupra
tabelului, cu identificatori obiect bazai pe concatenarea dintre cod i nume. S se arate modalitatea de
creare a unei referine ctre o anumit linie obiect din cadrul vizualizrii, linie unic determinat de
dou valori ale atributelor cod i nume.
--se adauga atributul cod tipului creat anterior t_angajat
ALTER TYPE t_angajat
ADD ATTRIBUTE (cod NUMBER)
CASCADE;
--se propaga schimbarea catre toate obiectele dependente
--(tab_angajati) si se populeaza atributul cod
UPDATE tab_angajati
SET cod = ROWNUM;
COMMIT;
ALTER TABLE tab_angajati
Orientare pe obiecte n Oracle9i 27

ADD (PRIMARY KEY (cod, nume));


--se creeaza o vizualizare obiect cu identificatorul obiect
--bazat pe cheia primara
CREATE VIEW viz_angajati OF t_angajat
WITH OBJECT IDENTIFIER (cod, nume)
AS SELECT * FROM tab_angajati;
SELECT MAKE_REF(viz_angajati, 1, 'Georgescu')
FROM DUAL;

Pachetul UTL_REF
Pachetul predefinit UTL_REF conine proceduri pentru operaiile cu referine. Spre deosebire
de comenzile LMD, 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 n subprogramele i
pachetele PL/SQL stocate pe server, ct i n aplicaiile PL/SQL de pe client (de exemplu, Oracle
Forms).
Pachetul conine urmtoarele proceduri:
SELECT_OBJECT, care primete ca parametru de intrare o referin i returneaz
obiectul referit;
LOCK_OBJECT, care permite blocarea unui obiect, specificnd referina corespunztoare
acestuia (procedura este suprancrcat astfel nct, opional, obiectul s poat fi reinut
ntr-o variabil);
UPDATE_OBJECT, care permite modificarea unui obiect, dat fiind o referin la acesta;
DELETE_OBJECT, care primete ca parametru de intrare o referin i are ca rezultat
suprimarea obiectului referit de aceasta.
Exemplu:
S se modifice toate adresele din Romnia asociate unor specialiti, astfel nct codul potal
s fie 7000. De asemenea, s se tearg toate adresele izolate.
DECLARE
v_adresa t_adresa;
CURSOR c_adrese IS
SELECT REF(a) ref_adr
FROM tab_adrese a
WHERE REF(a) IN (SELECT DISTINCT s.adresa
FROM tab_specialisti s)
AND INITCAP (tara) = 'Romania';
CURSOR c_adrese_izolate IS
SELECT REF(a) ref_adr
FROM tab_adrese a
WHERE NOT EXISTS (SELECT DISTINCT s.adresa
FROM tab_specialisti s
WHERE s.adresa = REF(a));
BEGIN
FOR v_rec IN c_adrese LOOP
-- se obtine obiectul referit prin v_rec.ref_adr
UTL_REF.SELECT_OBJECT (v_rec.ref_adr, v_adresa);
DBMS_OUTPUT.PUT_LINE (' Cod: '|| v_adresa.cod_adresa);
-- se blocheaza obiectul referit
-- in vederea modificarii
UTL_REF.LOCK_OBJECT (v_rec.ref_adr);
28 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

v_adresa.cod_postal := 7000;
-- se modifica obiectul referit prin v_rec.ref_adr
UTL_REF.UPDATE_OBJECT (v_rec.ref_adr, v_adresa);
END LOOP;
FOR v_rec2 IN c_adrese_izolate LOOP
-- este sters obiectul identificat de referinta
UTL_REF.DELETE_OBJECT (v_rec2.ref_adr);
END LOOP;
END;
/

3.4. Definirea tabelelor obiect


Odat cu adugarea caracteristicilor obiectuale, comanda CREATE TABLE, care permite
crearea de tabele ntr-o schem a bazei de date, a fost extins cu noi opiuni pentru a putea fi folosit
mpreun cu tipurile obiect. Au fost adugate clauze corespunztoare pentru crearea tabelelor obiect i
a tabelelor relaionale ce conin coloane de tipuri obiect, referin sau colecie.
Pentru a crea un tabel, utilizatorul trebuie s dein privilegiului obiect CREATE TABLE sau
cel sistem CREATE ANY TABLE. n cazul tabelelor obiect, proprietarul tabelului respectiv (obiect 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. Aceste
privilegii trebuie acordate n mod explicit i nu prin intermediul unui role.
Sintaxa comenzii CREATE TABLE pentru crearea tabelelor obiect este5:
CREATE TABLE [schema.]nume_tabel OF [schema.]tip_obiect
[ [NOT] SUBSTITUTABLE AT ALL LEVELS]
[ ( { {coloan | atribut} [DEFAULT expr]
[constr_linie [constr_linie] | constr_linie_ref]
| {constr_tabel | constr_tabel_ref} } ) ]
[clauz_OID] [proprieti_colecie];
Aceast comand creeaz un tabel obiect n schema curent sau n cea precizat (schema).
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 unic 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 utilizator, clauza DEFAULT trebuie s conin o invocare literal a
constructorului obiectului sau coleciei respective. Tipul de date al expresiei trebuie s corespund cu
tipul coloanei. 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 i
ROWNUM, constante de tip dat calendaristic nespecificate n totalitate.
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
5
n comentariile care urmeaz sunt fcute referiri la tabele obiect sau relaionale care conin coloane de tip obiect. Pentru
prezentarea detaliat a comenzii CREATE TABLE, vezi capitolul 2.
Orientare pe obiecte n Oracle9i 29

permise variabile sau funcii.


Exemplu:
S se defineasc un tip tablou imbricat (t_artisti_ti) de obiecte de tip t_artist. Tipul t_artist a
fost definit anterior i conine cmpurile nume, prenume, anul_nasterii, anul_mortii, nationalitate i
observatii. n acest exemplu se consider c tipul conine i un atribut adresa de tip t_adresa.
ALTER TYPE t_artist
ADD ATTRIBUTE adresa t_adresa
CASCADE;
CREATE TYPE t_artisti_ti AS TABLE OF t_artist;
/
O invocare literal a constructorului pentru tipul tabel imbricat t_artisti_ti este urmtoarea:
t_artisti_ti (
t_artist ('Brancusi', 'Constantin', 1876, 1957, NULL,
t_adresa (NULL, NULL, NULL, 'Tg Jiu', 'Romania'),
t_artist ('Dali', 'Salvador', 1904, 1989, NULL, NULL),
t_artist ('Picasso', 'Pablo', 1881, 1973, NULL,
t_adresa (2, 'Rue des Ecoles 13', '12345',
'Paris', 'Paris', 'France'));
Exemplu:
S se foloseasc invocrile literale de metode constructor pentru a specifica valori implicite
ale coloanelor unui tabel relaional care conine informaii despre operele de art.
CREATE TABLE opere_de_arta (
cod_opera NUMBER,
tip VARCHAR2(10),
titlu VARCHAR2(200),
artist t_artist
DEFAULT t_artist ('A', 'A', NULL, NULL, NULL, NULL, NULL),
data_crearii DATE,
data_achizitiei DATE DEFAULT SYSDATE,
polite t_polite_ti DEFAULT t_polite_ti(),
dimensiuni t_dim_v DEFAULT t_dim_v (-1,-1,-1))
NESTED TABLE polite STORE AS polite_store;
De remarcat c 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 clauz_OID are urmtoarea form:
OBJECT IDENTIFIER IS {SYSTEM GENERATED | PRIMARY KEY}
Clauza permite s se specifice dac identificatorul obiect6 al tabelului obiect este generat de
sistem sau este bazat pe cheia primar a tabelului. Opiunea implicit este SYSTEM GENERATED.
Restriciile legate de clauza referitoare la identificatorului obiect sunt:
se poate specifica OBJECT IDENTIFIER IS PRIMARY KEY doar dac s-a definit o
constrngere de cheie primar;
6
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.
30 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

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 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.
Pe lng aceast opiune, caracteristicile de substituibilitate pot fi specificate i la nivel de
coloan sau atribut corespunztor unei coloane de tip obiect, unui atribut sau unui element dintr-o
coloan sau atribut de tip colecie. Sintaxa de specificare la nivel de coloan este urmtoarea:
{COLUMN [ELEMENT] IS OF [TYPE] ( [ONLY] tip_de_date)
| [NOT] SUBSTITUTABLE AT ALL LEVELS}
Noiunile vor fi explicate pe larg n seciunea referitoare la motenirea tipurilor. Clauza de
substituibilitate indic dac atributele sau coloanele obiect din aceeai ierarhie se pot substitui
reciproc. Astfel, se poate specifica dac o coloan poate conine doar instane ale tipului declarat sau
i ale subtipurilor acestuia.
Opiunea ELEMENT se utilizeaz atunci cnd se face referire la tipul elementului unei
coloane sau al unui atribut de tip colecie. Clauza IS OF [TYPE] (ONLY tip_de_date) constrnge tipul
coloanei obiect la un subtip al tipului declarat. Prezena opiunii de subsitutibilitate arat c acea
coloan obiect poate conine instane corespunztoare unuia dintre subtipurile tipului declarat. n
cazul variantei negate, substituibilitatea este dezactivat pentru orice componente sau atribute
obiectuale incluse n vectorii sau tablourile imbricate respective.
Asupra clauzei COLUMN sunt impuse trei restricii:
nu poate fi specificat pentru un atribut al unei coloane obiect.
nu se poate specifica pentru o coloan obiect a unui tabel relaional sau obiect dac
substituibilitatea tabelului obiect a fost precizat explicit;
pentru o coloan de tip colecie, singura parte a clauzei care se poate utiliza este cea de
substituibilitate.
Numrul maxim de coloane dintr-un tabel este de 1000. Dar, la crearea unui tabel obiect (sau
a unui tabel relaional cu coloane de tip obiect, referin sau colecie) sistemul Oracle asociaz
coloane relaionale coloanelor de tipuri definite de utilizator. Apare n acest fel un efect de coloane
ascunse, numrul total de coloane trebuind s se ncadreze n limita de 1000 precizat.
Exemplu:
S se creeze tipul obiect t_autor (cu atributele cod, nume, prenume, sex) i s se defineasc un
tabel obiect pentru stocarea obiectelor de acest tip.
CREATE OR REPLACE TYPE t_autor AS OBJECT (
cod NUMBER,
nume VARCHAR2(30),
prenume VARCHAR2(40),
sex VARCHAR2(1));
/
CREATE TABLE tab_autori OF t_autor;
Orientare pe obiecte n Oracle9i 31

Acest tabel poate fi privit n dou moduri:


ca un tabel cu o singur coloan n care fiecare linie este un obiect de tipul t_autor,
permind executarea operaiilor obiectuale;
ca un tabel multicoloan n care fiecare atribut al tipului t_autor are cte o coloan
asociat, fiind posibil execuia operaiilor relaionale.
Exemplu:
S se introduc, n manier relaional, dou nregistrri n tabelul tab_autori i s se listeze o
nregistrare, n manier obiectual.
INSERT INTO tab_autori
VALUES (0, 'Plesu', 'Andrei', 'M' );
INSERT INTO tab_autori
VALUES (1, 'Rolland', 'Romain', 'M');
SELECT VALUE(a)
FROM tab_autori a
WHERE UPPER(a.nume) like '%L%';
Primele instruciuni insereaz obiecte de tip t_autor n tabelul tab_autori privit ca tabel
relaional multicoloan. Ultima selecteaz nregistrri din tabelul tab_autori ca dintr-un tabel cu o
singur coloan, utiliznd funcia VALUE pentru a returna liniile rezultat ca instane obiect.
Exemplu:
S se rafineze tipul creat anterior, adugnd un atribut care s conin adresa autorului. Liniile
tabelului tab_autori sunt linii obiect, iar valorile atributului adresa sunt coloane obiect.
ALTER TYPE t_autor
ADD ATTRIBUTE adresa t_adresa
CASCADE;
INSERT INTO tab_autori VALUES
(2, 'Cartarescu', 'Mircea', 'M', t_adresa (3, 'Magheru 15',
'7200', 'Bucuresti', 'Sector 2', 'Romania'));
INSERT INTO tab_autori VALUES
(3, 'Buzoianu', 'Catalina','F', t_adresa(4, 'Ipatescu 72',
'7200', 'Bucuresti','Sector 4', 'Romania'));
Clauza constr_linie, din cadrul comenzii CREATE TABLE, definete o constrngere la nivel
de coloan sau atribut i are forma urmtoare:
[CONSTRAINT nume_constr]
{ [NOT] NULL | UNIQUE | PRIMARY KEY |
clauz_referin_extern | CHECK (condiie) } [stare_constr]
Clauza constr_tabel definete una dintre constrngerile disponibile la nivel de tabel. De
obicei, acestea se folosesc pentru a declara, n cadrul definiiei tabelului, o constrngere de integritate
sau o constrngere care adreseaz mai multe coloane ale tabelului.
[CONSTRAINT nume_constr]
{UNIQUE (coloan [, coloan ] )
| PRIMARY KEY (coloan [, coloan] )
| FOREIGN KEY (coloan [, coloan] clauz_referire
| CHECK (condiie) } [stare_constr]
32 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Sistemul Oracle nu permite constrngeri asupra coloanelor sau atributelor de tip obiect,
colecie, referin sau LOB, cu dou excepii:
constrngerile NOT NULL sunt permise pentru toate tipurile definite de utilizator, vector
sau LOB (cu excepia tablourilor imbricate);
constrngerile NOT NULL, de cheie extern i de tip REF sunt permise pentru o coloan
de tip referin.
n general, la crearea unui subtabel sau a unei subvizualizri n cadrul unei ierarhii de
motenire nu se poate specifica o constrngere de tip UNIQUE sau PRIMARY KEY. Cheia unic poate
fi specificat doar n cadrul definiiei tabelului sau vizualizrii de pe nivelul rdcin.
Chiar dac coloanele i atributele de tip obiect, colecie, referin sau LOB nu pot avea
constrngeri de cheie unic, primar sau extern, cu unele restricii, aceste constrngeri sunt
disponibile pentru coloanele i atributele acestor tipuri.
Constrngerile din sintax pot fi specificate asupra atributelor scalare ale coloanelor de tip
obiect. Se pot impune constrngeri NOT NULL asupra coloanelor de tip obiect i constrngeri de tip
CHECK care s fac referin la coloane de tip obiect sau la atribute ale unor coloane de tip obiect.
Constrngerile NOT NULL sunt singurele constrngeri care se pot specifica la nivel de linie
pentru o coloan de tip XMLType sau vector. O astfel de constrngere nu se poate specifica pentru un
atribut al unui obiect. Pentru a implementa o astfel de restricie se poate folosi o constrngere de tip
CHECK asociat cu predicatul IS NOT NULL.
Exemplu:
S se creeze un tabel obiect ce conine artiti, specificnd c atributele nume i prenume sunt
obligatorii. S se defineas un tabel relaional care s conin dou coloane, artist de tip t_artist i
numar_opere de tip numeric. Tabelul va impune aceeai condiie asupra atributelor nume i prenume
ale tipului. Se observ c operaia de inserare ce urmeaz dup crearea tabelelor eueaz cu eroarea
ORA-02290: check constraint (STUDENT.SYS_C008911) violated.
CREATE TABLE tab_artisti OF t_artist
(CHECK (nume IS NOT NULL OR prenume IS NOT NULL));
CREATE TABLE statistica_artisti (
artist t_artist,
numar_opere NUMBER,
CHECK (artist.nume IS NOT NULL OR
artist.prenume IS NOT NULL));
INSERT INTO statistica_artisti
VALUES (t_artist (NULL, NULL, '1800', '1900',
NULL, NULL, NULL), 10);
Aa cum s-a exemplificat, la nivelul unui tabel obiect se pot defini aceleai categorii de
constrngeri ca i pentru tabelele relaionale obinuite. Aceste constrngeri se refer la atributele
scalare ale unei coloane obiect, cu excepia celor referin fr domeniu. Pot fi specificate
constrngeri de cheie primar (PRIMARY KEY), cheie extern (REFERENCING, FOREIGN KEY), de
unicitate (UNIQUE), NOT NULL, de verificare a unei condiii (CHECK).
Exemplu:
a) S se defineasc tabelul obiect tab_opere i s se plaseze o constrngere de cheie primar
asupra coloanei cod_opera. Se va presupune c tabelul tab_opere este bazat pe tipul t_opera_de_arta
definit anterior. De asemenea, cmpul titlu este obligatoriu, iar data crerii operei este anterioar datei
de achiziie.
Orientare pe obiecte n Oracle9i 33

CREATE TABLE tab_opere OF t_opera_de_arta (


cod_opera PRIMARY KEY,
titlu NOT NULL,
CHECK (data_crearii < data_achizitiei))
NESTED TABLE polite STORE AS ts_polite;
INSERT INTO tab_opere
VALUES (1, 'sculptura', 'David', NULL,
TO_DATE ('12-jul-1540','dd-mon-yyyy'),
SYSDATE, 120, t_polite_ti(), t_dim_v (100, 25, 50));
b) S se creeze tabelul relaional opere_de_arta folosind constrngeri ce includ referine la
atributele scalare ale unei coloane obiect (artist). Exemplul asigur c anul naterii artistului care a
creat opera de art (anul_nasterii) este anterior anului n care aceasta a fost creat i numele lui
(nume) este precizat.
DROP TABLE opere_de_arta;
CREATE TABLE opere_de_arta (
cod_opera NUMBER,
tip VARCHAR2(10),
titlu VARCHAR2(200) NOT NULL,
artist t_artist
DEFAULT t_artist('A', 'A', NULL, NULL, NULL, NULL, NULL),
data_crearii DATE,
data_achizitiei DATE DEFAULT SYSDATE,
valoare NUMBER,
polite t_polite_ti DEFAULT t_polite_ti(),
dimensiuni t_dim_v DEFAULT t_dim_v (-1, -1, -1),
CONSTRAINT opera_pk PRIMARY KEY (cod_opera),
CONSTRAINT verif_date
CHECK (data_crearii < data_achizitiei),
CONSTRAINT c_artist1 CHECK
(artist.anul_nasterii < TO_CHAR (data_crearii, 'RRRR')),
CONSTRAINT c_artist2 CHECK(artist.nume IS NOT NULL))
NESTED TABLE polite STORE AS polite_store;
O coloan sau un atribut de tip referin pot fi restricionate folosind clauza SCOPE sau o
clauz de constrngere referenial. Atunci cnd o coloan de tip referin nu prezint restricii, ea
poate stoca referine ctre linii obiect de tipul specificat, coninute n orice tabel obiect. n cadrul
coloanelor referin fr domeniu nu este permis stocarea referinelor obiect care conin un
identificator obiect bazat pe o cheie primar.
Sistemul nu verific dac referinele obiect stocate n coloane adreseaz obiecte linie valide i
existente. De aceea, coloanele referin pot conine referine ctre obiecte inexistente. Asemenea
valori referin se numesc referine izolate.
O coloan referin poate fi constrns s aib ca domeniu un tabel obiect specificat. Valorile
referin stocate n coloane cu domeniu adreseaz linii obiect ale tabelului specificat n clauza
SCOPE. n acest caz, riscul de a stoca referine izolate este mai mic.
O coloan referin poate avea o constrngere de integritate referenial similar clauzei
REFERENCES folosit n specificarea cheilor externe pentru tabelele relaionale. Referina obiect
stocat n aceste coloane trebuie s adreseze un obiect linie valid i existent n tabelul obiect
34 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

specificat.
Constrngerile de tip CHECK sau PRIMARY KEY nu pot fi impuse unor coloane referin. n
schimb, sunt permise constrngeri de tip NOT NULL.
O coloan de tip REF refer un obiect dintr-un tabel sau o coloan obiect. O constrngere de
tip REF permite definirea relaiilor dintre coloanele de tip referin i obiectele referite. Pentru aceasta
sunt utilizate clauzele constr_linie_ref sau constr_tabel_ref. Diferena dintre aceste dou clauze este
nivelul de specificaie. n cazul constrngerii la nivel de tabel, trebuie specificate coloana sau atributul
la care se face referire.
Sintaxa constrngerii de tip referin la nivel de linie este urmtoarea:
{SCOPE IS [schema.]tabel_domeniu
| WITH ROWID
| [CONSTRAINT nume_constr] clauza_referire [stare_constr] }
Constrngerea de tip referin la nivel de tabel are sintaxa urmtoare:
{SCOPE FOR ( {col_ref | atr_ref} ) IS [schema.]tabel_domeniu
| REF ( {col_ref | atr_ref} ) WITH ROWID
| [CONSTRAINT nume_constr] FOREIGN KEY ( {col_ref | atr_ref} )
clauza_referire [stare_constr] }
Ambele variante permit definirea unei constrngeri referitoare la:
domeniul atributului sau coloanei referin respective;
stocarea valorilor referin mpreun cu identificatorul de linie;
integritatea referenial a unei coloane de tip REF.
n cadrul unei specificaii la nivel de tabel, col_ref reprezint un nume de coloan de tip
referin din tabelul obiect sau relaional creat, iar atr_ref specific un atribut de tip referin integrat
n cadrul unei coloane obiect a tabelului relaional. Coloana referin este considerat de tip utilizator
dac domeniul acesteia este un tabel obiect care are identificatorii obiect bazai pe cheie primar.
ntr-un tabel cu o coloan de tip referin, fiecare valoare stocat poate referi o linie dintr-un
tabel obiect oarecare (inclusiv tabelul obiect curent). Clauza SCOPE restricioneaz domeniul
referinelor la un singur tabel obiect specificat (tabel_domeniu). Valorile din coloana sau atributul de
tip REF sunt corelate cu obiecte din tabelul domeniu, tabel n care sunt stocate instane obiect de
acelai tip cu cel al coloanei respective. Tabelul specificat ca domeniu trebuie s fac parte din propria
schem sau trebuie deinut fie privilegiul obiect SELECT asupra tabelului, fie privilegiul sistem
SELECT ANY TABLE. Pentru o coloan de tip REF nu poate fi specificat dect un singur tabel
domeniu.
Restriciile asupra constrngerilor de tip SCOPE sunt:
nu se poate aduga o constrngere de domeniu unei coloane existente dect dac tabelul
creat este vid;
nu se poate specifica o constrngere de domeniu pentru elementele unei coloane de tip
vector;
este obligatorie specificarea unei clauze de domeniu atunci cnd comanda de creare a
tabelului conine o subcerere ce returneaz referine definite de utilizator;
nu este permis suprimarea ulterioar a unei constrngeri de domeniu.
Clauza WITH ROWID se folosete pentru a stoca n cadrul coloanei sau atributului respectiv,
pe lng valoarea referin propriu-zis, identificatorul de linie al obiectului referit. Acest lucru poate
Orientare pe obiecte n Oracle9i 35

mbunti performanele operaiei de derefereniere, dar utilizeaz mai mult spaiu de stocare.
Opiunea implicit este stocarea fr identificatori de linie.
Restriciile asupra constrngerii WITH ROWID sunt:
nu se poate defini pentru elementele de tip referin ale unui vector;
nu poate fi eliminat ulterior printr-o comand ALTER TABLE;
este ignorat dac exist deja o constrngere de domeniu asupra coloanei sau atributului
respectiv.
Clauza REFERENCES coninut n opiunea clauza_referire permite definirea cheilor externe
asupra coloanelor de tip REF. Pe lng meninerea integritii refereniale, aceast clauz
restricioneaz n mod implicit domeniul coloanei sau atributului referin la tabelul obiect specificat.
O constrngere de cheie extern asupra unei coloane relaionale refer o alt coloan relaional din
tabelul printe. Diferena dintre abordarea relaional i cea obiectual este c o constrngere de
cheie extern asupra unei coloane de tip REF face referire la coloana tabelului printe ce conine
identificatorul obiect corespunztor.
Similar tabelelor relaionale, constrngerea la nivel de coloan utilizeaz clauza
REFERENCES, iar cea la nivel de tabel necesit n plus cuvintele cheie FOREIGN KEY i una sau
mai multe coloane sau atribute asupra crora se fixeaz constrngerea respectiv.
Restriciile relative la constrngerile de integritate referenial asupra coloanelor de tip REF
sunt:
la definirea unei constrngeri de integritate referenial asupra unei coloane de tip REF se
adaug automat o constrngere de tip SCOPE fr domeniu (toate restriciile care se
aplic constrngerilor de domeniu se aplic i n acest caz);
nu se poate specifica o coloan dup numele obiectului din clauza REFERENCES.
Exemplu:
S se creeze un tabel care s fac legtura ntre tabelele tab_artisti i tab_adrese definite
anterior. Noul tabel, tab_adrese_artisti, va conine trei coloane:
tip, care specific dac adresa este permanent sau temporar;
artist, care refer un obiect de tip t_artist din tabelul tab_artisti i asupra creia este
impus o constrngere de cheie extern;
adresa, care refer un obiect de tip t_adresa din tabelul tab_adrese.
Asupra coloanei artist se impune o constrngere de integritate referenial, iar asupra coloanei
adresa o constrngere de domeniu. Pentru corectitudine, iniial se elimin coloana adresa din cadrul
tipului t_artist.
ALTER TYPE t_artist
DROP ATTRIBUTE adresa
CASCADE;
CREATE TABLE tab_adrese_artisti (
tip VARCHAR2(10) CHECK (tip IN ('TEMP', 'PERM')),
artist REF t_artist REFERENCES tab_artisti,
adresa REF t_adresa SCOPE IS tab_adrese);
Clauza stare_constr se refer la starea constrngerii la momentul crerii tabelului (activ,
inactiv, amnat, imediat etc.), stare ce poate fi modificat ulterior cu o comand ALTER TABLE.
Proprietile coloanelor de tip vector (proprieti_colecie) se pot specifica prin intermediul
urmtoarelor opiuni:
36 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

VARRAY elem_vector
{clauza_col_substituibil
| STORE AS LOB {numesegment_LOB (parametri_LOB)
| numesegment_LOB
| (parametri_LOB) } }
Aceste clauze permit specificarea unor caracteristici de stocare separate pentru obiectul de tip
LOB n care va fi stocat vectorul. Dac elem_vector este o colecie pe mai multe niveluri, atunci toate
componentele coleciei imbricate din elementul specificat sunt stocate n cadrul aceluiai obiect LOB.
Clauza VARRAY permite specificarea caracteristicilor de stocare asociate segmentelor de date
LOB ale vectorului, la mai multe niveluri:
global, la nivel de tabel, pentru tabele nepartiionate;
asociate tuturor partiiilor i subpartiiilor, pentru un tabel partiionat n care specificarea
caracteristicilor se face la nivel de tabel;
corespunztoare unei partiii i subpartiiilor acesteia, n cazul unor partiii individuale ale
unui tabel partiionat (setrile la nivel de partiie suprascriu setrile la nivel de tabel);
corespunztoare unei subpartiii, pentru subpartiii individuale ale tabelului partiionat
(setrile la nivel de subpartiie suprascriu att setrile la nivel de partiie ct i pe cele la
nivel de tabel).
Opiunea STORE AS LOB respect urmtoarele reguli:
dac dimensiunea maxim a vectorului este mai mic de 4 KB i nu a fost dezactivat
stocarea la nivel de linie, atunci sistemul stocheaz vectorii n cadrul nregistrrii (inline);
dac dimensiunea maxim a vectorului este mai mare de 4 KB sau a fost dezactivat
stocarea la nivel de linie, atunci sistemul stocheaz vectorii n afara nregistrrii (out-of-
line).
Dac nu se specific opiunea STORE AS LOB, atunci stocarea vectorilor se face n mod
diferit fa de alte obiecte LOB. Stocarea se bazeaz pe dimensiunea maxim posibil a vectorilor
(adic numrul de elemente nmulit cu dimensiunea acestora, plus o cantitate pentru informaia de
control), nu pe dimensiunea real a coloanei de tip vector. Pot aprea urmtoarele cazuri:
dimensiunea maxim a vectorului este mai mic dect 4 KB i atunci vectorul este stocat
inline sub forma unor date nestructurate;
dimensiunea maxim este mai mare de 4 KB i atunci vectorul este stocat ca LOB (dac
dimeniunea real este mai mic de 4 KB, atunci este stocat ca LOB n cadrul liniei, n caz
contrar, vectorul fiind stocat ca LOB n afara nregistrrii, ca i celelalte coloane de tip
LOB).
Pentru obiectul LOB setat nu se poate specifica parametrul TABLESPACE n cadrul clauzei
parametri_LOB. Spaiul tabel al obiectului LOB asociat unui vector este n mod implicit spaiul tabel
din care face parte tabelul ce l conine.
Proprietile coloanelor de tip tablou imbricat se pot seta cu ajutorul urmtoarelor opiuni:
NESTED TABLE {elem_imbr | COLUMN_VALUE}
[clauza_col_substituibil] STORE AS tabel_stocare
[ ( (propr_obiect) [propr_fizice] [propr_coloana] ) ]
[RETURN AS {LOCATOR | VALUE} ]
Orientare pe obiecte n Oracle9i 37

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 ce conin coloane
(propriu-zise sau ascunse) de tip tablou imbricat. Clauzele clauza_col_substituibil, propr_obiect,
propr_fizice i propr_cooanal din cadrul opiunilor pentru tablouri imbricate funcioneaz n acelai
fel ca i pentru tabelul printe. Atributul element_imbr specific numele coloanei de tip tablou
imbricat sau al unui atribut tablou imbricat al tipului obiect 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. Pentru un tabel nepartiionat, tabelul de stocare este creat n aceeai schem i
n acelai spaiu tabel ca i tabelul printe (utiliznd caracteristicile de stocare implicite). Dac
tabelul printe este partiionat, atunci tabelul de stocare este creat n spaiul tabel implicit al
schemei.
Asupra tabelului de stocare exist urmtoarele restricii:
nu se poate partiiona un tabel de stocare al unui tablou imbricat;
nu se pot executa comenzi de interogare sau prelucrare a datelor dintr-un tabel de stocare
n mod direct, dar se pot schimba caracteristicile de stocare ale acestuia, prin comanda
ALTER TABLE.
Clauza RETURN AS specific tipul rezultatului returnat de cererile asupra coloanei 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 imbricat7.
Dac nu se specific opiunea propr_fizice, ce indic atributele segmentelor de date, modul de
organizare a tabelului sau utilizarea unei grupri, atunci tabloul de stocare este creat utiliznd
caracteristicile de stocare implicite.
Asupra clauzei NESTED TABLE exist urmtoarele restricii:
nu se poate specifica pentru un tabel temporar (un tabel temporar nu poate conine
coloane de tip colecie);
nu se pot specifica n cadrul aceleiai comenzi clauzele NESTED TABLE i OBJECT
IDENTIFIER;
nu se poate specifica parametrul TABLESPACE pentru un tablou imbricat, el fiind acelai
cu cel al tabelului printe;
nu se poate specifica o constrngere referenial asupra atributelor tabloului imbricat la
momentul crerii, dar este posibil modificarea ulterioar asupra tabelului printe
pentru adugarea unei astfel de constrngeri.
Declanatorii asupra unui tabel obiect se definesc similar celor asociai tabelelor obinuite. Nu
exist restricii speciale asupra utilizrii tipurilor obiect n cadrul declanatorilor.
Nu se pot defini declanatori pentru un tabel de stocare corespunztor coloanelor sau
atributelor de tip tablou imbricat. De asemenea, nu este permis modificarea valorilor de tip LOB n
corpul declanatorilor.
7
Locatorul este propriu unei sesiuni i nu poate fi reutilizat de la o sesiune la alta. Spre deosebire de un locator al unui LOB,
locatorii coleciilor nu pot fi utilizai pentru modificarea instanei respective.
38 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Exemplu:
S se creeze un declanator asupra tabelului obiect opere_de_arta definit anterior. Acest
declanator insereaz o nou nregistrare n tabelul cumparari, pentru fiecare oper de art cumprat.
S se insereze o nregistrare i s se constate efectul declanatorului.
CREATE OR REPLACE TRIGGER t_ai_on_opere
AFTER INSERT ON opere_de_arta
FOR EACH ROW
BEGIN
INSERT INTO cumparari VALUES
(t_opera_de_arta(:NEW.cod_opera,:NEW.tip, :NEW.titlu,
NULL, :NEW.data_crearii, :NEW.data_achizitiei,
:NEW.valoare,:NEW.polite,:NEW.dimensiuni),
DEFAULT, :NEW.valoare, 'Vanzator implicit');
END;
/
INSERT INTO opere_de_arta (cod_opera, tip, titlu)
VALUES (1, 'tip_fictiv', 'titlu_fictiv');
SELECT *
FROM cumparari;
Dac regsirea unei coloane ntr-o operaie relaional este determinist i poate fi fcut de
ctre sistem, atunci SQL permite omiterea prefixrii acesteia cu numele tabelului.
Exemplu:
S se gseasc toate operele de art care au fost evaluate exact la valoarea la care au fost
achiziionate (coloana valoare face parte din tabelul opere_de_arta, iar pret din tabelul cumparari).
SELECT cod_opera, titlu, tip
FROM opere_de_arta
WHERE EXISTS (SELECT 'X'
FROM cumparari
WHERE valoare = pret);
Sistemul determin crui tabel i aparine fiecare coloan (cod_opera, titlu, tip, valoare
tabelului opere_de_arta, iar pret tabelului cumparari).
Utiliznd notaia cu punct, se pot prefixa numele de coloane cu nume de tabele sau de alias-
uri, ceea ce face codul mai explicit i mai uor de ntreinut.
SELECT cod_opera, titlu, tip
FROM opere_de_arta
WHERE EXISTS(SELECT 'X'
FROM cumparari
WHERE opere_de_arta.valoare = cumparari.pret);
SELECT cod_opera, titlu, tip
FROM opere_de_arta oda
WHERE EXISTS (SELECT 'X'
FROM cumparari c
WHERE oda.valoare = c.pret);
Pe lng faptul c, n unele cazuri, specificarea unui alias este obligatorie, utilizarea numelor
necalificate poate genera probleme. Dac, de exemplu, se adaug o nou coloan, valoare, n cadrul
tabelului cumparari i nu se schimb cererea de mai sus (cea n care nu se prefixeaz nici o coloan),
sistemul recompileaz automat interogarea astfel nct subcererea va folosi noua coloan valoare din
tabelul cumparari.
Orientare pe obiecte n Oracle9i 39

Pentru evitarea unor astfel de situaii i a problemelor similare de rezolvare a referinelor, este
recomandat utilizarea unui alias de tabel pentru a prefixa referinele ctre metodele sau atributele
obiectelor, prin notaia cu punct. Alias-ul de tabel este opional dac referirea atributelor terminale ale
unui tabel obiect se face n mod direct, fr notaia cu punct.
Exemplu:
Urmtoarele cereri indic modaliti corecte sau incorecte de referire ale atributului nume.
Tabelul tab_artisti este un tabel obiect de tip t_artist, iar tabelul opere_de_arta este un tabel relaional
ce conine o coloan obiect de tip t_artist.
SELECT nume FROM tab_artisti; --Corect
SELECT artist.nume FROM opere_de_arta; --Incorect
SELECT opere_de_arta.artist.nume
FROM opere_de_arta; --Incorect
SELECT oda.artist.nume FROM opere_de_arta oda; --Corect
n prima comand, nume este o coloan din tab_artisti. Ea refer atributul terminal
corespunztor n mod direct, fr s utilizeze notaia cu punct, astfel nct nu este necesar un alias de
tabel. n cea de-a doua comand, nume este un atribut al obiectului de tip t_artist stocat n coloana
artist. Aceast referin utilizeaz notaia cu punct i necesit un alias de tabel pentru a fi corect. Cea
de-a treia comand utilizeaz numele tabelului pentru a prefixa coloana. Acest lucru nu este permis,
trebuie specificat alias-ul tabelului aa cum este exemplificat n ultima cerere.
O referin ctre atributul sau metoda unui obiect trebuie prefixat cu un alias de tabel i nu
cu numele tabelului, chiar dac acesta este la rndul lui prefixat de numele schemei (utilizator.tabel).
Acelai lucru se aplic i la accesarea atributelor de tip referin.
De exemplu, expresia student.cumparari.opera.valoare se refer la schema student, tabelul
cumparari, coloana opera i atributul valoare al acestei coloane. Expresia este totui incorect din
cauz c este folosit direct numele tabelului cumparari i nu un alias al acestuia.

3.5. 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.
De exemplu, n cadrul tipului obiect t_sala se poate declara o metod suma_valoare() pentru
a calcula valoarea total a operelor dintr-o anumit sal a muzeului. Apelarea acestei metode relativ la
o instan a tipului, v_sala, se poate face prin intermediul expresiei v_sala.suma_valoare().
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 i 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
40 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Pentru implementarea metodelor unui tip obiect se utilizeaz comanda CREATE TYPE
BODY. Prin intermediul acestei comenzi trebuie specificat codul asociat tuturor metodelor declarate n
comanda CREATE TYPE8.
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
trebuie deinut privilegiul sistem CREATE ANY TYPE, iar pentru a nlocui corpul unui astfel de tip
trebuie avut i privilegiul sistem DROP ANY TYPE. Comanda are urmtoarea sintax:
CREATE [OR REPLACE] TYPE BODY [schema.]nume_tip {IS | AS}
{MEMBER | STATIC}{declar_proc | decl_funcie | decl_constr}
[ {MEMBER | STATIC}{declar_proc | decl_funcie | decl_constr}]
[ {MAP | ORDER} MEMBER decl_funcie]
END;
Pentru a schimba definiia corpului unui tip obiect fr a-l suprima i crea din nou, se
utilizeaz opiunea OR REPLACE. Un avantaj al acestei abordri este c utilizatorii crora li s-au
acordat anumite privilegii asupra corpului recreat pot utiliza n continuare tipul fr a fi necesar
reacordarea privilegiilor. De asemenea, clauza OR REPLACE este utilizat atunci cnd se
implementeaz definiia unei noi metode MEMBER adugat prin intermediul comenzii ALTER
TYPEREPLACE.
Dac se omite numele schemei, atunci sistemul creeaz corpul tipului n schema curent. Nu
este permis definirea corpului unui tip pentru care nu a fost creat specificaia.
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 dintre metodele de ordonare, atunci se poate verifica doar egalitatea a dou obiecte
de acel tip.
Opiunile MEMBER sau STATIC specific tipul metodei implementate, care poate fi
procedur, funcie sau constructor. Sintaxa corespunztoare celor trei tipuri de metode este:
PROCEDURE nume_proc ( [parametru tip_de_date] )
{IS | AS} {bloc_PLSQL | specificaie_apel}
FUNCTION nume_funcie ( [parametru tip_de_date] )
RETURN tip_de_date {IS | AS} {bloc_PLSQL | specificaie_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_PLSQL | specificaie_apel}
Pentru fiecare metod trebuie specificate un nume, o list opional de parametri, iar n cazul
funciilor, un tip de date returnat. Antetul metodei trebuie s corespund celui din specificaia tipului
obiect definit.

8
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.
Orientare pe obiecte n Oracle9i 41

Dac pentru implementarea metodei nu este folosit un bloc PL/SQL, atunci trebuie definit o
specificaie de apel care face asocierea dintre o metod i o clas Java sau structur C.

Metode MEMBER
Metodele MEMBER reprezint modalitatea prin care o aplicaie acceseaz datele unei instane
obiect. n cadrul tipului obiect este posibil implementarea cte unei metode pentru fiecare operaie
care poate fi executat asupra obiectelor de tipul respectiv.
Exemplu:
S se defineasc o metod MEMBER, get_titlu(), care acceseaz informaiile despre o
anumit oper de art i returneaz titlul acesteia.
CREATE OR REPLACE TYPE BODY t_opera_de_arta AS
MEMBER FUNCTION get_titlu RETURN VARCHAR2 IS
BEGIN
RETURN SELF.titlu;
END get_titlu;
END;
/
SELECT o.get_titlu()
FROM opere o;
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 referi 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 de tip 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.
Exemplu:
S se defineasc tipul t_complex care modeleaz numerele complexe. Acesta conine
atributele real i imaginar de tip numeric i metode ce implementeaz calculul modulului unui numr
complex, al sumei i produsului a dou numere complexe.
PROMPT crearea tipului t_complex
CREATE TYPE t_complex AS OBJECT (
real NUMBER,
imaginar NUMBER,
MEMBER FUNCTION modul RETURN NUMBER,
MEMBER FUNCTION adunare(p_ob t_complex) RETURN t_complex,
MEMBER FUNCTION inmultit(p_ob t_complex) RETURN t_complex);
/
PROMPT crearea corpului tipului t_complex
CREATE OR REPLACE TYPE BODY t_complex AS
MEMBER FUNCTION modul RETURN NUMBER IS
v_rezultat NUMBER;
BEGIN
42 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

v_rezultat := SQRT (SELF.real * SELF.real) +


SQRT (SELF.imaginar * SELF.imaginar);
-- echivalent cu linia precedenta
v_rezultat := SQRT (real * real) +
SQRT (imaginar * imaginar);
RETURN v_rezultat;
END modul;
MEMBER FUNCTION adunare(p_ob t_complex) RETURN t_complex IS
v_rezultat t_complex;
BEGIN
v_rezultat := t_complex (SELF.real + p_ob.real,
SELF.imaginar + p_ob.imaginar);
-- echivalent cu linia precedenta
v_rezultat := t_complex (real + p_ob.real,
imaginar + p_ob.imaginar);
RETURN v_rezultat;
END adunare;
MEMBER FUNCTION inmultit(p_ob t_complex) RETURN t_complex
IS
v_rezultat t_complex;
v_real NUMBER;
v_imaginar NUMBER;
BEGIN
v_real := real * p_ob.real - imaginar * p_ob.imaginar;
v_imaginar := real * p_ob.imaginar + imaginar * p_ob.real;
v_rezultat := t_complex (v_real, v_imaginar);
RETURN v_rezultat;
END inmultit;
END;
/
PROMPT instantierea obiectului si apelarea metodelor
SET SERVEROUTPUT ON
SET VERIFY OFF
DECLARE
var1 t_complex := t_complex (&&g_real, &&g_imaginar);
var2 t_complex := t_complex (&g_real, -&g_imaginar);
v_a t_complex; -- pentru suma
v_i t_complex; -- pentru produs
BEGIN
DBMS_OUTPUT.PUT_LINE ('var1 = ' || var1.real || ' + (' ||
var1.imaginar || ') *i');
DBMS_OUTPUT.PUT_LINE ('var2 = ' || var2.real || ' + (' ||
var2.imaginar || ') *i');
v_a := var1.adunare (var2);
v_i := var1.inmultit (var2);
DBMS_OUTPUT.PUT_LINE ('var1 + var2 = ' || v_a.real ||
' + (' || v_a.imaginar || ') *i');
DBMS_OUTPUT.PUT_LINE ('var1 * var2 = ' || v_i.real ||
' + (' || v_i.imaginar || ') *i');
END;
/
Orientare pe obiecte n Oracle9i 43

Metode pentru compararea obiectelor


Valorile unui tip de date scalar au o ordine predefinit care permite folosirea acestora n
comparaii. Un tip obiect cu o structur complex i neuniform, format din mai multe atribute cu
tipuri de date diferite, 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 ce pot fi definite:
metode de mapare (de tip MAP);
metode de ordonare (de tip ORDER).
O metod de tip MAP permite compararea obiectelor prin asocierea dintre o instan obiect i
o valoare scalar (de exemplu, de tip DATE, VARCHAR2, NUMBER, CHAR, REAL).
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 instanei 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 ob_1 > ob_2) sau indirecte (generate de clauzele DISTINCT, GROUP BY i
ORDER BY9). Dac argumentul metodei MAP este null, atunci aceasta returneaz valoarea null i nu
mai este invocat. Dac ob_1 i ob_2 sunt dou obiecte ce pot fi comparate utiliznd o metod de
mapare denumit map(), atunci comparaia ob_1 > ob_2 este echivalent cu
ob_1.map() > ob_2.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:
S se defineasc o metod 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 tip obiect poate declara cel mult o metod de ordonare. Clauza ORDER MEMBER

9
Dac tipul va fi referit n cereri ce implic sortri (printr-o clauz ORDER BY, GROUP BY, DISTINCT sau UNION) sau
join-uri i se dorete ca aceste cereri s fie paralelizate, atunci este obligatorie o funcie de tip MAP.
44 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

specific o funcie membru de tip ORDER care accept instana unui obiect ca argument explicit,
SELF ca argument implicit i returneaz un ntreg. 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, metoda ntoarce tot null i nu 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 consideraie luminozitatea i
numrul de pixeli.
Exemplu:
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 a 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 VARCHAR2(60);
v_return INTEGER;
BEGIN
v_nume_complet := nume || ' ' || prenume;
IF v_nume_complet < a.nume || ' ' || a.prenume THEN
v_return := -1; --sau alt numar negativ
ELSE
IF v_nume_complet > a.nume || ' ' || a.prenume THEN
v_return := 1;-- sau alt numar pozitiv
ELSE -- acelasi nume
IF TO_NUMBER (anul_nasterii) >
TO_NUMBER (a.anul_nasterii) THEN
v_return := -1;
ELSIF TO_NUMBER (anul_nasterii) <
TO_NUMBER (a.anul_nasterii) THEN
v_return := 1;
ELSE
v_return := 0;
END IF;
END IF;
END IF;
RETURN v_return;
END comparare;
END;
Orientare pe obiecte n Oracle9i 45

/
DECLARE
v_artist1 t_artist := t_artist ('Peter', 'Breugel', '1457',
NULL, NULL, NULL);
v_artist2 t_artist := t_artist ('Peter', 'Breugel', '1512',
NULL, NULL, NULL);
v_rezultat INTEGER;
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;
/
Dac se declar una dintre metodele de comparare, atunci obiectele pot fi comparate n cadrul
instruciunilor SQL sau n comenzi procedurale. Dac nu s-a definit nici una dintre 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. De exemplu, se folosete o metod MAP pentru join-urile care folosesc funcii de
dispersie (hash join). n acest caz, nu se poate folosi o metod ORDER, deoarece mecanismul
dispersional folosete o valoare scalar asociat obiectului.
Metoda MAP se aplic o singur dat pentru a asocia obiectele cu nite valori scalare. Prin
urmare, o metod 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 mai
complex a lumii reale.

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:
Comenzile ce urmeaz prezint crearea i referirea unei metode statice. 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,
46 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

STATIC PROCEDURE ins (p_a_id NUMBER, p_b_id NUMBER));


/
CREATE TABLE b OF tip_b;
CREATE TABLE a OF tip_a;
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;
-- aliasul este obligatoriul pentru a folosi REF()
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 ce 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. ncepnd cu Oracle9i a fost introdus
clauza CONSTRUCTOR care 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, n mod implicit, sistemul returneaz noua instan
SELF definit de constructorul respectiv.
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:
a) S se defineasc un tip t_organizator care s conin atributele cod, nume, telefon i
adresa. S se implementeze un constructor care permite specificarea doar a codului i numelui
organizatorului. S se creeze un bloc PL/SQL n care s se utilizeze ambii constructori (implicit i
definit de utilizator).
CREATE OR REPLACE TYPE t_organizator AS OBJECT (
cod NUMBER,
nume VARCHAR2(20),
telefon VARCHAR2(30),
Orientare pe obiecte n Oracle9i 47

adresa 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.telefon := '1234567';
SELF.adresa := t_adresa (-1, 'nici o strada',
NULL, NULL, NULL, NULL);
RETURN;
END;
END;
/
DECLARE
v_org1 t_organizator;
v_org2 t_organizator;
BEGIN
-- constructor definit de utilizator
v_org1 := NEW t_organizator(1, 'Titan SA');
DBMS_OUTPUT.PUT_LINE (v_org1.adresa.strada);
-- constructorul implicit
v_org2 := t_organizator(1, 'Arta SA', '0724.513.331', NULL);
END;
/
b) S se defineasc tabelul obiect tab_organizatori i s se introduc date despre un
organizator avnd adresa precizat. Metoda constructor t_adresa creeaz un obiect de tipul t_adresa
avnd valorile atributelor specificate ca parametri.
CREATE TABLE tab_organizatori OF t_organizator;
INSERT INTO tab_organizatori
VALUES ( 1, 'Georgescu Elena', '630.98.04',
t_adresa(123, '23A N. Grigorescu', '74612', 'Bucuresti',
'Sector 3', 'Romania'));

3.6. Tipuri colecie


Sistemul Oracle suport dou tipuri colecie persistente: vector (varying array sau varray) i
tablou imbricat (nested table). Tipurile colecie au mai fost tratate n cadrul capitolului 3 din
perspectiva PL/SQL. n aceast seciune sunt prezentate tipurile colecie i cteva exemple din
perspectiva orientrii pe obiecte.
Un vector este o colecie ordonat de elemente. Poziiile sunt indexate numeric i pot fi
folosite pentru accesul la elemente. Dimensiunea unui vector este dinamic, n sensul c la declarare
se specific numrul maxim de elemente, dar acesta poate fi schimbat ulterior. Numrul de elemente
trebuie s fie un literal ntreg. Vectorii sunt stocai ca obiecte opace, adic de tip RAW sau BLOB.
Un vector nu poate conine elemente de tip LOB. Aceasta presupune c un vector nu poate s
48 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

conin elemente de un tip definit de utilizator care are atribute de tip LOB. Se poate crea un tip vector
de tip XMLType care s fie utilizat n PL/SQL sau n cererile vizualizrilor, dar nu se poate crea o
coloan de acest tip vector, deoarece sistemul stocheaz datele de tip XMLType sub form de CLOB.
Un tablou imbricat poate avea un numr nelimitat de elemente de acelai tip de date (nu este
specificat un numr maxim n definiia tabloului), iar ordinea elementelor nu este pstrat. El are o
singur coloan de tip predefinit sau definit de utilizator. n cazul n care coloana din tabloul imbricat
este de tip obiect, tabloul poate fi vizualizat ca un tabel multicoloan, avnd cte o coloan pentru
fiecare atribut al tipului obiect.
Asupra unui tablou imbricat se pot executa operaii LMD, similar celorlalte tabele ale
schemei. Elementele unui tablou imbricat sunt coninute ntr-un tabel de stocare separat, care conine
o coloan ce identific linia sau obiectul din tabelul printe din care face parte fiecare element.
Modalitatea este similar tabelelor printe - copil ale unei scheme relaionale.
Dac o coloan sau atribut dintr-un tabel relaional sau obiectual este de tip tablou imbricat,
atunci sistemul Oracle reine n acelai tabel de stocare toate valorile tabloului imbricat din tabelul
respectiv.
n atribuirile dintre colecii, sursa i inta trebuie s aib acelai tip de date. De asemenea,
obiectele ale cror tip de date sunt tipuri colecii nu pot fi comparate.
Dac este necesar s se stocheze doar un numr fix de elemente, s se parcurg elementele
ntr-o anumit ordine sau s se selecteze i s se prelucreze ntreaga colecie ca un ntreg, atunci se
recomand utilizarea unui vector.
Pentru eficien n accesarea coleciilor, prelucrarea unui numr arbitrar de elemente sau
executarea operaiilor de inserare, modificare i selectare n mas, este recomandat folosirea
tablourile imbricate. De asemenea, tablourile imbricate sunt utile atunci cnd nu exist o ordine
prestabilit a elementelor coleciei i este important interogarea eficient a elementelor individuale.
La crearea unui tip vector sau tablou imbricat nu se aloc spaiu de stocare, ci doar se reine
definiia tipului, care poate fi utilizat ulterior ca:
tip de date al unei coloane ntr-un tabel relaional;
atribut al unui tip obiect;
tip de date al unei variabile PL/SQL, parametru sau valoare returnat de o funcie.
Exemplu:
a) S se creeze un tip vector t_preturi care conine cel mult 10 preuri ce pot fi ataate unei
opere de art.
CREATE TYPE t_preturi AS VARRAY(10) OF NUMBER(12, 2);
/
b) S se creeze un tip tablou imbricat cu elemente de tip t_adresa. Tipul va fi utilizat pentru
stocarea coleciei de adrese a organizatorilor.
CREATE TYPE t_adrese_ti AS TABLE OF t_adresa;
/
c) S se nlocuiasc coloana adresa de tip t_adresa a tabelului obiect tab_organizatori, cu o
coloan adrese de tip t_adrese_ti care s conin mai multe adrese ale unui organizator. La crearea
tabelului tab_organizatori trebuie specificat tabelul de stocare (tstoc_adrese) asociat atributului
adrese. Acest tabel corespunde tuturor obiectelor de tip t_organizator stocate n cadrul tabelului
obiect.
ALTER TYPE t_organizator
DROP ATTRIBUTE adresa
Orientare pe obiecte n Oracle9i 49

CASCADE;
ALTER TYPE t_organizator
ADD ATTRIBUTE adrese t_adrese_ti
CASCADE;
DROP TABLE tab_organizatori;
CREATE TABLE tab_organizatori OF t_organizator
NESTED TABLE adrese STORE AS tstoc_adrese;
O modalitate convenabil de accesare a elementelor unui tablou imbricat n mod individual
este furnizat de un cursor imbricat (expresie CURSOR). n acest fel, valoarea unei coloane de tip
colecie poate fi transmis ca argument de tip REF CURSOR unui subprogram PL/SQL.
Exemplu:
S se listeze numele fiecrui organizator i adresele acestuia folosind o expresie CURSOR.
SELECT o.nume, CURSOR (SELECT * FROM TABLE (o.adrese))
FROM tab_organizatori o;

Tipuri colecie pe mai multe niveluri


Un tip colecie pe mai multe niveluri este un tip colecie cu elemente care sunt, n mod direct
sau indirect, tipuri colecie.
Ca i tipurile colecie pe un singur nivel, acestea pot fi utilizate ca tipuri de date ale
coloanelor ntr-un tabel relaional, ale atributelor unui obiect ntr-un tabel obiect sau ale variabilelor
PL/SQL. Numrul nivelurilor posibile de imbricare este limitat doar de capacitatea de stocare a
sistemului.
Exemplu:
S se defineasc un tablou imbricat de tablouri imbricate ce modeleaz un sistem solar n care
fiecare stea are asociat o mulime de planete ce graviteaz n jurul ei, iar fiecare planet are o
mulime de satelii ([63]).
CREATE TYPE t_satelit AS OBJECT (
nume VARCHAR2(20),
diametru NUMBER);
/
CREATE TYPE t_sateliti_ti AS TABLE OF t_satelit;
/
CREATE TYPE t_planeta AS OBJECT (
nume VARCHAR2(20),
masa NUMBER,
sateliti t_sateliti_ti);
/
CREATE TYPE t_planete_ti AS TABLE OF t_planeta;
/
O coloan sau un atribut al unui tabel obiect de tip tablou imbricat necesit specificarea unui
tabel de stocare unde s poat fi depuse valorile corespunztoare tuturor tablourilor imbricate din
coloana sau atributul respectiv. n mod similar, o colecie de tablouri imbricate pe mai multe niveluri
necesit cte un tabel de stocare specificat att pentru setul interior de tablouri imbricate, ct i pentru
cel exterior. n consecin, pentru fiecare atribut de tip tablou imbricat de pe un anumit nivel al
coleciei trebuie specificat cte o clauz de stocare separat.
50 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Exemplu:
S se creeze un tabel (stele), care conine o coloan denumit planete ce stocheaz colecia de
planete asociate fiecrei stele (tipul tablou imbricat t_planete_ti). La nivel de tabel trebuie specificate
clauze de stocare separate att pentru tabloul imbricat exterior planete, ct i pentru cel interior
sateliti.
CREATE TABLE stele (
nume VARCHAR2(20),
varsta NUMBER,
planete t_planete_ti)
NESTED TABLE planete STORE AS tstoc_planete
(NESTED TABLE sateliti STORE AS tstoc_sateliti);
Exemplul precedent poate face referire la tabloul imbricat interior (sateliti) prin nume,
deoarece acesta este un atribut al obiectului planete. Dac tabloul imbricat interior nu este un atribut
al unui obiect i nu are nume, atunci pentru a referi numele acestui tablou se folosete cuvntul cheie
COLUMN_VALUE.
Exemplu:
CREATE TYPE t_numere_ti AS TABLE OF NUMBER;
/
CREATE TYPE t_siruri_ti AS TABLE OF t_numere_ti;
/
CREATE TABLE tab (
data DATE,
rezultat t_siruri_ti)
NESTED TABLE rezultat STORE AS tstoc_rezultat
(NESTED TABLE COLUMN_VALUE STORE AS tstoc_colval);
Exemplu:
S se specifice atributele fizice pentru tabelele de stocare asociate coloanelor de tip colecie
planete i sateliti, utiliznd clauza NESTED TABLE.
DROP TABLE stele;
CREATE TABLE stele (
nume VARCHAR2(20),
varsta NUMBER,
planete t_planete_ti)
NESTED TABLE planete STORE AS tstoc_planete
((PRIMARY KEY (NESTED_TABLE_ID, nume))
ORGANIZATION INDEX COMPRESS
NESTED TABLE sateliti STORE AS tstoc_sateliti);
Fiecare tabel de stocare al unui tablou imbricat conine o coloan, referit prin
NESTED_TABLE_ID, care returneaz cheia nregistrrii corespunztoare liniei asociate din tabelul
printe. Dac un tabel printe este la rndul lui tablou imbricat (de exemplu planete) atunci el
conine dou coloane de tip identificator generate de sistem: una, referit prin NESTED_TABLE_ID,
care face legtura dintre liniile sale i liniile din propriul tabel printe, i o coloan ascuns referit
de coloana NESTED_TABLE_ID din tabelul imbricat copil.
n exemplul precendent, tabloul imbricat planete este organizat pe baz de index prin
adaugarea clauzei ORGANIZATION INDEX. De asemenea, el are asociat o cheie primar n care
prima coloan este NESTED_TABLE_ID. Aceast coloan conine identificatorul liniei din tabelul
Orientare pe obiecte n Oracle9i 51

printe cu care este asociat o linie dat din tabelul de stocare. Specificarea unei chei primare ce
conine NESTED_TABLE_ID i organizarea pe baz de index a tabelului determin sistemul s
grupeze fizic toate liniile tabloului imbricat care aparin aceleiai linii printe, obinndu-se un
acces mai rapid la informaii.
n funcie de tipul elementelor, vectorii pe mai multe niveluri sunt stocai ntr-unul din
urmtoarele moduri:
n cazul vectorilor de vectori, ntregul vector este stocat inline dac nu depete limita
superioar de 4000 octei sau dac se specific explicit stocarea lui sub form de LOB;
n cazul vectorilor de tablouri imbricate, ntregul vector este stocat sub form de LOB,
linia reinnd doar locatorul pentru obiectul LOB respectiv (nu exist tabele de stocare
asociate elementelor de tip tablou imbricate din vector, ntreaga colecie de tablouri
imbricate fiind stocat n cadrul vectorului).
Exemplu:
S se specifice explicit clauza de stocare sub form de obiect LOB pentru elementele de tip
vector ale unui tablou imbricat. Cuvntul cheie COLUMN_VALUE poate fi utilizat relativ la orice
colecie interioar fr nume (vector sau tablou imbricat).
CREATE TYPE t_numere_v AS VARRAY(10) OF NUMBER;
/
CREATE TYPE t_siruri_tiv AS TABLE OF t_numere_v;
/
CREATE TABLE tab_numere (
cod NUMBER,
rezultat t_siruri_tiv)
NESTED TABLE rezultat STORE AS tstoc_rez
(VARRAY COLUMN_VALUE STORE AS LOB numere_lob);
De asemenea, cuvintele cheie STORE AS LOB permit specificarea n mod explicit a stocrii
sub form de LOB pentru un tip vector de vectori.
CREATE TYPE t_siruri AS OBJECT (
a NUMBER,
b t_numere_v);
/
CREATE TYPE t_vv AS VARRAY(2) OF t_siruri;
/
CREATE TABLE tab_vv (
cod NUMBER,
doua_siruri t_vv)
VARRAY doua_siruri STORE AS LOB tab_vv_lob;
O instan a unui tip colecie se construiete asemntor cu o instan a unui tip obiect, prin
apelarea metodei constructor asociate. Numele metodei constructor coincide cu cel al tipului, iar
elementele coleciei apar n lista de argumente, delimitate prin virgul. Apelul unei metode
constructor cu o list vid de argumente creeaz o colecie vid. O colecie vid nu are elemente i nu
coincide cu o colecie care are valoarea null.
Exemplu:
Urmtorul exemplu apeleaz constructorul pentru colecia pe mai multe niveluri t_planete_ti.
52 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Acest tip este un tablou imbricat de obiecte de tip t_planeta, fiecare coninnd un tablou imbricat de
obiecte avnd tipul t_satelit. Constructorul tabloului imbricat exterior apeleaz constructorul
t_planeta pentru fiecare planet ce trebuie creat. Fiecare constructor t_planeta apeleaz constructorul
tipului tablou imbricat t_sateliti_ti, care, la rndul su, pentru fiecare instan obiect de tip t_satelit,
apeleaz constructorul asociat.
INSERT INTO stele
VALUES('Soare',23,
t_planete_ti(t_planeta('Neptun',10,
t_sateliti_ti(t_satelit('Proteus',67),
t_satelit('Triton',82))),
t_planeta('Jupiter',189,
t_sateliti_ti(t_satelit('Callisto',97),
t_satelit('Ganymede', 22)))));

Interogarea coleciilor
Exist dou metode generale de interogare a unui tabel care conine o coloan sau un atribut
de tip colecie. Prima returneaz coleciile imbricate integrate n cadrul liniilor rezultat, iar cealalt
distribuie colecia n aa fel nct fiecare element al acesteia s apar pe cte o linie.
Exemplu:
S se ataeze tipului creat anterior, t_autor, atributul articole de tip t_articole_ti, tablou
imbricat de elemente de tip t_articol. Coloana de tip colecie articole poate aprea n lista SELECT ca
orice alt coloan scalar, interogarea ei grupnd, n acest caz, elementele coleciei n linia rezultat cu
care este asociat.
CREATE TYPE t_articol AS OBJECT (
cod NUMBER,
titlu VARCHAR2(40),
data DATE);
/
CREATE TYPE t_articole_ti AS TABLE OF t_articol;
/
ALTER TYPE t_autor
ADD ATTRIBUTE (articole t_articole_ti)
CASCADE;
UPDATE tab_autori
SET articole = t_articole_ti (
t_articol(10, 'Despre bucurie', SYSDATE - 7),
t_articol(20, 'Vigilenta resentimentara', SYSDATE))
WHERE cod = 0;
Urmtoarea cerere returneaz numele fiecrui autor i colecia de articole asociat, prezentat
n format imbricat.
SELECT a.nume, a.articole
FROM tab_autori a;
NUME ARTICOLE(COD, TITLU, DATA)
----------- -------------------------------------------------Plesu
T_ARTICOLE_TI(T_ARTICOL(10, 'Despre bucurie',
'10-AUG-03'), T_ARTICOL(20, 'Vigilenta
resentimentara', '17-AUG-03'))
Orientare pe obiecte n Oracle9i 53

Rezultatele unei interogri sunt imbricate dac o coloan de tip obiect din lista SELECT
conine un atribut colecie (chiar dac acea colecie nu apare n lista SELECT). De exemplu, cererea
urmtoare produce un rezultat imbricat.
SELECT * FROM tab_autori;

Distribuirea rezultatelor interogrilor


Nu toate utilitarele sau aplicaiile pot lucra cu rezultate n format imbricat. Pentru a accesa
datele din coleciile Oracle este necesar un format convenional, atributele coleciilor unei linii fiind
proiectate n cadrul uneia sau mai multor linii relaionale. Acest lucru este posibil utiliznd expresia
TABLE.
Expresia TABLE permite interogarea unei colecii n clauza FROM, ntr-o manier similar
tabelelor obinuite. Efectul este executarea join-ului dintre tabloul imbricat i linia din tabelul
printe care l conine. Expresia TABLE poate fi utilizat pentru interogarea oricrei expresii de tip
colecie, inclusiv a valorilor transcendente (variabile sau parametri). TABLE a nlocuit expresia
subcerere THE, care va fi depreciat n versiunile ulterioare.
Exemplu:
a) S se obin numele fiecrui autor i colecia sa de articole, n format distribuit.
SELECT aut.nume, art.cod, art.titlu, art.data
FROM tab_autori aut, TABLE(aut.articole) art;
NUME COD TITLU DATA
------ --- ------------------------- ----------
Plesu 10 Despre bucurie 10-AUG-03
Plesu 20 Vigilenta resentimentara 17-AUG-03
Expresia TABLE utilizeaz alias-ul tabelului printe pentru a specifica tabelul care conine
coloana colecie referit. n exemplul anterior, expresia TABLE (aut.articole) face referire la coloana
de tip colecie articole a tabelului tab_autori. Pentru a referi o coloan dintr-un tabel, expresia TABLE
poate utiliza alias-ul oricrui tabel ce apare la stnga ei n clauza FROM.
b) Simpla selectare a numelui i a listei de articole pentru fiecare autor produce linii doar
pentru acei autori care au articole asociate. Pentru a obine i linii referitoare la autorii fr articole
nregistrate se poate utiliza un outer-join.
SELECT aut.nume, art.*
FROM tab_autori aut, TABLE(aut.articole)(+) art;
c) n exemplul urmtor, tabelul tab_autori este utilizat n clauza FROM doar pentru a
asigura un alias de tabel pentru expresia TABLE care urmeaz. De aceea, dei n rezultat nu apare nici
o coloan din tabel (alta dect coloana referit n expresia TABLE), eliminarea acestuia din clauza
FROM nu este permis.
SELECT art.*
FROM tab_autori aut, TABLE(aut.articole) art;
Exemplele precedente folosesc expresii TABLE care conin nume de colecii. O expresie
TABLE poate conine i o subcerere asupra unei colecii.
Restriciile asupra utilizrii subcererilor ntr-o expresie TABLE sunt:
54 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

subcererea trebuie s returneze un tip colecie;


lista SELECT a subcererii trebuie s conin un singur cmp;
subcererea trebuie s returneze o singur colecie, nu poate returna colecii pentru mai
multe linii (altfel, apare eroarea ORA-01427: single-row subquery returns more than one
row).
Exemplu:
S se afieze colecia de articole a autorului avnd codul 0. Se observ c subcererea din
expresia TABLE ndeplinete toate restriciile prezentate.
SELECT *
FROM TABLE (SELECT aut.articole
FROM tab_autori aut
WHERE aut.cod = 0);
O expresie TABLE poate fi utilizat n clauza FROM a unei cereri integrate ntr-o expresie
CURSOR.
Exemplu:
S se selecteze codul autorului i lista de articole corespunztoare acestuia, utiliznd o
expresie CURSOR.
SELECT aut.cod, CURSOR (SELECT *
FROM TABLE(aut.articole))
FROM tab_autori aut;
Distribuirea interogrilor poate fi utilizat, n mod similar, i pentru coleciile pe mai multe
niveluri.
Exemplu:
S se exemplifice distribuirea unei interogri referitoare la un tablou imbricat de tablouri
imbricate. Se consider tabelul stele, n care fiecare stea are ca atribut un tablou imbricat de planete i
fiecare planet are un tablou imbricat de satelii. S se defineasc o cerere care returneaz numele
tuturor sateliilor asociai planetelor ce graviteaz n jurul stelelor nregistrate n tabel.
SELECT t.nume
FROM stele s, TABLE(s.planete) p, TABLE(p.sateliti) t;
Pentru a distribui rezultatul cererilor asupra coleciilor se pot crea proceduri sau funcii
PL/SQL speciale.
Exemplu:
a) S se creeze o funcie sateliti_mari() care s returneze doar sateliii cu diametrul mai
mare dect 77.
CREATE OR REPLACE FUNCTION sateliti_mari
(p_sateliti IN t_sateliti_ti) RETURN t_sateliti_ti IS
v_sateliti_mari t_sateliti_ti := t_sateliti_ti();
i NUMBER;
j NUMBER := 0;
BEGIN
FOR i IN 1..p_sateliti.COUNT LOOP
IF p_sateliti IS NOT NULL AND
p_sateliti(i).diametru >= 77 THEN
Orientare pe obiecte n Oracle9i 55

v_sateliti_mari.EXTEND;
j := j + 1;
v_sateliti_mari(j) := p_sateliti(i);
END IF;
END LOOP;
RETURN v_sateliti_mari;
END;
/
b) S se obin lista stelelor care au planete cu satelii mari, mpreun cu numele i
diametrele sateliilor corespunztori.
SELECT s.nume, sm.nume, sm.diametru
FROM stele s, TABLE (s.planete) p,
TABLE (CAST (sateliti_mari (p.sateliti)
AS t_sateliti_ti)) sm;

Execuia operaiilor LMD asupra coleciilor


Asupra coloanelor de tip tablou imbricat, sistemul permite efectuarea urmtoarelor operaii
LMD:
inserri i modificri care afecteaz o ntreag colecie;
modificri pe seciuni (piecewise updates), adic operaii de inserare, tergere sau
modificare a elementelor unei colecii.
Sistemul Oracle nu permite modificri pe seciuni asupra coloanelor de tip vector. Coloanele
VARRAY pot fi, ns, inserate sau modificate atomic.
Pentru modificrile pe seciuni ale coloanelor de tip tablou imbricat, comenzile LMD trebuie
s identifice valoarea elementului care trebuie modificat. Acest lucru se face utiliznd expresia
TABLE. Dac valoarea coleciei returnate de expresia TABLE este null, atunci comanda de modificare
returneaz eroarea ORA-22908: reference to NULL table value. Nu se pot insera, terge sau
modifica valori dect n cadrul tablourilor imbricate instaniate.
Exemplu:
Urmtoarele comenzi exemplific execuia pe seciuni a celor trei operaii LMD asupra
coloanelor de tip tablou imbricat.
-- inserare
INSERT INTO TABLE (SELECT aut.articole
FROM tab_autori aut
WHERE aut.cod = 0)
VALUES (30, 'Noica', SYSDATE);
--modificare
UPDATE TABLE (SELECT aut.articole
FROM tab_autori aut
WHERE aut.cod = 0) art
SET VALUE(art) = t_articol(art.cod,'Noica si eu',art.data)
WHERE art.cod = 30;
-- stergere
DELETE FROM TABLE(SELECT aut.articole
FROM tab_autori aut
WHERE aut.cod = 0) art
WHERE art.cod = 20;
56 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Similar coleciilor simple, coleciile pe mai multe niveluri ce conin vectori permit doar
operaii globale la nivel de colecie.
Exemplu:
S se modifice pe seciuni o colecie pe mai multe niveluri pentru a redenumi satelitul Triton
al planetei Neptun. Noul nume este Thalia.
UPDATE TABLE(SELECT p.sateliti
FROM stele s, TABLE(s.planete) p
WHERE p.nume = 'Neptun') sat
SET VALUE(sat) = t_satelit('Thalia', 80)
WHERE sat.nume = 'Triton';
Expresia TABLE selecteaz tabloul imbricat ce conine sateliii planetei Neptun. Tabloul
imbricat returnat primete alias-ul sat, care este utilizat n cadrul clauzei SET pentru a referi valoarea
instanei ce va fi nlocuit (utiliznd funcia VALUE) i nu identificatorul obiect
(NESTED_TABLE_ID).
Exemplu:
Presupunnd c v_planete este o variabil de tip tablou imbricat de planete t_planete_ti, s se
insereze o nou stea avnd numele Aurora Boreal, vrsta 19 i planetele asociate date de variabila
v_planete.
DECLARE
v_planete t_planete_ti := NULL;
BEGIN
INSERT INTO stele VALUES ('Aurora Boreala', 19, v_planete);
END;
/
Urmtoarea comand modific tabelul stele setnd colecia de planete a stelei Aurora Boreal
la o valoare introdus de la tastatur. Dac se introduce o expresie valid pentru variabila de
substituie utilizat, atunci modificarea se realizeaz cu succes (de exemplu,
t_planete_ti(t_planeta('Pluto', 11, null))).
UPDATE stele s
SET s.planete = &v_planete
WHERE s.nume = 'Aurora Boreala';
Exemplu:
a) S se introduc o nou planet asociat stelei Soare. Planeta are numele Saturn, masa 65
i un singur satelit denumit Rea, cu diametrul 92.
INSERT INTO TABLE(
SELECT planete
FROM stele
WHERE nume = 'Soare') VALUES
('Saturn', 65, t_sateliti_ti( t_satelit('Rea', 92)));
b) S se asocieze planetei Jupiter un nou satelit, Miranda, cu diametrul 40. Expresia TABLE
din acest exemplu conine o subcerere care selecteaz tabloul imbricat interior pentru a putea specifica
inta comenzii INSERT.
INSERT INTO TABLE(SELECT p.sateliti
FROM TABLE(SELECT s.planete
Orientare pe obiecte n Oracle9i 57

FROM stele s
WHERE s.nume = 'Soare') p
WHERE p.nume = 'Jupiter')
VALUES ('Miranda', 40);

3.7. Motenirea tipurilor


Tipurile obiect permit o modelare expresiv i intuitiv a entitilor din lumea real care
trebuie implementate n cadrul unei aplicaii. Cu ajutorul obiectelor, pe lng entiti izolate, se pot
defini tipuri specializate de entiti, organizate ntr-o ierarhie de tipuri ce deriv dintr-un tip printe.
Astfel, operaiile se pot executa asupra ntregii ierarhii sau difereniat, asupra fiecrui tip din ierarhie,
n funcie de nivelul de specializare pe care l implementeaz.
O ierarhie de tipuri poate fi asemnat cu un arbore genealogic al tipurilor obiect. Ea const
dintr-un tip de baz, numit supertip (tip printe) i unul sau mai multe niveluri de tipuri obiect,
numite subtipuri (tipuri copii), derivate din acesta.
Subtipurile dintr-o ierarhie sunt conectate cu supertipurile lor prin motenire, acest lucru
nsemnnd c subtipurile primesc automat atributele i metodele tipului printe. De asemenea,
subtipurile se reflect automat orice schimbare asupra atributelor sau metodelor din cadrul tipului
printe, acest fapt definind proprietatea de propagare automat a schimbrilor.
Un subtip devine o versiune specializat a tipului printe prin adugarea de noi atribute i
metode celor motenite de la printe sau/i prin redefinirea metodelor motenite. Redefinirea unei
metode motenite asigur unui subtip propria implementare a metodei respective. O instan a unui
obiect de un anumit tip obiect poate fi substituit cu o instan obiect a unui subtip al su, ceea ce
definete proprietatea de polimorfism.
Polimorfismul este proprietatea unei variabile sau coloane obiectuale de a conine o valoare
de tipul declarat sau de orice subtip al tipului declarat. O metod apelat relativ la o astfel de variabil
sau coloan obiect se poate executa n mod diferit, n funcie de cel mai specific tip al valorii
coninute.

Tipuri i subtipuri
Un subtip poate fi derivat dintr-un supertip n mod direct sau indirect, prin intermediul mai
multor niveluri de extindere. Dintr-un supertip se pot deriva mai multe subtipuri, dar un subtip poate
fi derivat n mod direct dintr-un singur supertip. Cu alte cuvinte, sistemul Oracle permite doar
implementarea motenirii simpl, nu i a celei multiple.
Derivarea unui subtip dintr-un supertip se realizeaz prin definirea unei variante specializate a
supertipului. De exemplu, dintr-un tip t_organizator se poate deriva un tip t_org_particular i unul
t_org_de_stat. Fiecare dintre aceste subtipuri definesc tot un tip t_organizator, dar unul specializat.
Ceea ce face un subtip special i l distinge de supertipul printe este o schimbare asupra structurii
motenite de la tipul printe (modificarea sau adugarea de atribute sau metode).
Atributele i metodele unui tip obiect sunt elementele eseniale din specificaia lui. Dac
obiectul t_organizator are patru atribute cod, nume, telefon, adresa i metoda get_cod(), atunci tipul
obiect derivat din el va avea obligatoriu aceleai patru atribute i aceeai metod.
58 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Un subtip se poate specializa utiliznd una dintre urmtoarele modaliti:


adugarea de noi atribute sau metode;
schimbarea implementrii unei metode pe care subtipul o motenete de la tipul printe,
astfel nct versiunea de subtip s execute un alt cod dect printele su.
De exemplu, se poate specializa tipul t_organizator prin adugarea unui nou atribut,
cod_director_financiar, obinndu-se astfel subtipul t_org_particular. Dac tipul t_organizator
implementeaz o metod care s returneze descrierea complet a organizatorului, atunci metoda
respectiv trebuie adaptat pentru subtipul t_org_particular astfel nct s includ i atributul nou
introdus.
Un subtip nu poate elimina sau schimba tipul unui atribut motenit de la printe, el nu poate
dect s adauge noi atribute.
Un tip obiect forma_geometrica poate conine o metod calculeaza_aria(). Dou subtipuri ale
acestui tip, dreptunghi i cerc trebuie s implementeze aceast metod n moduri diferite.
Atributele i metodele primite de subtip de la printele lui se numesc motenite. Aceasta
presupune mai mult dect faptul c atributele i metodele sunt preluate de la tipul printe la
momentul definirii subtipului. Legtura de motenire rmne vie. Orice modificri fcute ulterior
asupra atributelor sau metodelor tipului printe sunt reflectate i n subtipurile tipului respectiv.
Un subtip conine, la orice moment, acelai nucleu de atribute i metode ca i tipul printe,
plus alte atribute i metode adugate, cu excepia cazurilor n care subtipul ofer o implementare nou
pentru o metod motenit. Prin urmare, dac definiia general a tipului t_organizator se schimb,
atunci se modific i definiia tipurilor copii t_org_particular i t_org_de_stat.
Relaia vie de motenire care exist ntre supertip i subtipurile sale consitutie sursa puterii
i complexitii obiectelor. Printr-o simpl recompilare, se poate schimba structura supertipului,
efectul reflectndu-se n toate subtipurile din ierarhie. Din acest motiv, astfel de schimbri trebuie
bine planificate.
De asemenea, o caracteristic important referitoare la un tabel sau o coloan este faptul c
poate conine obiecte att de tipul declarat, ct i de subtipurile acestuia. De aceea, sunt necesare noi
modaliti pentru a putea filtra n cadrul comenzilor SQL obiectele de un anumit tip din ierarhie.
Prin definiie, se poate specifica dac un tip obiect permite derivarea de subtipuri (opiunea
NOT FINAL din cadrul comenzii CREATE TABLE). n mod implicit, un tip obiect este final.
Exemplu:
S se defineasc un tip obiect, t_persoana, care s reprezinte un model de date pentru
informaiile legate de o persoan. Tipul t_persoana trebuie s permit definirea ulterioar de
subtipuri.
CREATE OR REPLACE TYPE t_persoana AS OBJECT (
cod NUMBER,
nume VARCHAR2(50))
NOT FINAL;
/
Proprietatea unui tip de a accepta derivarea de subtipuri poate fi modificat printr-o comand
ALTER TYPE. De exemplu, urmtoarea comand schimb tipul t_persoana ntr-un tip final.
ALTER TYPE t_persoana FINAL;
Orientare pe obiecte n Oracle9i 59

De asemenea, metodele pot fi declarate ca fiind finale sau nu. Dac o metod este final,
subtipurile nu pot s-i schimbe implementarea. Spre deosebire de tipuri, metodele sunt n mod
implicit nefinale i trebuie declarate explicit finale.
Exemplu:
S se creeze un tip nefinal care conine o funcie MEMBER final (combinaia invers nu are
sens).
CREATE TYPE tip AS OBJECT (,
MEMBER PROCEDURE afisare(),
FINAL MEMBER FUNCTION met(x NUMBER) )
NOT FINAL;
/

Crearea subtipurilor
Un tip poate avea mai multe subtipuri, iar acestea pot avea la rndul lor subtipuri. Un subtip
motenete toate atributele i metodele tipului printe direct (declarate sau motenite). Pentru a
defini un subtip se utilizeaz comanda CREATE TYPE specificnd n clauza UNDER printele
direct al subtipului.
Exemplu:
S se defineasc tipul t_artist care specializeaz tipul t_persoana. Deoarece t_artist este un
subtip al tipului t_persoana creat anterior, el motenete atributele cod i nume.
CREATE TYPE t_artist UNDER t_persoana (
cod_artist NUMBER,
an_nastere VARCHAR2(4),
an_moarte VARCHAR2(4),
nationalitate VARCHAR2(40));
/
Comanda care definete t_artist specializeaz tipul t_persoana, adugnd patru atribute.
Noile atribute declarate ntr-un subtip trebuie s aib nume diferite de numele oricrui atribut sau
metod declarate n supertipurile directe sau indirecte ale tipului respectiv.
Exemplu:
a) S se defineasc un subtip nefinal, t_autor, al tipului t_persoana.
CREATE OR REPLACE TYPE t_autor UNDER t_persoana (
cod_autor NUMBER,
ocupatie VARCHAR2(30),
descriere VARCHAR2(200))
NOT FINAL;
b) S se creeze un subtip, t_jurnalist, al tipului t_autor definit anterior. Pe lng atributele
motenite de la tipul t_autor, acesta declar dou noi atribute, functie i loc_munca.
CREATE TYPE t_jurnalist UNDER t_autor (
functie VARCHAR2(20),
loc_munca VARCHAR2(30));
/
SQL> desc t_jurnalist
t_jurnalist extends STUDENT.T_AUTOR
Nume Nul? Tip
----------- ---- --------------
COD NUMBER
60 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

NUME VARCHAR2(50)
COD_AUTOR NUMBER
OCUPATIE VARCHAR2(30)
DESCRIERE VARCHAR2(200)
FUNCTIE VARCHAR2(20)
LOC_MUNCA VARCHAR2(30)
Un tip este declarat neinstaniabil utiliznd clauza NOT INSTANTIABLE. Un tip neinstaniabil
este un fel de container. Dac tipul nu este instaniabil, el nu are constructor (nici implicit, nici definit
de utilizator) i nu se pot crea instane ale tipului respectiv. n limbajul Java, noiunea corespondent
este cea de clas abstract. Aceast opiune este util atunci cnd dou entiti au atribute comune care
pot fi implementate n cadrul unui tip printe al unei ierarhii, dar aceste atribute nu sunt suficiente
pentru instanierea de obiecte.
Exemplu:
Utiliznd tipuri obiect, s se reprezinte dou categorii de piese (rotund i dreptunghiular)
caracterizate de un nucleu de atribute i metode comune.
CREATE TYPE t_piesa AS OBJECT (
cod NUMBER,
tip VARCHAR2(10),
NOT INSTANTIABLE MEMBER FUNCTION suprafata RETURN NUMBER)
NOT INSTANTIABLE
NOT FINAL;
/
CREATE TYPE t_piesa_rotunda UNDER t_piesa (
diametru NUMBER,
OVERRIDING MEMBER FUNCTION suprafata RETURN NUMBER);
/
CREATE TYPE t_piesa_dreptunghiulara UNDER t_piesa (
latime NUMBER,
lungime NUMBER,
OVERRIDING MEMBER FUNCTION suprafata RETURN NUMBER);
/
Nu este permis crearea obiectelor de tip t_piesa pentru care nu sunt specificate clar
dimensiunile (lime i lungime pentru cea dreptunghiular i diametru pentru cea rotund). De aceea,
tipul printe comun este neinstaniabil.
Metodele pot fi i ele neinstaniabile. Similar tipurilor neinstaniabile, opiunea
corespunztoare este util atunci cnd dou tipuri trebuie s implementeze n mod diferit o metod
comun i obligatorie.
Un tip care conine o metod neinstaniabil trebuie s fie neinstaniabil. n exemplul anterior,
funcia suprafata din tipul neinstaniabil t_piesa este i ea neinstaniabil. Deci, definiiile corpurilor
tipurilor instaniabile t_piesa_rotunda i t_piesa_dreptunghiulara trebuie s conin o implementare
pentru aceast metod.
Exemplu:
S se defineasc o ierarhie cu tipul rdcin forma_geometrica i subtipurile dreptunghi i
cerc. Tipul printe este nefinal i neinstaniabil, iar subtipurile sale, dreptunghi i cerc, sunt finale.
CREATE TYPE forma_geometrica AS OBJECT (
tip VARCHAR2(20),
NOT INSTANTIABLE MEMBER FUNCTION aria RETURN NUMBER,
NOT INSTANTIABLE MEMBER FUNCTION perimetru RETURN NUMBER)
Orientare pe obiecte n Oracle9i 61

NOT INSTANTIABLE
NOT FINAL;
/
CREATE TYPE dreptunghi UNDER forma_geometrica (
lung NUMBER,
lat NUMBER,
OVERRIDING MEMBER FUNCTION aria RETURN NUMBER,
OVERRIDING MEMBER FUNCTION perimetru RETURN NUMBER);
/
CREATE TYPE BODY dreptunghi AS
OVERRIDING MEMBER FUNCTION aria RETURN NUMBER IS
BEGIN
RETURN SELF.lung * SELF.lat;
END;
OVERRIDING MEMBER FUNCTION perimetru RETURN NUMBER IS
BEGIN
RETURN 2 * (SELF.lung + SELF.lat);
END;
END;
/
SELECT dreptunghi('PATRULATER',20, 10).aria()
FROM DUAL;
CREATE TYPE cerc UNDER forma_geometrica (
raza NUMBER,
OVERRIDING MEMBER FUNCTION aria RETURN NUMBER,
OVERRIDING MEMBER FUNCTION perimetru RETURN NUMBER);
/
CREATE OR REPLACE TYPE BODY cerc AS
OVERRIDING MEMBER FUNCTION aria RETURN NUMBER IS
pi NUMBER := 3.1415;
BEGIN
RETURN SELF.raza * SELF.raza * pi;
END;
OVERRIDING MEMBER FUNCTION perimetru RETURN NUMBER IS
pi NUMBER := 3.1415;
BEGIN
RETURN 2 * SELF.raza * pi;
END;
END;
/
SELECT cerc('CIRCULARA',10).perimetru()
FROM dual;
Dac un subtip nu asigur o rescriere instaniabil pentru fiecare metod neinstaniabil
motenit, subtipul trebuie n mod obligatoriu s fie neinstaniabil. Un subtip instaniabil poate fi
extins dintr-un supertip neinstaniabil, dar nu invers.
Comanda ALTER TYPE permite modificarea unui tip din instaniabil n neinstaniabil, i
reciproc. De exemplu, urmtoarea comand modific tipul t_exemplu s fie instaniabil:
ALTER TYPE t_exemplu INSTANTIABLE;
Un tip instaniabil poate fi modificat astfel nct s fie neinstaniabil doar dac nu exist nici o
coloan, vizualizare, tabel sau instan obiect care s l refere n mod direct sau indirect prin
intermediul unui tip sau subtip dependent (practic, dac nu s-a definit nici o instan a lui).
62 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Nerespectarea aceastei reguli determin apariia erorii ORA-22327: cannot change a type to NOT
INSTANTIABLE if it has dependent tables.
Nu este permis definirea de tipuri neinstaniabile finale, deoarece acestea nu pot fi folosite
ulterior (sistemul returneaz eroarea de compilare PLS-00614: creating a FINAL NOT
INSTANTIABLE type).

Motenirea, suprancrcarea i suprascrierea metodelor


Un subtip motenete automat toate metodele supertipului su (declarate sau motenite). El
poate redefini (suprascrie) metodele motenite i poate aduga metode noi. Astfel, un tip poate
conine mai multe metode cu acelai nume, dar cu signaturi diferite. n acest caz, compilatorul
utilizeaz signaturile metodelor pentru a le deosebi la momentul rulrii.
Signatura unei metode este un fel de profil structural. Ea const din numele metodei, tipurile
i ordinea parametrilor formali ai metodei (inclusiv parametrul implicit SELF). Metodele unui tip care
au acelai nume i signaturi diferite se numesc suprancrcate.
Dotarea unui tip cu mai multe metode (declarate sau motenite) avnd acelai nume este
denumit suprancrcare (overloading). Suprancrcarea este util atunci cnd trebuie s se asigure
mai multe implementri ale aceluiai comportament.
Exemplu:
Subtipul t_subtip creeaz o suprancrcare pentru procedura(). De remarcat c subtipul
conine ambele versiuni ale procedurii. n funcie de tipul parametrului se apeleaz procedura
corespunztoare.
CREATE TYPE t_tip AS OBJECT (
a NUMBER,
MEMBER PROCEDURE procedura(x DATE))
NOT FINAL;
/
CREATE OR REPLACE TYPE BODY t_tip AS
MEMBER PROCEDURE procedura(x DATE) IS
BEGIN
DBMS_OUTPUT.PUT_LINE (SELF.a || TO_CHAR(x, 'ddmmyyyy'));
END procedura;
END;
/
CREATE TYPE t_subtip UNDER t_tip (
MEMBER PROCEDURE procedura(x VARCHAR2));
/
CREATE OR REPLACE TYPE BODY t_subtip AS
MEMBER PROCEDURE procedura(x varchar2) IS
BEGIN
DBMS_OUTPUT.PUT_LINE (SELF.a || x);
END;
END;
/
SET SERVEROUTPUT ON
DECLARE
v t_tip := t_tip (1);
w t_subtip := t_subtip (2);
Orientare pe obiecte n Oracle9i 63

BEGIN
v.procedura (SYSDATE);
--v_procedura ('text'); --incorect, genereaza eroare
w.procedura (SYSDATE);
w.procedura ('text');
END;
/
Redefinirea unei metode motenite pentru a-i particulariza comportamentul ntr-un subtip se
numete suprascriere (overriding). Pentru a semnala c o metod este suprascris, se utilizeaz
cuvntul cheie OVERRIDING n cadrul definiiei tipului i a corpului acestuia.
Exemplu:
Tipul forma_geometrica poate conine o metod afiseaza(). Aceasta va fi suprancrcat n
cadrul subtipului dreptunghi astfel nct s primeasc i s afieze un parametru de tip ir de caractere,
p_notatie. Se va adauga noua metod n cadrul tipului forma_geometrica, i se va da o implementare
fr parametri i apoi va fi suprancrcat n subtipul dreptunghi. n final, se prezint o modalitate de
testare.
ALTER TYPE forma_geometrica
ADD MEMBER PROCEDURE afiseaza
CASCADE;
CREATE TYPE BODY forma_geometrica AS
MEMBER PROCEDURE afiseaza IS
BEGIN
DBMS_OUTPUT.PUT_LINE (' Forma geometrica de tip: '
|| SELF.tip);
END;
END;
/
ALTER TYPE dreptunghi
ADD MEMBER PROCEDURE afiseaza(p_notatie VARCHAR2);
CREATE OR REPLACE TYPE BODY dreptunghi AS
OVERRIDING MEMBER FUNCTION aria RETURN NUMBER IS
BEGIN
RETURN SELF.lung * SELF.lat;
END;
OVERRIDING MEMBER FUNCTION perimetru RETURN NUMBER IS
BEGIN
RETURN 2 * (SELF.lung + SELF.lat);
END;
-- pana aici nimic schimbat
MEMBER PROCEDURE afiseaza(p_notatie VARCHAR2) IS
BEGIN
SELF.afiseaza();
DBMS_OUTPUT.PUT_LINE('Notatia:' || p_notatie);
DBMS_OUTPUT.PUT_LINE('*********');
DBMS_OUTPUT.PUT_LINE('* *');
DBMS_OUTPUT.PUT_LINE('*********');
END;
END;
/
DECLARE
64 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

v_dreptunghi dreptunghi := dreptunghi('PATRULATER', 20, 10);


BEGIN
DBMS_OUTPUT.PUT_LINE('*Metoda ''afiseaza'' din supertip.*');
v_dreptunghi.afiseaza;
DBMS_OUTPUT.PUT_LINE('*Metoda ''afiseaza'' din subtip...*');
v_dreptunghi.afiseaza('ABCD');
END;
/
Suprascrierea redefinete o metod motenit pentru a-i modifica aciunea n subtip. De
exemplu, un subtip patrat (derivat din supertipul dreptunghi) ar putea suprascrie metoda aria() pentru
a particulariza calculul specific al ariei. Dac un subtip suprascrie o metod i o instan a subtipului
invoc acea metod, atunci se execut versiunea local a acesteia. De asemenea, dac subtipul are alte
subtipuri, atunci acestea motenesc metoda suprascris i nu versiunea original.
Este posibil ca un supertip s conin suprancrcri ale unei metode care este suprascris n
cadrul unui subtip. Deoarece suprancrcrile metodei au acelai nume, compilatorul utilizeaz
signatura metodei din subtip pentru a identifica versiunea din supertip care este suprascris. Cu alte
cuvinte, pentru a suprascrie o metod trebuie s i se pstreze signatura, care o identific n mod unic
n cadrul tipului obiect.
n exemplul urmtor, subtipul semnaleaz c suprascrie metoda fr parametrii afiseaza().
Declaraiile complete ale metodelor suprascrise trebuie s fie incluse n comanda CREATE TYPE
BODY.
CREATE TYPE t_tip AS OBJECT (,
MEMBER PROCEDURE afiseaza(),
MEMBER PROCEDURE afiseaza(p_titlu VARCHAR2))
NOT FINAL;
CREATE TYPE t_SubTip UNDER t_Tip ( ,
OVERRIDING MEMBER PROCEDURE afiseaza());
Restriciile la suprascrierea metodelor sunt urmtoarele:
se pot suprascrie doar metode care nu sunt declarate finale n supertip;
metodele de ordonare (de tip ORDER) pot aprea doar n tipul rdcin al unei ierarhii de
tipuri (ele nu pot fi suprascrise n subtipuri);
o metod static nu poate redefini o metod MEMBER din supertip;
o metod MEMBER nu poate redefini o metod static din supertip;
o metod care furnizeaz valori implicite pentru anumii parametri, trebuie s asigure
aceleai valori implicite pentru aceiai parametri n cadrul subtipului care o suprascrie.

Legarea dinamic a metodelor


Ca rezultat al suprascrierii metodelor, o ierarhie de tipuri poate defini mai multe implementri
pentru aceeai metod. De exemplu, ntr-o ierarhie de tipuri corespunztoare formelor geometrice,
fiecare dintre tipuri trebuie s defineasc n mod diferit metoda de calcul a ariei.
Pentru a determina care dintre implementrile unei metode suprascrise va fi folosit, se
analizeaz tipul instanei obiect ce invoc metoda. Decizia este luat la momentul rulrii i nu n
timpul compilrii. De aceea, aceast modalitate de alegere a metodei invocate se numete legare
dinamic (dynamic method dispatch).
Apelul metodei se face conform cu cea mai apropiat implementare, cutnd n definiia
tipului specificat i apoi pe nivelurile superioare din cadrul ierarhiei de tipuri. Deci, dac apelul
Orientare pe obiecte n Oracle9i 65

invoc o metod MEMBER a unei instane obiect sau o metod static a unui tip, atunci este utilizat
implementarea definit sau motenit de acel tip.
De exemplu, dac inst este o instan obiect a unui tip (tip) extins din alt tip (tip_super) i care
are un subtip (tip_sub), atunci apelul inst.met() caut mai nti o implementare a metodei met()
definit n tipul tip. Dac aceasta nu exist, caut pe nivelul superior, deci n supertip. Faptul c
tip_sub definete i el o implementare nu este relevant deoarece ierarhia tipurilor este parcurs de jos
n sus, ctre nivelurile superioare. Subtipurile tipului curent nu prezint interes n acest caz. n mod
similar, un apel ctre o metod static tip.met_stat() declaneaz cutarea mai nti n tip i apoi, dac
mai este necesar, n supertipurile lui tip. Subtipul tip_sub nu este parcurs.

Substituirea tipurilor n ierarhia de tipuri


ntr-o ierarhie de tipuri, subtipurile reprezint diferite variante ale tipului rdcin. De
exemplu, tipurile t_artist i t_autor definite anterior sunt variante ale tipului t_persoana. Tipul de
baz include subtipurile, n sensul c orice autor sau artist este o persoan.
Dac se lucreaz cu o ierarhie de tipuri, atunci sunt necesare mecanisme pentru a face
referin la diferite niveluri de specializare, fie la cel mai general nivel (de exemplu, s se selecteze
sau s se modifice toate persoanele), fie la niveluri particulare (de exemplu, s se selecteze sau
modifice doar autorii sau doar persoanele care nu sunt autori).
Proprietatea de polimorfism permite selectarea tuturor obiectelor de un anumit tip (de
exemplu t_persoana) i obinerea att a obiectelor de tipul respectiv (t_persoana), ct i a obiectelor
al cror tip declarat este un subtip al acestui tip (t_artist, t_autor sau t_jurnalist). Aceast proprietate
se numete substituibilitate. Dac un supertip este substituibil, atunci variabilele, coloanele i
atributele de acel tip pot conine att obiecte de tipul respectiv, ct i instane obiect corespunztoare
subtipurilor acestuia.
Supertipurile sunt substituibile deoarece un subtip este doar o variant specializat a
supertipurilor sale (directe sau indirecte). Din punct de vedere formal, un subtip este un tip de sine
stttor. De aceea, o coloan care conine informaii despre toate persoanele, inclusiv despre cele care
nu sunt autori sau artiti, de fapt stocheaz date de mai multe tipuri.
Substituibilitatea se aplic la atribute, coloane i linii obiect (din vizualizri sau tabele obiect),
colecii sau referine ctre obiecte. Atributele obiectelor, elementele coleciilor i referinele sunt
ntotdeauna substituibile. Dac t este un tip obiect, atunci:
un atribut substituibil de tip referin ctre un obiect de tip t poate conine referine att
ctre o instan a tipului t, ct i ctre o instan a unui subtip al tipului t;
un atribut de tipul t poate conine att instane obiect de tip t, ct i instane ale unui
subtip al tipului t;
o colecie de elemente de tip t poate conine att instane obiect de tip t, ct i instane ale
oricrui subtip corespunztor tipului t.
Nu exist o sintax la nivelul definiiei tipului pentru a constrnge substituibilitatea unui
anume subtip. Exist posibilitatea de a activa sau dezactiva substituibilitatea la nivel de stocare pentru
anumite coloane sau tabele obiect.
Exemplu:
S se defineasc tipul t_sursa n care atributul autor s fie substituibil.
CREATE TYPE t_sursa AS OBJECT (
titlu VARCHAR2(30),
autor t_persoana /* substituibil */);
66 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

/
O instan a tipului t_sursa conine titlul i autorul, care este de tip t_persoana sau de orice alt
subtip al tipului t_persoana. Urmtorul exemplu specific un autor de tip t_artist:
SELECT t_sursa('Noa Noa',
t_artist(12345, 'Gaugain', 123, '1839', '1906', 'franceza'))
FROM dual;
Coloanele i liniile obiect sunt n mod implicit substituibile. Cu alte cuvinte, o coloan sau
linie de tip obiect t poate conine instane ale tipului t sau ale oricruia dintre subtipurile sale.
Exemplu:
Se consider ierarhia t_persoana cu subtipurile t_autor i t_artist. Tipul t_autor are la rndul
lui un subtip t_jurnalist. Un tabel obiect de tip t_persoana poate conine linii de tip t_persoana sau de
unul dintre subtipurile acestuia. Pentru a introduce un autor de un tip dat se utilizeaz, n clauza
VALUES a comenzii INSERT, constructorul specific tipului respectiv.
CREATE TABLE tab_persoane OF t_persoana;
INSERT INTO tab_persoane
VALUES (t_persoana (15, 'Georgescu'));
INSERT INTO tab_persoane
VALUES (t_autor (25, 'Irving Stone', 125, 'scriitor', NULL));
INSERT INTO tab_persoane
VALUES (t_jurnalist (35, 'Simona Popescu', 135, 'jurnalist',
NULL, 'redactor', 'Dilema'));
n mod similar se lucreaz ntr-un tabel sau vizualizare relaional pentru o coloan
subtituibil de tip t_persoana. Urmtorul exemplu insereaz n tabelul relaional tab_surse informaii
despre o persoan, un autor i un jurnalist.
CREATE TABLE tab_surse OF t_sursa;
INSERT INTO tab_surse
VALUES('Cronica de azi', t_persoana(15, 'Georgescu'));
INSERT INTO tab_surse
VALUES('Agonie si extaz', t_autor (25, 'Irving Stone', 125,
'scriitor', NULL));
INSERT INTO tab_surse
VALUES('Expozitii', t_jurnalist (35, 'Simona Popescu', 135,
'jurnalist', NULL, 'redactor', 'Dilema'));
n general, atributele pot fi accesate utiliznd notaia cu punct. n cazul atributelor unui subtip
al tipului declarat, se utilizeaz funcia TREAT.
Exemplu:
ntr-o vizualizare obiect viz_surse de tip t_sursa (n care coloana autor conine instane ale
oricrui tip din ierarhia cu rdcina t_persoana), se poate utiliza funcia TREAT mpreun cu
predicatul IS OF TYPE (ONLY) pentru a afia titlurile tuturor crilor i informaiile legate numai de
autorii de tip t_artist.
INSERT INTO tab_surse
VALUES ('Noa Noa', t_artist(12345, 'Gaugain', 123, '1839',
'1906', 'franceza'));
CREATE VIEW viz_surse OF t_sursa
AS SELECT * FROM tab_surse;
Orientare pe obiecte n Oracle9i 67

SELECT TREAT(autor AS t_artist), titlu


FROM viz_surse
WHERE autor IS OF TYPE (ONLY t_artist);
Un subtip poate fi stocat n orice tabel sau coloan substituibil asociat supertipurilor sale
directe sau indirecte, att n cele care exist deja la momentul definirii lui, ct i n cele care urmeaz
a fi create. De asemenea, exist posibilitatea ca un subtip s aib un atribut de tipul supertipului din
care a fost extins. Se creeaz astfel o referin ncruciat care complic mecanismele de tratare a
obiectelor.
Exemplu:
S se adauge tipului t_autor un nou atribut, impresar, de tip t_persoana.
ALTER TYPE t_autor
ADD ATTRIBUTE impresar t_persoana CASCADE;
Coloanele avnd un tip care i refer supertipul nu sunt substituibile, iar tipul respectiv nu
poate fi utilizat pentru tabele obiect. Din aceast cauz, comanda anterioar funcioneaz doar dup
tergerea tabelelor tab_persoane i tab_surse. n caz contrar, apare eroarea ORA-30756: cannot
create column or table of type that contains a supertype attribute.
n mod similar, un subtip st poate avea un atribut de tip colecie ale crui elemente sunt de
unul dintre supertipurile subtipului st. Nici coloanele de acest tip nu sunt substituibile. De exemplu,
dac t_autor conine un tabel imbricat sau un vector de elemente de tip t_persoana, atunci o coloan
de tip t_autor nu va fi substituibil. n schimb, se pot defini coloane substituibile corespunztoare
subtipurilor care au atribute de tip referin ctre supertipurile lor.
Coloanele i atributele de tip referin sunt substituibile att n tabele, ct i n vizualizri. De
exemplu, ntr-o vizualizare sau un tabel, o coloan de tip referin ctre tipul t_persoana poate conine
referine ctre instane obiect de acest tip sau de oricare dintre subtipurile sale.
Elementele coleciilor sunt i ele subtituibile att n tabele, ct i n cadrul vizualizrilor. De
exemplu, un tablou imbricat de obiecte de tip t_persoana poate conine instane obiect de tip
t_persoana sau de oricare dintre subtipurile sale.
Substituibilitatea unei coloane, a unui atribut specific unui tip i a unei colecii imbricate la
orice nivel, se poate dezactiva cu ajutorul clauzei NOT SUBSTITUTABLE AT ALL LEVELS.
Exemplu:
S se defineasc un tabel relaional catalog, similar tabelului tab_surse. Coloana autor trebuie
s stocheze doar instane de tip t_persoana i s nu permit instane ale subtipurilor acestui tip.
CREATE TABLE catalog (
sursa VARCHAR2(20),
autor t_persoana,
pret NUMBER)
COLUMN autor NOT SUBSTITUTABLE AT ALL LEVELS;
n cazul tabelelor obiect, clauza poate fi aplicat ntregului tabel.
CREATE TABLE tab_surse_persoane OF t_sursa
NOT SUBSTITUTABLE AT ALL LEVELS;
S se defineasc tabelul curente, specificnd c elementele obiectuale ale coleciei artisti nu
sunt substituibile.
68 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

CREATE TYPE t_lista_artisti AS TABLE OF t_artist;


/
CREATE TABLE curente (
nume VARCHAR2(10),
artisti t_lista_artisti)
NESTED TABLE artisti NOT SUBSTITUTABLE AT ALL LEVELS
STORE AS ts_artisti;
Observaii:
Nu exist nici un mecanism pentru dezactivarea substituibilitii coloanelor referin.
Clauza de substituibilitate nu poate fi aplicat unui atribut al unui tip obiect.
O coloan trebuie s fie pe nivelul cel mai nalt din ierarhie pentru a i se putea aplica
opiunea NOT SUBSTITUTABLE AT ALL LEVELS.
Se poate impune o constrngere care s limiteze domeniul tipurilor permise ntr-o coloan sau
atribut obiect, la un singur subtip din ierarhia de tipuri asociat. Acest lucru se face utiliznd o
constrngere de tip IS OF i cuvntul cheie ONLY.
Pentru o coloan obiect se poate utiliza att constngerea IS OF, ct i NOT
SUBSTITUTABLE AT ALL LEVELS, dar nu ambele.
Exemplu:
S se creeze un tabel de tip t_sursa n care autorii trebuie s fie de tip t_autor. Chiar dac
tipul t_sursa permite autori de tip t_persoana, declararea coloanei impune numai stocarea instanelor
obiect de tip t_autor.
CREATE TABLE surse_bibliografice OF t_sursa
COLUMN autor IS OF (ONLY t_autor);
Regulile de atribuire dintre tipuri se aplic n cadrul comenzilor INSERT, UPDATE, clauzei
RETURNING, parametrilor funciilor i variabilelor PL/SQL.
Aa cum s-a observat, substituibilitatea este proprietatea unui subtip de a nlocui pe unul
dintre supertipurile lui ntr-un context dat. La o ncercare de a executa o substituie n alt direcie
(substituirea unui subtip cu un supertip al su) apare o eroare de compilare.
Cnd se atribuie n mod direct unei coloane sau variabile de tip tip_tinta o valoare obiect de
tip tip_sursa, trebuie ndeplinit una dintre situaiile urmtoare:
tip_sursa i tip_tinta s aib acelai tip;
tip_sursa s fie un subtip al tipului tip_tinta.
Cel de-al doilea caz definete procesul de lrgire (widening), o atribuire n care tipul declarat
al sursei este mai specific dect tipul declarat al intei. De exemplu, acest proces este ntlnit atunci
cnd i se atribuie unei variabile de tip t_persoana o instan de tip t_artist.
Intuitiv, un artist poate fi privit ca fiind o persoan. Tipul t_artist este un tip t_persoana
definit mai strict, astfel nct s se poat stoca informaii specifice unui artist acolo unde se ateapt
informaii despre o persoan. Procesul de lrgire este utilizat atunci cnd atributele suplimentare dintr-
un subtip nu sunt constrnse s fie diferite de null.
De exemplu, atribuirea unei valori de tip t_artist unei variabile de tip t_persoana se poate
face doar dac atributele cod_artist, an_nastere, an_moarte i nationalitate pot fi null. Toi artitii
sunt persoane, astfel nct asocierea prin lrgire va funciona ntotdeauna corect.
Orientare pe obiecte n Oracle9i 69

Exemplu:
Pentru a ilustra atribuirea prin lrgire, se consider urmtorul tabel.
CREATE TABLE tabel(
perscol t_persoana,
artcol t_artist,
autcol t_autor);
INSERT INTO tabel (perscol, artcol, autcol)
VALUES (t_persoana (15, 'Georgescu'),
t_artist (20, 'Peter Breugel', 11, '1457', NULL, NULL),
t_autor (25, 'Irving Stone', 125, 'scriitor', NULL));
Urmtorul exemplu folosete atribuirea prin lrgire. Instruciunile sunt valide doar dac
perscol este substituibil.
n SQL:
UPDATE tabel
SET perscol = artcol;
n PL/SQL:
DECLARE
var1 t_persoana;
var2 t_artist;
BEGIN
var1 := var2;
END;
/
Dac este necesar o substituire n sensul invers celui obinuit (o valoare de un anumit tip s
fie considerat de un supertip al tipului declarat), atunci se poate utiliza procesul reciproc, de lrgire
(narrowing). Acesta implic tratarea unui obiect de un tip mai general (de exemplu, t_persoana), ca
fiind de un tip specializat (de exemplu, t_artist). Nu toate persoanele sunt artiti, astfel nct o
atribuire n care tipul variabilei int este t_artist i tipul obiectului surs este t_persoana funcioneaz
doar dac obiectul respectiv este de tip t_artist.
Pentru a face o atribuire prin limitare, trebuie utilizat funcia TREAT care convertete n mod
explicit valorea surs la tipul specializat al variabilei sau coloanei int. Funcia TREAT verific dac
schimbarea poate fi fcut, la momentul execuiei, dup care fie realizeaz conversia i returneaz o
expresie de tipul specificat n opiunea AS, fie returneaz valoarea null dac valoarea surs nu este de
tipul int sau de un subtip al acestuia.
Exemplu:
S se atribuie coloanei perscol de tip t_persoana valorile coloanei artcol de tip t_artist.
Pentru fiecare valoare din coloana perscol, atribuirea se face cu succes doar dac persoana respectiv
este artist. n caz contrar, funcia TREAT returneaz valoarea null.
UPDATE tabel
SET artcol = TREAT (perscol AS t_artist);
Urmtoarea comand ncearc s fac o atribuire prin limitare fr a schimba n mod explicit
tipul valorii surs, ceea ce nu este permis. Comanda va determina apariia erorii ORA-00932:
inconsistent datatypes: expected STUDENT.T_ARTIST got STUDENT.T_PERSOANA.
UPDATE tabel
SET artcol = perscol;
n atribuirile expresiilor de tip colecie, tipul elementelor corespunztoare tipului surs i inta
70 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

trebuie s fie acelai. La nivel de colecie, nu sunt permise nici atribuiri prin lrgire i nici prin
limitare. Evident ns, c atribuirile de la nivelul elementelor unei colecii respect regulile de
substituibilitate prezentate anterior.
Exemplu:
S se creeze dou tipuri tablou imbricat cu elemente de tip t_persoana, respectiv t_autor.
Atribuirea dintre dou expresii colecie de tipuri diferite nu este permis, dar se poate realiza
substituirea la nivel de element (elem2 este utilizat n constructorul tipului colecie t_lista_persoane,
realizndu-se n acest fel la nivel de element, un proces de lrgire).
CREATE TYPE t_lista_persoane AS
TABLE OF t_persoana;
/
CREATE TYPE t_lista_autori AS
TABLE OF t_autor;
/
DECLARE
var1 t_lista_persoane;
var2 t_lista_autori;
elem1 t_persoana;
elem2 t_autor;
BEGIN
--var1 := var2; /*NEPERMIS - colectiile nu au acelasi tip */
var1 := t_lista_persoane (elem1, elem2);
/*PERMIS - elem2 este de un subtip al tipului declarat */
END;
/

Comparaiile ntr-o ierarhie de tipuri


Dou instane obiect pot fi comparate doar dac au acelai tip sau una are subtipul celeilalte.
Pentru aceasta sunt folosite metodele de tip MAP i ORDER, care asigur mecanismul de comparare a
obiectelor. Dac se definete o metod de comparare, ea este apelat n mod automat atunci cnd
obiecte de acel tip sau de subtipuri ale acestuia trebuie s fie comparate.
De asemenea, dou variabile referin pot fi comparate doar dac valorile obiectuale ale
acestora sunt de acelai tip sau dac una are un subtip al celeilalte.
Nu exist nici un mecanism pentru compararea coleciilor luate unitar.
Exemplu:
S se defineasc o metod de comparare de tip MAP pentru obiectele de tip t_persoana. S se
selecteze din tabelul tab_surse titlurile surselor bibliografice, codurile i numele persoanelor care le-
au publicat. Rezultatul trebuie s apar n ordinea dat de metoda MAP definit n cadrul tipului.
ALTER TYPE t_persoana
ADD MAP MEMBER FUNCTION map_cod RETURN NUMBER
CASCADE;
CREATE OR REPLACE TYPE BODY t_persoana IS
MAP MEMBER FUNCTION map_cod RETURN NUMBER IS
BEGIN
RETURN SELF.cod;
END map_cod;
Orientare pe obiecte n Oracle9i 71

END;
/
SELECT titlu, s.autor.cod, s.autor.nume
FROM tab_surse s
ORDER BY autor.map_cod();
72 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

4. Gestiunea obiectelor n Oracle

Odat cu apariia caracteristicilor obiectuale, a fost necesar i introducerea unor mijloace de


prelucrare a acestora. Acest capitol prezint extensiile SQL i PL/SQL pentru lucrul cu obiecte,
respectiv cteva dintre modalitile specifice de implementare a tehnicilor de stocare i prelucrare, cu
referire la datele obiectuale.

4.1. Modificarea dinamic a tipurilor


Modificarea dinamic a structurii sau a comportamentului unui tip definit de utilizator este o
caracteristic nou a versiunii Oracle9i i se numete type evolution. Sunt permise urmtoarele
schimbri:
adugarea sau eliminarea de atribute i metode;
modificarea tipului de date al unui atribut prin mrirea lungimii, a preciziei sau a
domeniului;
schimbarea proprietilor FINAL sau INSTANTIABLE ale tipului.
Modificrile unui tip afecteaz toate obiectele care sunt n relaie cu el. De exemplu, dac se
adaug un atribut unui tip obiect, datele din coloanele de acel tip trebuie s fie afiate astfel nct s
includ noul atribut.
Obiectele dependente de un tip sunt acele obiecte ale schemei care refer n mod direct sau
indirect tipul respectiv. Ele trebuie s reflecte orice schimbare a acestuia i pot fi: tabele, tipuri sau
subtipuri, blocuri PL/SQL stocate (proceduri, funcii, pachete sau declanatori), tipuri index,
vizualizri, indeci bazai pe funcii, operatori definii de utilizator etc.
Modalitatea n care un obiect dependent este afectat de o schimbare a tipului de care depinde
difer n funcie de natura schimbrii. Atunci cnd un tip este modificat, toate obiectele dependente
sunt marcate invalide. Urmtoarea referire a unui obiect invalidat duce la recompilarea acestuia,
utiliznd noua definiie a tipului modificat. Dac obiectul este recompilat cu succes, atunci el devine
valid i poate fi folosit. n funcie de schimbarea fcut asupra tipului, indecii bazai pe funcii pot fi
eliminai sau dezafectai i trebuie reconstruii.
Modificrile de structur ale tipurilor se execut rapid pentru c determin doar schimbarea
metadatelor corespunztoare tabelelor dependente.
Ulterior trebuie actualizate datele din tabele, conform noului format. Deoarece modificarea
datelor poate fi consumatoare de timp, versiunea Oracle9i prevede, n cadrul comenzii ALTER
TABLE, opiuni care permit utilizatorului s aleag ntre convertirea datelor din tabelele dependente la
momentul schimbrii tipului sau ulterior, pe msur ce acestea sunt accesate sau modificate.
Chiar dac datele sunt stocate n formatul vechi, la fiecare consultare sistemul face conversia
ctre cel mai recent format. Modul de stocare nu este actualizat pn la actualizarea sau conversia
explicit a datelor respective.
Definiia cea mai recent a unui tip poate fi obinut din vizualizarea USER_SOURCE, iar
definiiile tuturor versiunilor unui tip pot fi selectate din USER_TYPE_VERSIONS. De asemenea,
pentru a afla toate obiectele schemei care depind de un anumit tip, se consult vizualizarea
USER_DEPENDECIES.
Orientare pe obiecte n Oracle9i 73

Exemplu:
a) S se listeze numele, tipul i tipul dependenei pentru obiectele schemei care depind de
tipul t_artist.
SELECT NAME, TYPE, REFERENCED_NAME, DEPENDENCY_TYPE
FROM USER_DEPENDENCIES
WHERE UPPER(REFERENCED_NAME) = 'T_ARTIST';
b) S se afieze pentru fiecare tip definit de utilizator numele acestuia i numrul de versiuni
definite pn la momentul curent.
SELECT TYPE_NAME, COUNT(DISTINCT VERSION#)
FROM USER_TYPE_VERSIONS
GROUP BY TYPE_NAME;

Comanda ALTER TYPE


Pentru modificarea structurii sau comportamentului unui tip definit de utilizator se folosete
comanda ALTER TYPE. De asemenea, aceast comand LDD permite recompilarea specificaiei sau a
corpului tipului respectiv i schimbarea anumitor proprieti (FINAL, INSTANTIABLE).
Pentru iniierea unei astfel de comenzi, tipul obiect trebuie s fie definit n propria schem i
utilizatorul s aib privilegiile sistem CREATE TYPE sau CREATE ANY TYPE. Dac tipul de
modificat nu se afl n schema curent, utilizatorul trebuie s dein i privilegiul ALTER ANY TYPE.
Sintaxa simplificat a comenzii ALTER TYPE este:
ALTER TYPE [schema.]nume_tip
{ COMPILE [DEBUG] [ {SPECIFICATION | BODY} ]
[REUSE SETTINGS]
| REPLACE [ {AUTH CURRENT_USER | DEFINER} ]
AS OBJECT (atribut tip_de_date [, atribut tip_de_date]
metoda_spec [, metoda_spec] )
| { {ADD | DROP} metoda_spec [, metoda_spec]
| { {ADD | MODIFY} ATTRIBUTE {atribut [tip_de_date]
| (atribut tip_de_date [, atribut tip_de_date] ) }
| DROP ATTRIBUTE {atribut | (atribut [, atribut] ) }
| [NOT] {INSTANTIABLE | FINAL} }
[ { INVALIDATE
| CASCADE [ { [NOT] INCLUDING TABLE DATA
| CONVERT TO SUBSTITUTABLE} ]
[ [FORCE] EXCEPTIONS INTO [schema.]tabel} ] }
Pentru a valida n mod explicit un tip, se utilizeaz clauza COMPILE, care determin
compilarea specificaiei sau corpului tipului. n mod implicit, sunt compilate ambele, dar este posibil
compilarea doar a corpului (BODY) sau a specificaiei (SPECIFICATION) pentru tipul respectiv. La
recompilare, sistemul elimin setrile compilatorului, le ncarc pe cele din sesiunea curent i, la
finalul compilrii, revine la parametrii iniiali. Pentru a evita acest proces, care poate fi ineficient, se
precizeaz clauza REUSE SETTINGS.
Un tip este compilat cu succes dac toate tipurile de care depinde sunt valide i dependenele
sunt satisfcute. Dac din recompilarea unui tip rezult erori, acesta rmne invalid. Toate programele
PL/SQL care conin variabile definite cu atributul %ROWTYPE relativ la un tabel obiect sau %TYPE
74 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

relativ la o coloan, respectiv atribut de tip obiect, sunt recompilate pe baza ultimei versiuni a tipului.
Dac revalidarea eueaz, atunci i compilarea blocului PL/SQL eueaz.
Clauza DEBUG se folosete pentru a impune compilatorului PL/SQL s genereze i s
stocheze codul n vederea utilizrii lui de ctre depanatorul PL/SQL.
Clauza REPLACE AS OBJECT permite adugarea de noi specificaii pentru atribute i
metode. Se poate redefini ntreg tipul obiect n mod similar unei comenzi CREATE TYPE. Aceast
clauz este valid doar pentru tipurile obiect, nu i pentru tipurile colecii.
n aceeai comand ALTER TYPE se pot aduga, terge sau modifica mai multe atribute sau
metode, dar fiecare atribut sau metod poate aprea o singur dat. n cazul adugrii sau tergerii
unei metode, sistemul dezafecteaz orice index bazat pe funcii care depinde de acel tip. Adugarea de
metode sau atribute nu trebuie s intre n conflict cu cele deja existente n ierarhia de tipuri.
O metod motenit nu poate fi tears dintr-un subtip, ea trebuie eliminat direct din
supertipul care o definete sau o suprascrie. Dac metoda eliminat nu este suprascris n subtipuri,
eliminarea ei se realizeaz utiliznd opiunea CASCADE i determin tergerea metodei att din tipul
int ct i din toate subtipurile acestuia.
Dac o metod este suprascris n cadrul subtipurilor, atunci operaia de tergere a acesteia
eueaz, iar comanda de modificare este anulat. Pentru ca operaia de eliminare cu propagare a
schimbrilor s se execute cu succes, este necesar ca mai nti s fie eliminate toate suprascrierile
metodei din subtipuri i abia apoi, s fie eliminat metoda din tipul care o definete.
Clauza ADD ATTRIBUTE permite adugarea unui nou atribut. Numele atributului trebuie s
nu intre n conflict cu atributele sau metodele ierarhiei din care face parte tipul modificat. Sistemul
adaug noul atribut la sfritul listei de atribute definite local. Dac se adaug un atribut unui supertip,
atunci acesta este motenit de toate subtipurile sale. n subtipuri, atributele motenite preced
ntotdeauna atributele declarate. Deci, n urma unei operaii de adugare a unor atribute asupra unui
tip care deine subtipuri, este posibil s fie necesar actualizarea unor operaii asociate subtipurilor (de
exemplu, se pot modifica apelurile constructorilor asociai acestora).
Dac se elimin un atribut prin intermediul clauzei DROP ATTRIBUTE, atunci sistemul
Oracle suprim coloana corespunztoare atributului, toi indecii, statisticile i constrngerile
(inclusiv cele de integritate referenial) care fac referire la atributul respectiv.
Restriciile cu privire la eliminarea atributelor presupun c:
nu se poate elimina un atribut motenit de la un supertip (el trebuie ters din supertip i n
acest fel, n urm propagrii schimbrilor, va fi eliminat i din subtip);
nu se poate elimina un atribut care face parte dintr-o cheie de partiionare, subpartiionare
sau din cheia unei grupri;
nu este permis eliminarea unui atribut care face parte dintr-un identificator obiect bazat
pe cheia primar a unui tabel obiect sau dintr-o cheie primar a unui tabel organizat pe
baz de index;
nu se pot terge toate atributele unui tip rdcin, ci trebuie ters tipul n ntregime (se pot
terge ns, toate atributele definite local ale unui subtip pentru c acesta tip motenete
toate atributele de la supertipul su i deci numrul de atribute nu se reduce la zero).
Modificarea tipului de date al unui atribut scalar existent se face folosind clauza MODIFY
ATTRIBUTE. De exemplu, se poate mri lungimea unui atribut de tip VARCHAR2 sau precizia i
domeniul unui atribut numeric. Nu se poate mri dimensiunea unui atribut referit ntr-un index bazat
pe funcie, index de domeniu sau cheie a unei grupri.
Exemplu:
Orientare pe obiecte n Oracle9i 75

Tipul t_persoana conine atributele cod de tip NUMBER i nume de tip VARCHAR2(50). S
se adauge un atribut corespunztor codului numeric personal (cnp) i altul referitor la nlime
(inaltime). S se elimine atributul cod i s se mreasc dimensiunea numelui pn la 60 de caractere.
ALTER TYPE t_persoana
ADD ATTRIBUTE (cnp VARCHAR2(13)),
DROP ATTRIBUTE cod,
ADD ATTRIBUTE inaltime NUMBER(3,2),
MODIFY ATTRIBUTE nume VARCHAR2(60)
CASCADE;
Urmtoarea comand ALTER TYPE, care face mai multe modificri aceluiai atribut, este
incorect i returneaz eroarea PLS-00716: Attribute/method 'CULOARE_OCHI' can occur only
once in an ALTER TYPE statement.
ALTER TYPE t_persoana
ADD ATTRIBUTE (greutate INTEGER, culoare_ochi VARCHAR2(15)),
DROP ATTRIBUTE culoare_ochi
CASCADE;
Dac se schimb proprietatea FINAL a unui tip, atunci este obligatorie clauza de dependen
CASCADE pentru a determina convertirea datelor din toate coloanele i tabelele dependente. n acest
caz, nu este permis amnarea conversiei datelor cu opiunea NOT INCLUDING TABLE DATA.
Evident c un tip care are deja subtipuri definite nu poate fi schimbat din NOT FINAL n FINAL.
Dac se face modificarea proprietii FINAL n NOT FINAL, acest lucru necesit conversia
obiectelor schemei care sunt dependente de tipul respectiv. n acest caz i n eventualitatea crerii de
subtipuri instaniabile, coloanele i tabelele obiect necesit o nou coloan care s stocheze
identificatorul de tip.
La iniierea unei astfel de comenzi pot aprea dou situaii.
Dac trebuie s fie create noi tabele i coloane substituibile de tipul respectiv, dar datele
dependente deja existente nu trebuie s fie substituibile, atunci se specific clauza
CASCADE INCLUDING TABLE DATA. Sistemul marcheaz toate coloanele i tabelele
dependente NOT SUBSTITUTABLE AT ALL LEVELS, astfel nct nu se vor putea insera
instane ale viitoarelor subtipuri asociate tipului modificat, n coloanele sau tabelele
existente la momentul schimbrii.
Dac schimbarea trebuie s fie reflectat de toate coloanele i tabelele dependente (att
cele existente la momentul modificrii ct i cele viitoare), atunci se utilizeaz clauza
CASCADE CONVERT TO SUBSTITUTABLE. Sistemul marcheaz toate coloanele i
tabelele existente cu SUBSTITUTABLE AT ALL LEVELS, cu excepia celor care sunt
marcate explicit nesubstituibile.
Proprietatea unui tip de a fi instaniabil indic dac pot fi construite instane ale tipului
respectiv. Evident c nu se poate schimba un tip obiect din INSTANTIABLE n NOT INSTANTIABLE
dac exist deja instane de acel tip.
Comportamentul implicit al unei comenzi ALTER TYPE fr clauze pentru dependen
(CASCADE, INVALIDATE) este de a verifica dac exist vreun obiect dependent. Dac exist astfel
de obiecte comanda este abandonat cu eroarea ORA-22312: must specify either CASCADE or
INVALIDATE option.
76 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Clauzele pentru dependen instruiesc sistemul n legtur cu modalitatea de prelucrare a


obiectelor dependente. Ele sunt obligatorii atunci cnd tipul int are tipuri sau tabele dependente i
permit schimbrile n cascad (CASCADE) sau invalidarea (INVALIDATE) obiectelor dependente.
Spre deosebire de CASCADE, opiunea INVALIDATE permite sistemului s execute
modificrile specificate n comanda ALTER TYPE fr un mecanism prealabil de verificare i de
propagare a schimbrilor ctre obiectele dependente.
Aceast opiune este mai rapid dect CASCADE, dar este mai riscant, deoarece pot aprea
probleme la revalidarea tipurilor i a tabelelor dependente. Obiectele invalidate sunt recompilate la
momentul urmtorului acces. Acest lucru este deosebit de important, pentru c datele dintr-un tabel
invalid nu mai pot fi accesate.
De exemplu, n cazul eliminrii unei metode care este suprascris, subtipurile dependente vor
rmne n stare invalid pn cnd sunt modificate n mod explicit i eliminate suprascrierile invalide.
Pn atunci, orice ncercare de recompilare pentru validare va eua. De asemenea, validarea unui tabel
poate eua din cauza adugrii automate a unui atribut la un tip dependent, care determin depirea
numrului maxim de coloane dintr-un tabel, sau din cauza eliminrii unui atribut folosit n cheia de
partiionare sau drept cheie a unei grupri.
Clauza CASCADE determin propagarea schimbrii ctre toate tipurile i tabelele dependente.
Dac nu este specificat cuvntul cheie FORCE i apar erori la validarea obiectelor dependente, atunci
comanda eueaz.
Pentru a converti ctre noua versiune de format toate datele dependente de tipul modificat ce
sunt stocate n baza de date, se utilizeaz clauza INCLUDING TABLE DATA. Aceasta este opiunea
implicit10. Dac tipul are tabele dependente, atunci pentru fiecare atribut adugat sunt create n cadrul
acestor tabele una sau mai multe coloane interne iniializate cu valoarea null. Similar, pentru fiecare
atribut suprimat sunt eliminate coloanele asociate acestuia. La modificarea tipului de date al unui
atribut, lungimea, precizia sau domeniul coloanei asociate sunt schimbate n consecin. Dac se
utilizeaz aceast clauz, atunci toate spaiile tabel ce conin datele tabelelor afectate trebuie s fie n
mod citire/scriere.
Dac se specifc NOT INCLUDING TABLE DATA, atunci sistemul Oracle actualizeaz doar
metadatele asociate coloanei pentru a reflecta schimbrile tipului, dar nu modific datele dependente.
Totui, coloanele dependente rmn accesibile i cererile ulterioare reflect modificrile tipului.
Clauza FORCE se specific dac sistemul trebuie s ignore erorile generate de procesul de
propagare a schimbrilor i s execute comanda chiar dac nu sunt ndeplinite toate condiiile de
validare ale obiectelor dependente. Este posibil nregistrarea erorilor prute, n tabelul de excepii
specificat prin intermediul clauzei EXCEPTIONS INTO. Acest tabel trebuie s existe deja n schema
curent. El poate fi creat utiliznd procedura CREATE_ALTER_TYPE_ERROR_TABLE din pachetul
predefinit DBMS_UTILITY.
Exemplu:
Se presupune c tipul t_persoana conine atributele nume, prenume i varsta. S se modifice
acest tip prin adugarea unui atribut data_nasterii i eliminarea atributului varsta. Modificarea trebuie
s se fac doar cu propagarea schimbrilor structurale, urmnd ca datele s fie convertite ulterior. De
asemenea, eventualele erori de la modificarea tipului trebuie nregistrate n tabelul de erori e.
DROP TYPE t_persoana FORCE;
DROP TABLE tab_persoane FORCE;

10
Clauza este obligatorie dac datele coloan sunt n formatul imagine Oracle8 sau schimbarea ce se face asupra tipului este
de la FINAL la NOT FINAL.
Orientare pe obiecte n Oracle9i 77

CREATE OR REPLACE TYPE t_persoana AS OBJECT (


prenume VARCHAR(30),
nume VARCHAR(30),
varsta NUMBER(3));
/
CREATE TABLE tab_persoane OF t_persoana;
INSERT INTO tab_persoane
VALUES (t_persoana('Ion', 'Ionescu', 50));
SELECT VALUE(p)
FROM tab_persoane p;
EXEC DBMS_UTILITY.CREATE_ALTER_TYPE_ERROR_TABLE('STUDENT','E');
ALTER TYPE t_persoana
ADD ATTRIBUTE (data_nasterii DATE),
DROP ATTRIBUTE varsta
CASCADE NOT INCLUDING TABLE DATA
FORCE EXCEPTIONS INTO E;
SELECT *
FROM tab_persoane;
n urma comenzii ALTER TYPE datele din tabelul tab_persoane nu sunt convertite, i totui
sistemul le returneaz conform ultimei versiuni de format. Noul atribut adugat este iniializat cu
valoarea null.
O comand SELECT nu determin conversia fizic a datelor rezultate, ctre cel mai recent
format, chiar dac acestea ntrunesc condiiile necesare pentru a fi convertite. De aceea, dac aceste
date sunt accesate frecvent, este preferabil s se permanentizeze conversia. Astfel, se evit conversiile
repetate, redundante i consumatoare de timp (n cazul datelor de tip vector, atunci cnd procesul de
conversie este ndelungat, permanentizarea este obligatorie).
Datele dependente sunt afectate doar de modificrile structurale care pot fi fcute asupra unui
tip. De exemplu, schimbrile care se limiteaz la implementarea unei metode deja existente a tipului
nu afecteaz datele dependente.
Schimbrile structurale ale unui tip sunt urmtoarele:
adugarea sau eliminarea unui atribut;
modificarea lungimii, preciziei sau domeniului unui atribut;
schimbarea clauzei FINAL a tipului.
Aceste schimbri duc la noi versiuni ale tipului modificat i ale tipurilor dependente i
necesit adugarea, eliminarea sau modificarea coloanelor interne ale tabelelor dependente, n timpul
procesului de convertire ctre noua versiune.
Atunci cnd sunt fcute schimbri structurale asupra unui tip care are obiecte dependente,
efectele propagrii nu se limiteaz doar la metadate, ci afecteaz i configuraia stocrii datelor. Exist
mai multe ci de conversie a datelor dependente:
pe msura reactualizrii datelor;
la modificarea tipului, pentru anumite coloane sau tabele dependente;
la modificarea tipului, pentru toate datele dependente.
De asemenea, operaia de modificare dinamic a unui tip determin i alte schimbri ce
trebuie prevzute i tratate. De exemplu, dac se adaug un nou atribut unui tip, atunci fiecare apel al
78 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

constructorului trebuie modificat astfel nct s specifice o valoare pentru acel atribut. Dac se adaug
o nou metod, atunci corpul tipului trebuie nlocuit i adugat o implementare pentru acea metod
(utiliznd comanda CREATE OR REPLACE TYPE BODY). Nu este disponibil o comand ALTER
TYPE BODY pentru modificarea corpului unui tip.

Opiunile comenzii ALTER TABLE pentru modificarea tipurilor


n cadrul procesului de modificare dinamic a unui tip avnd tabele dependente este util i
comanda ALTER TABLE. Aceasta prevede opiuni pentru convertirea datelor ctre cel mai recent
format al tipurilor referite. n acest context, sintaxa simplificat a comenzii este urmtoarea:
ALTER TABLE [schema.]nume_tabel
{UPGRADE [ [NOT] INCLUDING DATA]
| DROP UNUSED COLUMNS
| clauz_stocare_coloan}
Clauza UPGRADE permite conversia metadatelor unui tabel astfel nct acestea s se
conformeze cu cele mai recente versiuni ale tipurilor referite. Dac tabelul este deja valid, atunci
metadatele corespunztoare rmn neschimbate.
Opiunea INCLUDING DATA este similar cu cea din comanda ALTER TYPE i determin
conversia datelor stocate n coloanele de tip definit de utilizator ctre cele mai recente versiuni de
tipuri. Aceast opiune este implicit.
Versiunea negat a opiunii las datele coloanelor n formatul curent. De exemplu, dac un
atribut este eliminat dintr-un tip referit de un tabel, atunci coloanele corespunztoare atributului
suprimat nu sunt eliminate din tabel. Sunt actualizate doar metadatele referitoare la coloana
respectiv, astfel nct s reflecte faptul c atributul respectiv nu mai este folosit. Dac atributul
eliminat este stocat n afara nregistrrii (out-of-line) cum este de exemplu, un atribut de tip colecie
sau LOB, atunci datele corespunztoare atributului respectiv nu sunt eliminate.
Folosind aceast opiune, se poate accelera viteza actualizrii metadatelor referitoare la tabel
n momentul modificrii tipului. n schimb, selectarea informaiilor va necesita de fiecare dat
conversia datelor stocate n coloane, ctre cel mai recent format. Acest lucru poate afecta
performanele unor interogri succesive asupra tabelelor dependente. Pentru a elimina coloanele
nefolosite se utilizeaz clauza DROP UNUSED COLUMNS.
Opiunea NOT INCLUDING DATA este obligatorie atunci cnd tabelele sunt foarte mari i
capacitatea segmentelor de revenire este prea mic pentru a realiza conversia tuturor datelor ntr-o
singur tranzacie. Cum aceast opiune presupune doar modificarea metadatelor tabelului, nu este
necesar ca toate spaiile tabel asociate s fie disponibile n mod citire/scriere. n acest caz, conversia
datelor din fiecare tabel dependent poate fi fcut n tranzacii separate, la un moment ulterior,
utiliznd clauza UPGRADE INCLUDING DATA.
O alt modalitate de convertire a datelor este doar propagarea schimbrilor n metadatele
asociate tabelelor dependente fr convertirea datelor. n acest caz, propagarea schimbrilor la nivel
de date poate fi realizat treptat, pentru fiecare coloan. Conversia este declanat n mod automat de
ctre sistem, atunci cnd se face o comand UPDATE asupra datelor tabelului, caz n care nu se mai
poate amna convertirea acestora ctre cea mai recent versiune de format.
Dac un tabel este imposibil de convertit ctre cel mai recent format al tipului pe care l
refer, atunci nu mai sunt permise comenzi LMD asupra tabelului i datele lui devin inaccesibile.
Aceasta presupune c, pn la validarea tabelului, sunt permise doar comenzile DROP TABLE sau
TRUNCATE TABLE.
Orientare pe obiecte n Oracle9i 79

Utiliznd vizualizarea USER_TAB_COLUMNS din dicionarul datelor se poate determina care


dintre tabele conine date bazate pe un format neactualizat. Coloana DATA_UPGRADED returneaz
valorile YES sau NO dup cum datele au fost convertite sau nu. Pentru coloanele unde nu se pune
problema unei conversii a datelor (de exemplu, cele scalare) este returnat valoarea N/A.
Exemplu:
a) S se modifice tipul t_persoana prin adugarea unui nou atribut de tip BLOB care s
stocheze fotografia persoanei. S se actualizeze i tabelul dependent tab_persoane. Diferena dintre
cele dou metode este c prima realizeaz conversia la nivel de tabel, iar cea de-a doua doar pentru
coloana foto.
ALTER TYPE t_persoana
ADD ATTRIBUTE (foto BLOB)
CASCADE NOT INCLUDING TABLE DATA;
Metoda 1:
ALTER TABLE tab_persoane UPGRADE INCLUDING DATA;
Metoda 2:
UPDATE tab_persoane
SET foto = foto;
b) n urma modificrii tipului t_persoana, s se verifice pentru tabelele dependente
tab_persoane i tab_surse dac datele sunt actualizate la noul format. Se observ c pentru coloanele
tabelului tab_persoane conversia este fcut, pentru coloana autor din tab_surse nu este fcut, iar
pentru coloana titlu nu este cazul.
SELECT TABLE_NAME, COLUMN_NAME, DATA_UPGRADED
FROM USER_TAB_COLUMNS
WHERE UPPER (TABLE_NAME) IN ('TAB_PERSOANE', 'TAB_SURSE');
n cadrul unei comenzi ALTER TABLE pot fi specificate clauze de stocare pentru noile
atribute de tip colecie sau LOB. Acestea sunt similare celor prezentate n seciunea despre definirea
tabelelor obiect.

Algoritm pentru modificarea unui tip obiect


Sintetiznd, pentru a modifica un tip obiect trebuie urmai urmtorii pai:
1) Se execut comanda ALTER TYPE pentru modificarea tipului.
2) Se utilizeaz comanda CREATE OR REPLACE TYPE BODY pentru a sincroniza corpul
tipului cu noua definiie a acestuia.
3) Se actualizeaz datele din tabelele dependente n conformitate cu ultima versiune de tip,
utiliznd opiunile din comanda ALTER TABLE sau comenzi LMD asupra datelor ce trebuie
convertite.
4) Se modific unitile de program PL/SQL dependente, astfel nct acestea s ia n
considerare schimbrile aduse tipului.
5) Se utilizeaz opional Oracle Type Translator sau JPublisher pentru a genera noile fiiere
header pentru aplicaii, dac limbajul extern folosit de aplicaii este C, respectiv Java. Aceste utilitare
pot automatiza operaia de actualizare a aplicaiei n urma schimbrilor asupra tipurilor de la nivelul
bazei de date.
80 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

4.2. Eliminarea tipurilor obiect


Pentru suprimarea unui tip definit de utilizator este disponibil instruciunea DROP TYPE.
Utilizatorul care iniiaz aceast comand trebuie s fie proprietarul tipului sau s aib privilegiul
sistem DROP ANY TYPE.
Sintaxa comenzii este:
DROP TYPE [schema.]nume_tip [ {FORCE | VALIDATE} ]
Dac nu se precizeaz numele schemei, atunci sistemul presupune c tipul ce va fi eliminat se
afl n propria schem. Opiunile FORCE sau VALIDATE sunt obligatorii pentru eliminarea tipurilor
care au obiecte dependente.
Clauza FORCE este specificat dac se dorete eliminarea unui tip dei exist obiecte ale
bazei care sunt dependente de acesta. n acest caz, sistemul marcheaz invalide toate tipurile,
coloanele sau tabelele dependente de tipul eliminat, acestea devenind inaccesibile pn la revalidare.
Prin urmare, opiunea FORCE trebuie utilizat cu atenie. O comanda DROP TYPE nu poate fi
anulat.
Atunci cnd este specificat clauza FORCE, sistemul Oracle mai nti disociaz toate
obiectele asociate cu tipul respectiv i apoi elimin tipul. De exemplu, este cunoscut c tipul rdcin
al unei ierarhii nu poate fi eliminat dect dup ce sunt terse toate tabelele i subtipurile care l refer.
Prin urmare, dac se specific FORCE, sistemul invalideaz toate subtipurile asociate tipului
suprimat.
Dac se precizeaz clauza VALIDATE, sistemul caut instanele stocate n cadrul coloanelor
substituibile avnd tipul respectiv i subtipuri ale acestuia. Dac nu este gsit nici o astfel de instan,
sistemul duce la bun sfrit comanda propagnd schimbarea ctre toate coloanele substituibile de tipul
respectiv. Din cauz c invalidarea unui tabel poate duce la pierderea datelor stocate n acesta, se
recomand utilizarea opiunii VALIDATE la tergerea oricrui tip.
Un subtip este o versiune specializat a supertipului su direct i, prin urmare, ntre cele dou
tipuri exist o dependen explicit. Pentru a evita ruperea legturii dintre subtipuri i supertipurile
corespunztoare, un supertip nu poate fi eliminat dect dac mai nti sunt suprimate toate subtipurile
sale.
Exemplu:
S se elimine tipul t_persoana fr a utiliza opiunea FORCE. Tipul t_persoana este tipul
rdcin al ierarhiei ce conine tipurile t_artist, t_autor i t_jurnalist. De asemenea, acest tip este
utilizat n cadrul tabelului tab_persoane i tab_surse.
-- mai intai tabelele dependente
DROP TABLE tab_surse;
DROP TABLE tab_persoane;
-- tipurile incepand de la subtipuri pana la tipul radacina
DROP TYPE t_jurnalist;
DROP TYPE t_autor;
DROP TYPE t_artist;
--eliminarea tipului t_persoana
DROP TYPE t_persoana;
Orientare pe obiecte n Oracle9i 81

4.3. Dependene i tipuri incomplete


Tipurile obiect pot fi n relaie, n sensul c se folosesc unul pe cellalt n cadrul definiiei lor.
De exemplu, poate fi necesar ca tipul t_artist s conin un atribut de tip colecie (cu elemente de tip
t_opera_de_arta) care s indice operele de art create de fiecare artist, iar tipul t_opera_de_arta s
conin un atribut de tip t_artist care s indice artistul care a creat opera respectiv.
Tipurile pot fi dependente n mod direct sau indirect, prin intermediul tipurilor intermediare,
numite mutual dependente. Un graf orientat de tipuri mutual dependente n care tipurile sunt noduri i
dependenele sunt reprezentate prin arce, conine ntotdeauna un circuit. Pentru a defini astfel de
dependene circulare, trebuie s fie utilizat tipul referin pe cel puin unul dintre segmentele
circuitului.
Exist dou metode de abordare pentru crearea a dou tipuri dependente (t_a i t_b) n mod
direct.
Prima metod presupune urmtorii pai:
crearea tipului t_a ca tip incomplet;
crearea tipului t_b, care refer tipul existent tip_a;
completarea definiiei tipului t_a (prin CREATE OR REPLACE TYPE).
Cea de-a doua metod ia n considerare faptul c, atunci cnd apar erori de compilare la
definirea unui tip, sistemul creeaz automat tipul ca fiind incomplet. Paii acestei metode sunt
urmtorii:
crearea tipului t_a (sistemul creeaz automat tipul t_a incomplet);
crearea tipului t_b, care refer tipul existent tip_a;
compilarea tipului t_a (prin ALTER TYPECOMPILE).
Exemplu:
Utiliznd cele dou metode prezentate anterior, s se defineasc tipuri ce modeleaz entitile
dependente artist i opera. Tipul t_opera_de_arta conine un atribut care face referin la un obiect de
tip t_artist, iar tipul t_artist are un atribut de tip colecie care conine pentru fiecare artist operele de
art asociate.
Metoda 1:
CREATE TYPE t_artist;
/
CREATE TYPE t_opera_de_arta AS OBJECT (
cod_opera NUMBER,
tip VARCHAR2(10),
titlu VARCHAR2(200),
artist REF t_artist,
data_crearii DATE,
data_achizitiei DATE,
valoare NUMBER);
/
CREATE TYPE t_opere_ti AS TABLE OF t_opera_de_arta;
/
CREATE TYPE t_artist AS OBJECT (
nume VARCHAR2(30),
prenume VARCHAR2(30),
82 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

anul_nasterii VARCHAR2(4),
anul_mortii VARCHAR2(4),
nationalitate VARCHAR2(40),
observatii VARCHAR2(2000),
opere t_opere_ti);
/
Metoda 2:
CREATE TYPE t_artist AS OBJECT (
nume VARCHAR2(30),
prenume VARCHAR2(30),
anul_nasterii VARCHAR2(4),
anul_mortii VARCHAR2(4),
nationalitate VARCHAR2(40),
observatii VARCHAR2(2000),
opere t_opere_ti);
/
CREATE TYPE t_opera_de_arta AS OBJECT (
cod_opera NUMBER,
tip VARCHAR2(10),
titlu VARCHAR2(200),
artist REF t_artist,
data_crearii DATE,
data_achizitiei DATE,
valoare NUMBER);
/
CREATE TYPE t_opere_ti AS TABLE OF t_opera_de_arta;
/
ALTER TYPE t_artist COMPILE;
Aceaste secvene de comenzi creeaz un set de tipuri mutual dependente.
Utiliznd prima metod, se observ c tipul t_artist este definit de dou ori. Prima comand
este o declaraie incomplet, necesar pentru definirea atributului de tip referin artist al tipului
t_opera_de_arta. Declaraia este incomplet pentru c se omite specificarea structurii i a
comportamentului. Acestea sunt specificate ulterior, n declaraia complet, tipul t_artist devenind
funcional. Declaraia incomplet asigur compilarea cu succes a tipului t_opera_de_arta.
Fr declararea tipului t_artist ca fiind tip incomplet, comanda de creare a tipului
t_opera_de_arta ar fi returnat erori de compilare. n metoda a doua, dei sistemul realizeaz operaia
de creare, din cauza erorilor de compilare tipul t_artist este marcat automat ca fiind tip obiect
incomplet. Existena acestui tip determin compilarea fr erori a tipurilor t_opere_ti i t_artist. Dup
crearea tipurilor complete ce l utilizeaz (t_opere_ti i, indirect, t_opera_de_arta), tipul t_artist este
recompilat fr erori i devine un tip complet.
Un tip incomplet poate fi definit n urmtoarele dou situaii:
n mod explicit de ctre utilizator, atunci cnd comanda de creare a tipului stabilete doar
un nume pentru tip, omind definirea structurii i comportamentului acestuia;
n mod implicit de ctre sistem, atunci cnd la crearea unui tip apar erori de compilare i
tipul este creat fr a i se asocia o structur i un comportament valid.
Pentru a completa un tip incomplet, se execut comanda CREATE TYPE n care se specific
Orientare pe obiecte n Oracle9i 83

atributele i metodele tipului. Completarea unui tip incomplet se face dup ce au fost create toate
tipurile care fac referire la el. Aceast operaie determin recompilarea lui i permite sistemului s
elibereze eventualele blocri. Dac la crearea unui tip, acesta refer tipuri care nu exist (nici mcar
declarate incomplet), atunci tipul este creat, dar cu erori de compilare (este afiat mesajul Warning:
Type created with compilation errors).
Tehnica tipurilor incomplete permite crearea de tipuri care conin atribute referin ctre un
subtip planificat, dar care nu a fost creat nc. Pentru aceasta, mai nti se creeaz subtipul ca tip
incomplet, urmnd s fie completat ulterior.
Odat ce un tip obiect este declarat incomplet, el trebuie s fie completat ulterior ca tip obiect.
Nu se poate, de exemplu, s fie declarat ulterior ca tip colecie. Singura alternativ, n eventualitatea
acestei necesiti, este eliminarea tipului i recrearea lui.
Dac un tip a fost creat cu erori de compilare i se ncearc executarea unei operaii asupra
lui, cum ar fi crearea de tabelele obiect sau instanierea unor obiecte de tipul respectiv, este posibil s
apar eroarea Recompile type <nume_tip> before attempting this operation. n acest caz tipul
trebuie s fie recompilat manual, prin intermediul unei comenzi ALTER TYPECOMPILE.
Un tabel sau o coloan substituibil de tip obiect este dependent nu numai de tipul su, ci i
de subtipurile acestuia. Pentru fiecare atribut adugat ntr-un subtip al unui tip care este utilizat ntr-un
tabel, se introduce cte o coloan ascuns. Aceste coloane ascunse sunt adugate chiar i atunci cnd
tabelul sau coloana substituibil nu conine date pentru acel subtip.
De exemplu, un tabel obiect substituibil de tip t_persoana este dependent nu numai de acest
tip, dar i de subtipurile asociate, t_autor, t_jurnalist sau t_artist.
Exemplu:
Se consider tipul t_autor i subtipul acestuia t_jurnalist. S se creeze tabelul obiect
substituibil tab_autori, care s nu conin obiecte de tip t_jurnalist. S se insereze o nregistrare de tip
t_autor i apoi s se elimine tipul t_jurnalist.
CREATE TABLE tab_autori OF t_autor;
INSERT INTO tab_autori
VALUES (t_autor(1,'Dan Mihailescu',10,'critic','literar'));
COMMIT;
--DROP TYPE t_jurnalist
--returneaza eroarea ORA-02303
DROP TYPE t_jurnalist VALIDATE;
Dac se ncearc tergerea unui subtip avnd obiecte dependente, atunci comanda DROP
TYPE returneaz eroarea ORA-02303: cannot drop or replace a type with type or table dependents
i nu se execut. De exemplu, ncercarea de a terge tipul t_autor va genera o eroare, deoarece acest
tip este dependent de tabelul tab_persoane i de tipul t_jurnalist.
Dac exist tabele sau coloane dependente, dar care nu conin date de tipul eliminat, se poate
folosi cuvntul cheie VALIDATE, care face ca sistemul s verifice instanele existente ale tipului
respectiv i s tearg tipul doar dac nu a gsit date dependente. n acest caz, coloanele ascunse
asociate cu atributele unice ale tipului ters sunt, la rndul lor, eliminate. Utilizarea opiunii
VALIDATE este recomandat mereu, att la modificarea, ct i la tergerea subtipurilor.
84 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

4.4. Privilegii asupra tipurilor obiect i a metodelor lor


Privilegiile referitoare la tipurile obiect pot fi definite la nivel de sistem sau de obiect al
schemei.
Privilegiile la nivel de sistem sunt urmtoarele:
CREATE TYPE, care permite crearea de tipuri obiect n cadrul propriei scheme;
CREATE ANY TYPE, ALTER ANY TYPE i DROP ANY TYPE, care permit crearea,
modificarea, respectiv suprimarea tipurilor obiect din orice schem;
EXECUTE ANY TYPE, care permite utilizarea i referirea tipurilor obiect din orice
schem;
UNDER ANY TYPE, care permite crearea de subtipuri ale tipurilor obiect nefinale din
orice schem;
UNDER ANY VIEW, care permite crearea de subvizualizri ale vizualizrilor obiect din
orice schem.
Role-urile CONNECT i RESOURCE includ privilegiul sistem CREATE TYPE. Role-ul DBA
include toate aceste privilegii.
Relativ la tipurile obiect, se pot utiliza dou privilegii la nivel de obiect (EXECUTE i
UNDER).
Privilegiul EXECUTE permite utilizarea tipului pentru definirea unui tabel obiect, a unei
coloane obiect ntr-un tabel relaional sau pentru declararea unei variabile sau parametru de tipul
respectiv, n cadrul propriei scheme. De asemenea, acest privilegiu permite invocarea metodelor
tipului. Execuia metodelor i permisiunile asociate acestora sunt similare cu cele create pentru
subprogramele PL/SQL stocate.
Privilegiul UNDER permite crearea de subtipuri sau subvizualizri ale tipurilor, respectiv ale
vizualizrilor, asupra crora trebuie s existe privilegii speciale deja acordate. Acest privilegiu poate fi
acordat asupra unei subvizualizri sau subtip doar dac utilizatorul sau role-ul cruia i se acord are
acelai privilegiu i asupra supertipului sau supervizualizrii, iar acesta a fost primit n mod direct, cu
opiunea WITH GRANT OPTION.
Opiunea WITH HIERARCHY OPTION, utilizat la acordarea unui privilegiu obiect asupra
unui tip sau unei vizualizri, permite acordarea automat a privilegiului respectiv asupra tuturor
subtipurilor, respectiv subvizualizrilor corespunztoare. De exemplu, n contextul unei ierarhii de
vizualizri, aceast opiune este util atunci cnd trebuie acordat privilegiului SELECT asupra unei
vizualizri i asupra tuturor subvizualizrilor acesteia.
Sunt necesare privilegii speciale pentru:
a defini tipuri i tabele care utilizeaz tipuri ce aparin altor utilizatori;
a acorda privilegiul de utilizare a tipurilor sau tabelelor proprii ctre ali utilizatori ai
bazei de date.
Pentru orice tip utilizat n definiia unui nou tip sau a unui tabel trebuie deinut privilegiul
sistem EXECUTE ANY TYPE sau privilegiul obiect EXECUTE.
Dac se intenioneaz s se acorde altor utilizatori acces ctre propriile tipuri sau tabele,
atunci este necesar fie privilegiul EXECUTE cu opiunea WITH GRANT OPTION, fie privilegiul
sistem EXECUTE ANY TYPE cu opiunea WITH ADMIN OPTION. Toate aceste privilegii trebuie s
fi fost primite n mod direct, i nu prin intermediul role-urilor.
Orientare pe obiecte n Oracle9i 85

Exemplu:
Se consider c utilizatorul student deine obiectele create pe parcursul acestui capitol. S se
creeze doi utilizatori (student1, student2) care dein role-urile CONNECT i RESOURCE.
CREATE USER student1 IDENTIFIED BY parola1;
GRANT RESOURCE TO student1;
GRANT CONNECT TO student1;
--.. ceilalalt utilizator se creeaza asemanator
CONNECT student/oracle@instantaBD;
Utilizatorul student acord urmtoarele privilegii obiect utilizatorului student1 asupra tipurilor
t_adresa i t_autor, definite anterior.
GRANT EXECUTE ON t_adresa TO student1;
GRANT EXECUTE ON t_autor TO student1 WITH GRANT OPTION;
Utilizatorul student1 execut urmtoarele comenzi LDD.
CONNECT student1/parola1@instantaBD;
CREATE TABLE tab_adrese OF student.t_adresa;
CREATE TYPE t_adrese_ti AS TABLE OF student.t_adresa;
/
CREATE TYPE t_lansare_de_carte AS OBJECT (
data DATE,
titlu VARCHAR2(20),
autor student.t_autor);
/
CREATE TABLE tab_autori OF student.t_autor;
De asemenea, student1 are posibilitatea de a acorda mai departe altor utilizatori privilegii
asupra obiectelor care folosesc tipul t_autor, deoarece are privilegiul EXECUTE asupra acestuia, cu
opiunea WITH GRANT OPTION. n schimb, asupra tipului t_adresa nu a fost acordat privilegiul cu
aceeai opiune. De aceea, asupra obiectelor care l utilizeaz nu se pot acorda privilegii altor
utilizatori n acest caz, sistemul returneaz eroarea ORA-01720: grant option does not exist for
'<nume_utilizator>.<nume_tip>'.
GRANT SELECT ON tab_autori TO student2;
GRANT EXECUTE ON t_lansare_de_carte TO student2;
-- Returneaza eroarea ORA-01720
GRANT EXECUTE ON t_adrese_ti TO student2;
GRANT SELECT ON tab_adrese TO student2;
Utilizatorul student2 poate executa cu succes comenzi care acceseaz i folosesc tipurile i
tabelele din schema student1.
CREATE TYPE t_carte AS OBJECT(
nume VARCHAR2(20),
domeniu VARCHAR2(10),
lansare student1.t_lansare_de_carte);
/
CREATE TABLE tab_carti OF t_carte;
Pentru accesul la tipuri obiect se utilizeaz doar privilegiile EXECUTE i UNDER, dar
tabelele obiect folosesc toate privilegiile de acces disponibile pentru tabelele relaionale.
Privilegiile referitoare la un tabel obiect sunt:
86 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

SELECT, care permite accesul la valorile atributelor pentru obiectele stocate n liniile
tabelului;
UPDATE, care permite modificarea atributelor obiectelor utilizate n cadrul tabelului;
INSERT, care permite adugarea de noi obiecte n tabel;
DELETE, care permite eliminarea de obiecte din tabel.
Privilegiile care coordoneaz accesul la coloanele obiect ale unui tabel sunt similare celor la
nivel de tabel. Operaia de selectare a anumitor coloane ale unui tabel obiect nu necesit privilegii
asupra tipurilor obiect utilizate n cadrul tabelului. n schimb, pentru selectarea unei ntregi linii obiect
trebuie privilegii de acces la structura tipului obiect referit (EXECUTE). Nu este permis definirea de
privilegii la nivel de coloan (respectiv, atribut) asupra tabelelor obiect.
Exemplu:
Se consider tipul t_artist definit anterior, care conine un atribut de tip tablou imbricat
(t_opere_ti), i tabelul obiect tab_artisti asociat. Interogrile care urmeaz se execut folosind un set
diferit de privilegii:
CREATE TABLE tab_artisti OF t_artist
NESTED TABLE opere STORE AS ts_opere;
INSERT INTO tab_artisti VALUES
('Rodin', 'Auguste', '1840', '1917', 'franceza', NULL, NULL);
SELECT VALUE(a)
FROM tab_artisti a;
SELECT nume||' '||prenume||
'('||anul_nasterii||'-'||anul_mortii||')'
FROM tab_artisti;
Pentru ambele cereri, sistemul verific existena privilegiului SELECT asupra tabelului
tab_artisti. n cadrul primei cereri, pentru a interpreta datele, utilizatorul trebuie s obin informaii
despre structura tipului. De aceea, atunci cnd cererea acceseaz tipul, sistemul verific i privilegiul
EXECUTE. Execuia celei de-a doua cereri, nu implic tipuri n mod explicit, aa c privilegiile
asupra tipului t_artist nu sunt verificate.
Exemplu:
Utiliznd schema din seciunea precedent, student2 poate executa urmtoarele cereri.
SELECT aut.cod_autor
FROM student1.tab_autori aut;
SELECT c.lansare.autor.nume
FROM tab_carti c;
n ambele interogri utilizatorul folosete tipuri asupra crora nu are privilegii explicite, dar
comenzile se execut cu succes pentru c proprietarii tipului (student) i tabelului (student1) dein
privilegiile necesare, iar acestea au fost acordate cu opiunea WITH GRANT OPTION.
Sistemul Oracle face verificri suplimentare i returneaz o eroare dac utilizatorul care
execut cererea nu deine privilegiile necesare, la executarea urmtoarelor operaii:
ncrcarea unui obiect n memoria virtual obiect ca urmare a accesrii unei valori de tip
referin (se verific privilegiul SELECT asupra tabelului obiect ce conine obiectul referit
i privilegiul EXECUTE asupra tipului obiect respectiv);
modificarea sau instanierea unui obiect ncrcat n memoria virtual (se verific
Orientare pe obiecte n Oracle9i 87

privilegiul UPDATE, iar, n cazul instanierii, privilegiul INSERT asupra tabelului obiect
destinaie);
tergerea unui obiect (se verific privilegiul DELETE asupra tabelului obiect sau
relaional destinaie);
invocarea unei metode (se verific privilegiul EXECUTE asupra tipurilor obiect ce conin
metoda).

4.5. Utilitare
Versiunea Oracle9i permite utilizarea mecanismelor obiectuale n cadrul utilitarelor de
import/export i pentru ncrcarea rapid a datelor prin SQL*Loader.
Utilitarele de import/export permit introducerea i extragerea datelor n, respectiv din bazele
de date Oracle. De asemenea, acestea sunt utile pentru crearea copiilor de siguran (backup) i
migrarea ntre diferitele versiuni ale server-ului de baze de date Oracle.
Au fost aduse mbuntiri astfel nct s fie acceptate datele de tip obiect. Componenta de
export scrie definiiile tipurilor obiect i toate datele asociate ntr-un fiier depozit cu extensia .dmp,
iar componenta de import poate crea modelul de date i informaiile exportate, utiliznd acest fiier.
n cazul tipurilor, se export i comenzile de definire ale subtipurilor, iar la import, un subtip
poate fi creat naintea importului definiiei supertipului su. n acest caz, subtipul va fi creat cu erori
de compilare. Acestea trebuie ignorate, tipul fiind revalidat dup crearea supertipului su. De
asemenea, definiiile vizualizrilor obiect ce aparin unei ierarhii de vizualizri pot fi i ele exportate.
Utilitarul SQL*Loader extrage date din fiiere externe pentru a le insera n tabelele unei baze
de date Oracle. Fiierele pot conine att date de tip scalar (CHAR, INTEGER, DATE, NUMBER), ct
i date complexe de tipuri definite de utilizator. Se pot ncrca linii sau coloane obiect (inclusiv
obiecte care au atribute de tip obiect, colecie sau referin), colecii i obiecte de tip LOB. n
versiunea Oracle9i, prin SQL*Loader pot fi ncrcate doar coleciile pe un singur nivel, nu i cele pe
mai multe niveluri.
SQL*Loader folosete fiiere de control (*.ctl), care conin comenzi speciale de definire a
datelor, pentru a descrie formatul i locaia fiierelor de date, tabelul n care se introduc datele
ncrcate i ali parametri ai procesului.
Exist dou abordri pentru ncrcarea datelor:
ncrcarea convenional, care utilizeaz comenzi INSERT i un vector tampon de
legtur pentru a transporta date n tabelele bazei de date;
ncrcarea direct, care utilizeaz Direct Path Load API pentru a scrie blocurile de date
direct n baza de date, pentru client-ul SQL*Loader.
ncrcarea direct nu folosete o interfa SQL i evit cuantumul de procesare suplimentar,
asociat comenzilor SQL. De aceea, ncrcarea direct tinde s asigure performane mai bune dect cea
convenional. Oricare dintre cele dou abordri se poate utiliza pentru a ncrca date de tip obiect sau
colecie.

4.6. Tipuri generice i tranzitorii


Sistemul Oracle asigur trei tipuri de date SQL generice care permit ncapsularea dinamic i
accesul la descrieri de tipuri, instane de date i seturi de instane de date ale altor tipuri SQL, inclusiv
88 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

tipuri obiect sau colecie. Aceste tipuri speciale pot fi utilizate pentru implementarea de tipuri
anonime. Tipurile generice aparin schemei SYS.
Cele trei tipuri generice SQL sunt implementate ca tipuri opace, adic structura lor intern nu
este cunoscut bazei de date. Datele de aceste tipuri pot fi interogate doar dac se implementeaz
funcii speciale (de obicei rutine LG3). n acest scop, sistemul Oracle furnizeaz funcii OCI i
PL/SQL.
Tipurile generice sunt urmtoarele:
ANYTYPE, care conine o descriere a unui tip SQL;
ANYDATA, care este un tip autodescriptiv pentru instanele tipurilor de date, coninnd
att date, ct i o descriere a fiecrui tip utilizat;
ANYDATASET, care este un tip autodescriptiv pentru seturi de instane i care include o
descriere a tipului mpreun cu un set de instane ale tipului respectiv.
Tipurile ANYDATA i ANYDATASET pot fi stocate persistent n cadrul bazei de date.
ANYTYPE, dei se refer la un tip stocat persistent n baza de date, este tranzitoriu, valoarea lui
nefiind stocat automat n baza de date.
Fiecare dintre aceste trei tipuri poate fi utilizat att cu tipurile predefinite, native ale bazei de
date, ct i cu tipurile obiect sau colecie (cu sau fr nume). Ele asigur un mod generic de a lucra
dinamic cu descrierile, instanele i seturile de instane ale diverselor tipuri. Utiliznd funciile API, se
poate crea o descriere ANYTYPE a oricrui tip. De asemenea, se poate converti (CAST) o valoare de
orice tip SQL ctre ANYDATA i reciproc. Similar se lucreaz cu tipul ANYDATASET.
Tipurile generice simplific lucrul cu procedurile stocate. Ele se pot utiliza pentru a ncapsula
descrieri i date de tipuri standard sau pentru a transmite informaia ncapsulat n parametri de tip
generic. n corpul procedurii se detaliaz modalitatea de abordare a datelor ncapsulate i a
descrierilor de tipuri.
De asemenea, ntr-o coloan de tip ANYDATA sau ANYDATASET se pot stoca date
ncapsulate, de o varietate de tipuri. De exemplu, se poate utiliza ANYDATA mpreun cu tehnologia
Oracle Advanced Queuing pentru a modela cozile de tipuri de date eterogene.
Pentru fiecare tip SQL generic exist un tip OCI corespunztor care l implementeaz i care
este prevzut cu un set de funcii pentru crearea i accesarea informaiilor de tipul respectiv. Tipurile
OCI sunt urmtoarele:
OCIType, corespunztor lui SYS.ANYTYPE;
OCIAnyData, corespunztor lui SYS.ANYDATA;
OCIAnyDataSet, corespunztor lui SYS.ANYDATASET.
Exist unele limbaje care utilizeaz tipuri de date ce pot fi modificate dinamic la momentul
rulrii programului sau permit programului s verifice tipul variabilei. De exemplu, limbajul C are
cuvntul cheie union i pointer-ul void *, Java are operatorul typeof i clase nfurtoare (wrapper)
pentru tipurile scalare. Versiunea Oracle9i permite crearea variabilelor i a coloanelor ce conin date
de orice tip. De asemenea, este posibil determinarea reprezentrii fizice a unor valori de tip generic.
Utiliznd aceste caracteristici, o coloan a unui tabel poate conine o valoare numeric ntr-o linie, un
ir de caractere sau un obiect n alta.
Pachetul predefinit DBMS_TYPES conine constante ce caracterizeaz tipurile predefinite i
cele definite de utilizator, necesare pentru lucrul cu ANYTYPE, ANYDATA i ANYDATASET. Aceste
constante au tipul PLS_INTEGER i sunt folosite pentru a indica tipul (predefinit sau definit de
utilizator) unei valori de tip ANYTYPE. Constantele sunt de forma TYPECODE_numetip, unde
Orientare pe obiecte n Oracle9i 89

numetip este tipul identificat i poate fi NUMBER, VARCHAR2, BLOB, REF, OBJECT, VARRAY,
TABLE etc.
Tipul ANYDATA permite reprezentarea valorilor de orice tip scalar sau obiect. Acest tip
generic este un tip obiect ce are ataate metode specifice care primesc o valoare scalar i o
convertesc la un scalar sau obiect. Similar, tipul predefinit ANYDATASET se poate utiliza pentru a
reprezenta valori de orice tip colecie. Pentru a prelucra i verifica informaii despre un tip, se poate
utiliza tipul predefinit ANYTYPE n combinaie cu pachetul DBMS_TYPES.
Principalele metode ale tipului generic ANYDATA sunt urmtoarele:
funciile metode statice de forma CONVERTnumetip, care au un parametru de intrare de
tip numetip i returneaz instana de tip SYS.ANYDATA asociat valorii parametrului;
metodele de tip GETnumetip, care au un parametru de ieire de tip numetip prin
intermediul cruia returneaz valoarea instanei de tip SYS.ANYDATA n formatul adecvat
(numetip poate fi un tip scalar sau definit de utilizator);
funcia metod GETTYPE, care are un parametru de ieire de tip SYS.ANYDATA prin
intermediul cruia se pot afla caracteristicile unui tip (precizia, scala unui numr,
lungimea unui ir de caractere etc.) i care returneaz o valoare ntreag corespunztoare
tipului instanei SYS.ANYDATA relativ la care se apeleaz (identificatorul returnat este
consistent constantelor din cadrul pachetului DBMS_TYPES);
metoda GETTYPENAME, care nu are parametri i care, aplicat unei instane ce
stocheaz o valoare obiectual, returneaz numele tipului obiect al valorii stocate.
Exemplu:
Se consider tipul t_persoana creat anterior, ce conine atributele cod i nume. Se definete un
tabel tab_generic cu dou coloane, cod de tip numeric i data de tip SYS.ANYDATA. S se
construiasc o procedur care parcurge tabelul i afieaz sugestiv datele stocate n coloana de tip
SYS.ANYDATA, interpretnd tipul de baz i procesnd valoarea corespunztor cu acest tip.
CREATE TABLE tab_generic (
cod NUMBER,
data SYS.ANYDATA);
INSERT INTO tab_generic VALUES
(1, SYS.ANYDATA.CONVERTnumber(10));
INSERT INTO tab_generic VALUES
(2, SYS.ANYDATA.CONVERTobject(t_persoana(99,'Dali')));
INSERT INTO tab_generic VALUES
(3, SYS.ANYDATA.CONVERTvarchar2('arta'));
COMMIT;
CREATE OR REPLACE PROCEDURE proc_generica IS
CURSOR c_generic IS
SELECT cod, data
FROM tab_generic;
v_cod tab_generic.cod%TYPE;
v_data tab_generic.data%TYPE;
v_tip SYS.ANYTYPE;
v_codtip PLS_INTEGER;
v_numetip VARCHAR2(60);
v_dummy PLS_INTEGER;
v_numar NUMBER;
v_varchar2 VARCHAR2(100);
90 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

v_persoana t_persoana;
anytype_nenul_pt_scalar EXCEPTION;
numetip_necunoscut EXCEPTION;
BEGIN
FOR v_rec IN c_generic LOOP
v_cod := v_rec.cod;
v_data := v_rec.data;
/* codul tipului este un numar care identifica
** tipul valorii lui v_data. */
v_codtip := v_data.GetType (v_tip);
/* v_codtip este comparat cu constantele din pachetul
** DBMS_TYPES pentru a determina tipul de date si
** a decide modalitatea de afisare */
CASE v_codtip
--daca este numeric..
WHEN DBMS_TYPES.TYPECODE_number THEN
IF v_tip IS NOT NULL THEN
-- tipul scalar trebuie sa returneze v_tip null
RAISE anytype_nenul_pt_scalar;
END IF;
v_dummy := v_data.GETnumber (v_numar);
DBMS_OUTPUT.PUT_LINE (TO_CHAR(v_cod) ||
': NUMBER = ' || TO_CHAR(v_numar));
--daca este sir de caractere..
WHEN DBMS_TYPES.TYPECODE_varchar2 THEN
IF v_tip IS NOT NULL THEN
-- tipul scalar trebuie sa returneze v_tip null
RAISE anytype_nenul_pt_scalar;
END IF;
v_dummy := v_data.GETvarchar2 (v_varchar2);
DBMS_OUTPUT.PUT_LINE (TO_CHAR(v_cod) ||
': VARCHAR2 = ' || v_varchar2);
--daca este de tip obiect..
WHEN DBMS_TYPES.TYPECODE_object THEN
v_numetip := v_data.GetTypeName();
--numele unui tip obiect este calificat cu numele
--schemei din care face parte
IF UPPER(v_numetip) != 'STUDENT.T_PERSOANA' THEN
--este alt tip?
RAISE numetip_necunoscut;
END IF;
v_dummy := v_data.GETobject (v_persoana);
DBMS_OUTPUT.PUT_LINE (TO_CHAR (v_cod) ||
': tip obiect = ' || v_numetip ||
' (' || v_persoana.cod || ', ' ||
v_persoana.nume || ')' );
END CASE;
END LOOP;
EXCEPTION
WHEN anytype_nenul_pt_scalar THEN
RAISE_Application_Error (-20001,
'Paradox: instanta de tip AnyType returnata de GetType '
||' trebuie sa fie NULL pentru toate tipurile scalare');
Orientare pe obiecte n Oracle9i 91

WHEN numetip_necunoscut THEN


RAISE_Application_Error (-20002, 'Tip necunoscut ' ||
v_numetip||'program valid pentru student.t_persoana');
END proc_generica;
/
SQL> SELECT t.data.gettypename() FROM tab_generic t;
T.DATA.GETTYPENAME()
--------------------------------------
SYS.NUMBER
STUDENT.T_PERSOANA
SYS.VARCHAR2
SQL> EXEC proc_generica;
1: NUMBER = 10
2: tip obiect = STUDENT.T_PERSOANA (99, Dali)
3: VARCHAR2 = arta

4.7. Stocarea obiectelor


Sistemul Oracle gestioneaz structura complex a tipurilor obiect n mod similar cu structura
simpl, relaional a tabelelor.
Un tip obiect poate fi reprezentat ca o structur arborescent n care nodurile reprezint
atribute. Atributele de tip obiect au, la rndul lor, noduri copil pentru propriile atribute. Fiecare
ramur se termin cu un atribut de tip scalar (VARCHAR2, NUMBER, REF) sau de tip colecie.
Atributele de pe nivelurile terminale ale tipului obiect original pot fi stocate ntr-o coloan a unui
tabel.
Atributele din cadrul unei ierarhii arborescente care se afl pe nivelurile finale i nu sunt de
tip colecie se numesc atribute scalare finale ale tipului obiect.
ntr-un tabel obiect, sistemul stocheaz informaia din fiecare atribut scalar final sau referin
n cte o coloan separat. De asemenea, fiecare vector este stocat ntr-o coloan, dac nu depete
limita de 4000 octei. Atributele finale de tip tablou imbricat sunt stocate n tabele separate, asociate
cu tabelul obiect care le conine. Aceste tabele trebuie s fie declarate la definirea tabelului obiect
(clauza NESTED TABLE din comanda CREATE TABLE).
Atunci cnd se consult sau se modific atributele obiectelor dintr-un tabel obiect, sistemul
execut automat operaiile asupra coloanelor corespunztoare ale tabelului. La accesarea unei instane
obiect, sistemul aduce o copie a acestuia n memoria client. Acest lucru este realizat prin invocarea
constructorului implicit al tipului respectiv, n care se utilizeaz coloanele tabelului obiect ca
argumente.
Dac un tabel are o coloan de tip obiect, atunci pentru fiecare dintre atributele finale ale
tipului este adaugat cte o coloan ascuns tabelului. De asemenea, fiecare coloan obiect are
asociat o coloan ascuns care stocheaz informaia null pentru aceasta, adic valorile null atomice
ale obiectelor de pe primul nivel i ale celor imbricate.
O coloan sau un tabel obiect substituibil are asociate coloane ascunse nu numai pentru
fiecare atribut al tipului obiect declarat, dar i pentru fiecare atribut definit n cadrul subtipurilor
acestuia. Aceste coloane stocheaz valorile atributelor referitoare la instanele subtipurilor inserate.
92 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

De exemplu, o coloan substituibil t_persoana va avea asociat cte o coloan ascuns


pentru fiecare atribut al tipului t_persoana (cod i nume) i pentru fiecare atribut din subtipuri
(cod_artist, nationalitate, an_nastere i an_moarte ale subtipului t_artist; cod_autor, ocupatie i
descriere pentru t_autor; functie i loc_munca ale subtipului t_jurnalist).
Atunci cnd este creat un subtip, coloanele ascunse asociate atributelor definite de subtipuri
sunt adugate automat n toate tabelele ce conin coloane substituibile de tipul printe al noului
subtip. Aceast operaie permite stocarea valorilor corepsunztoare atributelor din subtipul creat.
Dac, din diferite motive, coloanele nu pot fi adugate, crearea subtipului eueaz.
Dac pentru eliminarea unui subtip se utilizeaz opiunea VALIDATE a comenzii DROP
TYPE, toate coloanele ascunse asociate atributelor unice ale subtipului sunt eliminate automat, dac
nu conin date.
n contextul substituibil furnizat de o ierarhie de tipuri, cel mai specific tip al unei instane
obiect este tipul cel mai deprtat de rdcin cruia i aparine instana respectiv. De exemplu, un
obiect de tip t_jurnalist poate fi considerat de tip t_autor sau t_persoana, dar cel mai specific tip este
t_jurnalist.
Fiecare coloan substituibil are asociat n cadrul aceluiai tabel o coloan ascuns special
care furnizeaz informaii referitoare la cel mai specific tip al fiecrui obiect stocat n cadrul tabelului.
Aceasta se numete coloan discriminant, iar valorile ei se numesc identificatori de tip (typeid) i
identific cel mai specific tip al obiectului stocat n linia respectiv. Un identificator de tip ocup un
octet, dar poate ajunge pn la 4 octei dac ierarhia are multe elemente.
Identificatorul de tip al unei instane obiect poate fi obinut utiliznd funcia SYS_TYPEID.
Exemplu:
Se consider tabelul obiect substituibil tab_persoane cu elemente de tip t_persoana. S se
selecteze identificatorii de tip corespunztori obiectelor stocate n tabel.
CREATE TABLE tab_persoane OF t_persoana;
INSERT INTO tab_persoane
VALUES (t_persoana (15, 'Georgescu'));
INSERT INTO tab_persoane
VALUES (t_autor (25, 'Irving Stone', 125, 'scriitor', NULL));
INSERT INTO tab_persoane
VALUES (t_jurnalist (35, 'Simona Popescu', 135, 'jurnalist',
NULL, 'redactor', 'Dilema'));
SELECT nume, SYS_TYPEID(VALUE(p)) "Identificator de tip"
FROM tab_persoane p;
NUME Identificator de tip
-------------- --------------------
Georgescu 01
Irving Stone 03
Simona Popescu 04
Vizualizarea USER_TYPES din dicionarul datelor are o coloan denumit TYPEID care
conine valoarea identificatorului pentru fiecare tip.
Exemplu:
S se selecteze numele persoanelor i numele celui mai specific tip al instanei
corespunztoare stocate n tabelul tab_persoane.
SELECT p.nume, ut.TYPE_NAME
FROM tab_persoane p, USER_TYPES ut
Orientare pe obiecte n Oracle9i 93

WHERE SYS_TYPEID(VALUE(p)) = ut.TYPEID


AND TYPE_NAME IN
('T_PERSOANA', 'T_ARTIST', 'T_AUTOR', 'T_JURNALIST');
Fiecare linie obiect dintr-un tabel obiect trebuie s aib un identificator logic asociat (OID),
care s fie unic. Identificatorii obiect pot fi generai de sistem sau bazai pe o cheie primar existent.
Acetia sunt utilizai pentru a construi referine la acel obiect.
Identificatorii obiect bazai pe cheie primar permit ncrcarea mai uoar i mai rapid a
datelor stocate ntr-un tabel obiect. n schimb, identificatorii obiect generai de sistem au avantajul c
nu trebuie s fie gestionai de utilizator folosind chei definite de acesta, unicitatea lor fiind asigurat
de sistem. Prin urmare, mecanismul de refereniere al obiectelor este mai sigur.
Atunci cnd se construiete o referin ctre o linie obiect, aceasta este format din
identificatorul obiect, unele metadate despre tabelul obiect care conine linia respectiv i, opional,
identificatorul de linie (ROWID). Pentru o coloan de tip referin cu domeniu, spaiul de stocare
asociat acesteia este mai mic, nefiind necesare metadatele tabelului obiect.
Liniile obiect de tip tablou imbricat sunt meninute ntr-un tabel de stocare separat. Fiecare
tablou imbricat are un singur tabel de stocare asociat tuturor liniilor i nu cte unul pentru fiecare
nregistrare. Acesta conine valorile tuturor elementelor coloanei respective. Pentru a face asocierea
dintre elementele tabloului imbricat i nregistrrile printe corespunztoare, tabelul de stocare are o
coloan ascuns NESTED_TABLE_ID care conine un identificator generat de sistem.

4.8. Indeci
Tipurile obiect pot interveni n mecanismul de indexare furnizat de sistemul Oracle. n
continuare sunt prezentate cteva modaliti de implementare.

Indeci bazai pe metode


Un index bazat pe funcii este un index n cheia cruia intervin valorile returnate de o expresie
sau o funcie. Noutatea pe care o aduce versiunea Oracle9i este c funcia de la baza unui astfel de
index poate fi o metod a unui tip obiect.
Un index bazat pe o metod determin calculul valorii returnate de metoda respectiv, pentru
fiecare instan obiect din coloana sau tabelul indexat. Aceste valori sunt stocate n cadrul indexului i
pot fi utilizate fr a reevalua funcia.
Indecii bazai pe funcii sunt utili pentru mrirea performanelor cererilor care conin o
funcie n clauza WHERE.
Exemplu:
Se consider tipul obiect t_opera_de_arta cu structura definit anterior. Acesta conine o
metod volum care returneaz volumul necesar expunerii unei opere de arta. Volumul se calculeaz pe
baza dimensiunilor obiectului respectiv, (stocate n cadrul vectorului dim de tip t_dim_v). S se
defineasc un tabel obiect de tip t_opera_de_arta i o cerere care s retureze operele ce ocup mai
puin de 2 m3. S se indexeze tabelul opere dup valorile returnate de metoda volum.
DROP TYPE t_opera_de_arta;
94 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

DROP TYPE t_dim_v;


CREATE OR REPLACE TYPE t_dim_v AS
VARRAY(3) OF NUMBER;
/
CREATE OR REPLACE TYPE t_opera_de_arta AS OBJECT (
cod_opera NUMBER,
tip VARCHAR2(10),
titlu VARCHAR2(200),
data_crearii DATE,
data_achizitiei DATE,
valoare NUMBER,
dim t_dim_v,
MEMBER FUNCTION volum RETURN NUMBER DETERMINISTIC);
/
CREATE OR REPLACE TYPE BODY t_opera_de_arta IS
MEMBER FUNCTION volum RETURN NUMBER IS
v_rezultat NUMBER;
BEGIN
IF dimensiuni IS NOT NULL THEN
v_rezultat := dim(1) * dim(2) * dim(3);
ELSE
v_rezultat := 0;
END IF;
RETURN v_rezultat;
END volum;
END;
/
CREATE TABLE opere OF t_opera_de_arta;
SELECT o.*
FROM opere o
WHERE o.volum() < 2;
CREATE INDEX volum_opere_idx ON opere o (o.volum());
Pentru a executa cererea anterioar, sistemul trebuie s evalueze funcia volum pentru fiecare
linie obiect din tabel. Dac exist un index bazat pe funcie care returneaz valorile funciei volum,
atunci calculul este realizat la crearea indexului, iar la execuia acestei interogri sistemul consult
doar rezultatele din index. n acest fel, cererea este executat mai rapid.
Indexarea valorilor returnate de o funcie are sens doar dac acestea sunt constante n raport
cu parametri, adic dac funcia returneaz ntotdeauna aceeai valoare pentru aceeai instan obiect.
Din acest motiv, pentru a folosi o funcie definit de utilizator n cadrul unui index, aceasta trebuie s
fie declarat ca fiind determinist, utiliznd cuvntul cheie DETERMINISTIC. Astfel, se asigur faptul
c exist o dependen determinist ntre valoarea returnat de funcie i valorile argumentelor
corespunztoare unui set de instane obiect.

Indexarea atributelor
Definirea indecilor asupra unui tabel obiect sau tabel de stocare (asociat unui atribut sau
coloan de tip tablou imbricat) este similar cu cea a indecilor corespunztori tabelelor obinuite. Se
pot defini indeci asupra:
Orientare pe obiecte n Oracle9i 95

atributelor scalare ale coloanelor obiect;


atributelor sau coloanelor referin cu domeniu.
Exemplu:
S se defineasc un tabel relaional, avnd numele tab_galerii. Tabelul conine coloanele
cod_galerie, nume_galerie, nume_cladire i adresa. Coloana adresa este obiectual i are tipul
t_adresa. Pentru obinerea unei performane sporite n interogrile care implic atributul cod_postal,
s se creeze un index corespunztor asupra tabelului tab_galerii.
CREATE TABLE tab_galerii (
cod_galerie NUMBER,
nume_galerie VARCHAR2(50) NOT NULL,
nume_cladire VARCHAR2(30),
adresa t_adresa);
CREATE INDEX i_adresa_gal1 ON tab_galerii(adresa.cod_postal);
Dac este necesar, sistemul permite definirea de indeci asupra atributelor de tip tablou
imbricat.
Exemplu:
Se consider tabelul tab_opere ce conine obiecte de tip t_opera_de_arta. Tipul
t_opera_de_arta are un atribut (polite) care stocheaz poliele de asigurare asociate unei opere sub
forma unui tablou imbricat (t_polite_ti). Acest tablou conine obiecte de tip t_polita_asigurare. S se
defineasc un index unic asupra codului polielor de asigurare. Se presupune c numele tabelului de
stocare asociat atributului polite este ts_polite.
CREATE UNIQUE INDEX cod_polita_unic_idx
ON ts_polite (NESTED_TABLE_ID, cod_polite);
n contextul unei ierarhii de tipuri obiect, este posibil definirea de indeci asupra atributelor
tuturor tipurilor ce pot fi stocate ntr-o coloan substituibil. Aceste atribute pot fi referite n comanda
CREATE INDEX, utiliznd funcia TREAT pentru a filtra doar anumite tipuri.
Exemplu :
S se creeze un index asupra atributului cod_autor al autorilor de surse bibliografice
nregistrai n tabelul tab_surse.
CREATE INDEX cod_autor_idx ON tab_surse
(TREAT(autor AS t_autor).cod_autor);
Tipul declarat al coloanei autor este t_persoana, care l are ca subtip pe t_autor, i de aceea,
coloana poate conine instane obiect ale acestui tip i ale subtipurilor lui. Atributul cod_autor este
definit de tipul t_autor, supertipul t_persoana neavnd acest atribut. Prin urmare, coloana ascuns
corespunztoare atributului cod_autor are valori diferite de null doar pentru autorii de tip t_autor sau
pentru eventualele subtipuri ale acestuia. Valorile coloanei ascunse cod_autor sunt identice cu valorile
expresiei TREAT. Att coloana ascuns, ct i expresia TREAT au ca valoare codul autorului, pentru
liniile ce conin obiecte de tip t_autor, i null, pentru celelalte tipuri de autori. Sistemul exploateaz
acest lucru i creeaz indexul cod_autor_idx de tip B-arbore asupra coloanei ascunse.
De remarcat c valorile din coloana ascuns sunt identice cu valorile expresiei TREAT, doar
dac tipul referit n cadrul opiunii AS (n exemplu, t_autor) este tipul care definete atributul indexat.
96 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Dac tipul int este un subtip care doar motenete atributul, expresia TREAT va returna valori
diferite de null doar pentru subtip (t_jurnalist), nu i pentru supertipurile acestuia (t_autor).
CREATE INDEX cod_autor_gresit_idx
ON tab_surse (TREAT(autor AS t_jurnalist).cod_autor);

4.9. Partiionarea tabelelor care conin obiecte


Partiionarea rezolv problema prelucrrii tabelelor i a indecilor de dimensiuni
considerabile, oferind posibilitatea descompunerii acestora n pri mai mici i mai uor de gestionat,
numite partiii. Versiunea Oracle9i extinde aceast tehnic i pentru tabelele care conin obiecte,
referine, vectori i tablouri imbricate. Tablourile imbricate sunt permise n tabelele partiionate, dar
tabelul de stocare asociat nu poate fi partiionat.
Exemplu:
S se partiioneze tabelul tab_opere dup domeniu, utiliznd dimensiunea slii (suprafata),
care este un atribut al coloanei sala de tip t_sala. Se consider c tipul t_opera_de_arta conine o
coloan de tip vector t_polite_v, pentru a ilustra stocarea vectorilor partiionai. De asemenea, se
presupune c fiecare instan conine o valoare de tip BLOB pentru a stoca fotografia operei de art
respective.
CREATE OR REPLACE TYPE t_polite_v IS
VARRAY(100) OF t_polita_asigurare;
/
CREATE OR REPLACE TYPE t_sala AS OBJECT (
cod_sala NUMBER,
galerie VARCHAR2(50),
nume VARCHAR2(100),
suprafata NUMBER); -- in mp
ALTER TYPE t_opera_de_arta
ADD ATTRIBUTE (polite t_polite_v,
sala t_sala,
foto BLOB) CASCADE;
CREATE TABLE tab_opere OF t_opera_de_arta1
LOB (foto) STORE AS (NOCACHE LOGGING)
PARTITION BY RANGE (sala.suprafata)
(PARTITION Opere_din_sali_mici
VALUES LESS THAN (100)
LOB (foto) STORE AS(
STORAGE (INITIAL 10 MINEXTENTS 10 MAXEXTENTS 100))
VARRAY polite STORE AS LOB (
STORAGE (INITIAL 10 MINEXTENTS 10 MAXEXTENTS 100)),
PARTITION Opere_din_sali_medii
VALUES LESS THAN (300)
LOB (foto) STORE AS (
STORAGE (INITIAL 10 MINEXTENTS 10 MAXEXTENTS 100))
VARRAY polite STORE AS LOB (
STORAGE (INITIAL 10 MINEXTENTS 10 MAXEXTENTS 100)),
PARTITION Opere_din_sali_mari
Orientare pe obiecte n Oracle9i 97

VALUES LESS THAN (500)


LOB (foto) STORE AS (
STORAGE (INITIAL 10 MINEXTENTS 10 MAXEXTENTS 100))
VARRAY polite STORE AS LOB (
STORAGE (INITIAL 10 MINEXTENTS 10 MAXEXTENTS 100)));

4.10. Funcii i predicate utile


n lucrul cu obiectele i referinele ctre obiecte apar frecvent funciile VALUE, REF,
DEREF, TREAT, SYS_TYPEID i predicatul IS OF tip. n blocurile PL/SQL, funciile VALUE, REF i
DEREF pot aprea doar n comenzi SQL.

VALUE
ntr-o comand SQL, funcia VALUE accept ca argument un alias al unui tabel sau
vizualizare obiect i returneaz instanele obiect stocate n acesta. Aceast funcie poate returna
instane de tipul liniei sau de oricare dintre subtipurile sale, dac este activat opiunea de
substituibilitate. Funcia VALUE este util n cadrul comenzilor LMD pentru a returna linii obiect n
vederea modificrii coleciilor.
Exemplele prezentate folosesc ierarhia de tipuri definit anterior, format din tipul t_persoana
cu subtipurile t_artist, t_autor i t_jurnalist. Se consider c tabelul obiect tab_persoane de tip
t_persoana este substituibil pentru toate nivelurile ierarhiei (SUBSTITUTABLE AT ALL LEVELS).
Exemplu:
a) S se selecteze n form obiectual, respectiv relaional, toate persoanele al cror nume
este Georgescu.
SELECT VALUE(p)
FROM tab_persoane p
WHERE p.nume = 'Georgescu';
SELECT *
FROM tab_persoane p
WHERE nume = 'Georgescu';
Se observ c abordarea obiectual permite extragerea mai multor informaii, i anume
valorile tuturor atributelor celui mai specific tip al instanei. Abordarea relaional extrage numai
valorile atributelor pentru tipul specificat al tabelului (cod i nume ale tipului rdcin t_persoana).
b) S se selecteze persoanele (cod i nume), inclusiv artitii i autorii, dintr-o vizualizare
obiect viz_persoane asupra tabelului obiect tab_persoane.
CREATE VIEW viz_persoane OF t_persoana
AS SELECT *
FROM tab_persoane;
SELECT VALUE(p)
FROM viz_persoane p;

REF
Funcia REF are ca argument un alias al unui tabel sau al unei vizualizri obiect i returneaz
o referin ctre instanele obiect din acesta. REF poate returna referine att ctre obiecte de tipul
98 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

declarat al tabelului, ct i ctre obiecte corespunztoare subtipurilor acestuia, stocate n cadrul


tabelului.
Exemplu:
S se listeze referine ctre toate persoanele, inclusiv ctre autori i artiti.
SELECT REF(p)
FROM tab_persoane p;

DEREF
ntr-o comand SQL, funcia DEREF permite obinerea instanei obiect corespunztoare unei
referine (derefereniere). Instana obiect returnat poate fi de tipul declarat al referinei sau de unul
dintre subtipurile acestuia.
Exemplu:
S se selecteze liniile obiect coninute n tabelul obiect tab_persoane, innd cont de
substituibilitatea acestuia. Vor fi afiate nregistrrile stocate att relativ la persoane obinuite, ct i la
artiti sau autori.
SELECT DEREF(REF(p))
FROM tab_persoane p;

TREAT
Funcia TREAT modific tipul unei expresii la un alt tip specificat. n general, acesta este un
subtip al tipului expresiei. Cu alte cuvinte, funcia ncearc s trateze o instan a unui supertip ca o
instan a unui subtip al acestuia. Dac acest lucru nu este posibil, este returnat valoarea null. Funcia
TREAT este permis n SQL, dar nu i n PL/SQL.
Principalele utilizri ale lui TREAT sunt:
n limitarea atribuirilor, pentru a modifica tipul unei expresii, astfel nct s poat fi
atribuit unei variabile de un tip mai specializat n ierarhie (altfel spus, pentru a seta
valoarea unui supertip la un subtip);
pentru accesarea atributelor i metodelor unui subtip al tipului declarat liniei sau coloanei
obiect.
De exemplu, un obiect de tip t_persoana poate fi tratat ca fiind de tip t_autor, doar dac
obiectul respectiv este ntr-adevr de tip t_autor (sau un subtip al acestuia, t_jurnalist). Dac persoana
este autor, atunci obiectul este returnat cu tipul t_autor avnd toate atributele i metodele
corespuntoare acestui tip. Dac persoana nu este autor, funcia TREAT returneaz valoarea null.
Funcia TREAT poate fi utilizat att relativ la parametri de tip obiect, ct i relativ la
parametri de tip referin.
Exemplu:
a) Se consider tabelul definit anterior, tabel, avnd atributele perscol de tip t_persoana,
autcol de tip t_autor i artcol de tip t_artist. S se realizeze o atribuire prin limitare ntre coloanele
autcol i perscol. Pentru fiecare linie, TREAT returneaz o expresie de tip t_autor, dac n linia
respectiv este stocat o valoare de acest tip, sau valoarea null, n caz contrar.
UPDATE tabel
set autcol = TREAT(perscol AS t_autor);
Orientare pe obiecte n Oracle9i 99

b) S se selecteze toate instanele de tip t_autor ale tabelului obiect tab_persoane de tip
t_persoana. Comanda utilizeaz TREAT pentru a modifica tipul fiecrei linii obiect din t_persoana n
t_autor.
SELECT TREAT(VALUE(p) AS t_autor)
FROM tab_persoane p;
c) S se selecteze referine ctre toate instanele t_autor din tabelul obiect tab_persoane.
SELECT TREAT(REF(p) AS REF t_autor)
FROM tab_persoane p;
Una dintre cele mai frecvente utilizri a funciei TREAT este aceea de a accesa atributele i
metodele unui subtip al tipului unei linii sau coloane obiect.
Exemplu:
S se listeze numele i ocupaia persoanelor din tabelul tab_persoane. S va afia ocupaia,
pentru persoanele care sunt caracterizate prin acest atribut i, n rest, valoarea null. Atributul ocupatie
face parte din tipul t_autor
SELECT nume, TREAT(VALUE(p) AS t_autor).ocupatie ocupatie
FROM tab_persoane p;
NUME OCUPATIE
---- --------
Georgescu null
Irving Stone scriitor
Simona Popescu jurnalist
Urmtoarea cerere va declana o eroare (ORA-00904: invalid identifier) deoarece ocupatie
este un atribut al tipului t_autor i nu al tipului t_persoana.
SELECT nume, VALUE(p).ocupatie ocupatie
FROM tab_persoane p;
Un tabel sau o coloan obiect de tip T care sunt substituibile, au asociat cte o coloan
ascuns corespunztoare fiecrui atribut al subtipurilor lui T. Aceste coloane nu sunt listate de o
comand DESCRIBE, dar ele conin date referitoare la atributele subtipurilor. Funcia TREAT permite
accesul la aceste coloane.
Exemplu:
Se presupune c tipul t_autor conine o metod ocupatie ce returneaz valoarea acestui atribut
pentru o instan obiect dat. S se descrie structura tabelului tab_persoane i s se afieze numele i
ocupaia fiecrei persoane. Exemplul arat modul de utilizare al funciei TREAT pentru a accesa o
metod.
DESC tab_persoane
SELECT nume, TREAT(VALUE(p) AS t_autor).ocupatie() ocupatie
FROM tab_persoane1 p;

IS OF
Predicatul IS OF verific instanele obiect n raport cu nivelul de specializare al tipului lor. IS
OF este permis n SQL, dar nu i n PL/SQL.
100 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Exemplu:
S se selecteze doar instanele obiect de tip t_autor (inclusiv instanele corespunztoare
subtipurilor acestuia) stocate n tabelul tab_persoane.
SELECT VALUE(p)
FROM tab_persoane p
WHERE VALUE(p) IS OF (t_autor);
VALUE(P)(COD, NUME)
-------------------------------------------------------------
T_AUTOR(25, 'Irving Stone', 125, 'scriitor', NULL)
T_JURNALIST(35, 'Simona Popescu', 135, 'jurnalist', NULL, 'redactor',
'Dilema')
Pentru orice obiect care nu este de subtipul specificat sau de un subtip al acestuia, predicatul
IS OF returneaz FALSE. Dac trebuie excluse subtipurile tipului specificat, se poate utiliza cuvntul
cheie ONLY. Acesta permite selectarea exclusiv a obiectelor cu cel mai specific tip dat.
Pentru a condiiona tipul obiectului adresat de o referin, se utilizeaz predicatul IS OF n
combinaie cu funcia DEREF, ce regsete obiectul referit.
Exemplu:
a) S se selecteze sursele bibliografice ale cror autori sunt de tip t_autor. Sunt excluse
sursele ale cror autori sunt de un subtip al tipului t_autor (de exemplu, t_jurnalist).
SELECT s.titlu titlu, s.autor autor
FROM tab_surse s
WHERE s.autor IS OF (ONLY t_autor);
TITLU AUTOR
--------------- ------
Agonie si extaz T_AUTOR(25,'Irving Stone',
125, 'scriitor', NULL)
b) S se selecteze referine ctre obiectele de tip t_autor sau t_artist, stocate n tabelul
tab_persoane.
SELECT REF(p)
FROM tab_persoane p
WHERE VALUE(p) IS OF (t_autor, t_artist);
c) S se afieze numai autorii pentru care t_autor este cel mai specific tip. Exemplul
utilizeaz funcia TREAT pentru a converti obiectele de tip t_autor de la tipul tabelului obiect
tab_persoane (t_persoana) la t_autor. n acest fel, sunt listate toate atributele tipului corespunztor
instanei returnate.
SELECT TREAT(VALUE(p) AS t_autor) AUTOR
FROM tab_persoane p
WHERE VALUE(p) IS OF (ONLY t_autor);
AUTOR(COD, NUME, COD_AUTOR, OCUPATIE, DESCRIERE)
---------------------------------------------------
T_AUTOR (25, 'Irving Stone', 125, 'scriitor', NULL)
SELECT p.*
FROM tab_persoane p
WHERE VALUE(p) IS OF (ONLY t_autor);
COD NUME
Orientare pe obiecte n Oracle9i 101

--- -------------
25 Irving Stone

SYS_TYPEID
Funcia SYS_TYPEID poate fi utilizat n cadrul cererilor SQL pentru a obine identificatorul
celui mai specific tip al instanei obiect precizate ca argument. Funcia returneaz identificatorii de tip
din coloana discriminant asociat coloanelor substituibile dintr-un tabel.
Tuturor tipurilor ce aparin unei ierarhii de tipuri li se asociaz identificatori diferii de null,
unici n cadrul ierarhiei. Dac instana dat ca argument corespunde unui tip final, atunci funcia
returneaz valoarea null.
Exemplu:
a) Se consider tabelul obiect substituibil tab_persoane, avnd tipul t_persoana. Tipul
t_persoana este tipul rdcin al ierarhiei. Acesta are pe t_autor i t_artist ca subtipuri, iar pe
t_jurnalist ca subtip al tipului t_autor. S se afieze numele fiecrei persoane i identificatorul tipului
instanei respective.
SELECT nume, SYS_TYPEID(VALUE(p)) cod_tip
FROM tab_persoane p;
NUME COD_TIP
-------------- ------
Georgescu 01
Irving Stone 03
Simona Popescu 04
b) S se afieze titlul lucrrii, numele i identificatorii celor mai specifice tipuri, pentru
autorii de surse bibliografice nregistrai n tabelul tab_surse. Coloana autor de tip t_persoana este
substituibil.
SELECT s.titlu, s.autor.nume, SYS_TYPEID(autor) cod_tip
FROM tab_surse s;
TITLU AUTOR COD_TIP
-------------------------- ----------- ------
Cronica de azi Georgescu 01
Agonie si extaz Irving Stone 03
Expozitii Simona Popescu 04
102 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

5. Vizualizri obiect

Acest capitol prezint modalitatea de creare a aplicaiilor orientate pe obiecte, pstrnd


structura relaional a bazei de date. Datele din tabele relaionale pot fi sintetizate n vizualizri obiect
i accesate n manier obiectual. Aceast modalitate de regsire a obiectelor poate optimiza traficul
client/server, deoarece consultarea unui multitabel se face cu mai puine incursiuni la server.
La fel cum o vizualizare poate fi asemnat cu un tabel virtual, o vizualizare obiect poate fi
asemnat cu un tabel obiect virtual. Fiecare linie dintr-o vizualizare obiect este un obiect care
permite apelarea metodelor, accesul la atribute i crearea de referine. Principalele avantaje ale
vizualizrilor obiect sunt flexibilitatea i performanele sporite.
Vizualizrile obiect sunt utile pentru crearea de prototipuri sau pentru tranzitarea simpl i
rapid a aplicaiilor spre modelul obiectual, fr a schimba structura fizic a tabelelor existente n
baza de date.
De asemenea, vizualizrile obiect pot fi utilizate ca i cele relaionale pentru a prezenta datele
necesare utilizatorilor ntr-o form special sau pentru a restriciona accesul la unele dintre
informaiile stocate n tabele. De exemplu, se poate crea o vizualizare obiect asupra tabelului ce
conine informaii despre operele de art, restricionnd accesul la valoarea acestora, care este secret.
Sintetiznd obiectele din date relaionale, se pot selecta informaii care folosesc noi formate.
Pornind de la aceleai date se pot crea mai multe modele cu grade diferite de complexitate. n cadrul
unei vizualizri obiect se poate continua dezvoltarea modelului. Dac sunt necesare modificri asupra
unui tip obiect asociat unei vizualizri, vizualizrile invalidate de aceast operaie pot fi cu uurin
actualizate n conformitate cu noua definiie.
Pe lng flexibilitate, vizualizrile obiect aduc i un plus de performan. Datele relaionale,
care sunt transformate n linii obiect ale unei vizualizri, traverseaz reeaua ca un ntreg, micornd
traficul n reea i timpul de procesare.
Deoarece obiectele din vizualizare sunt procesate pe server i nu pe maina client, rezult mai
puine comenzi SQL. De asemenea, datele obiectuale din vizualizrile obiect pot fi ncrcate n/din
memoria virtual client. n acest fel, mecanismele specifice de selectare i ncrcare a obiectelor
dependente reduc traficul n reea.
Datele relaionale pot fi ncrcate n memoria virtual obiect de pe maina client i asociate
unor structuri C/C++ sau clase Java, astfel nct s fie prelucrate ca nite clase native n cadrul
aplicaiilor LG3. De asemenea, sunt furnizate modaliti complexe de regsire a obiectelor pornind de
la datele relaionale existente. Prin mecanismul de refereniere a obiectelor se pot selecta simplu i
eficient datele din mai multe tabele, nefiind necesare join-uri complexe.
Utilizarea obiectelor n vizualizri nu implic restricii suplimentare asupra mecanismelor de
stocare ale bazei de date sau limitri legate de restriciile tehnologiei relaionale. De exemplu, se pot
sintetiza obiecte din tabele relaionale partiionate i se pot utiliza cereri paralelizate.
Orientare pe obiecte n Oracle9i 103

5.1. Definirea vizualizrilor obiect


O vizualizare reprezint un tabel logic bazat pe unul sau mai multe tabele sau vizualizri.
Pentru definirea unei vizualizri se utilizeaz comanda CREATE VIEW. Practic, vizualizarea nu
conine date, ea permite doar accesul ctre acestea. Tabelele sau vizualizrile pe care se bazeaz
vizualizarea se numesc tabele de baz.
Avnd la baz mecanismul deja existent pentru crearea vizualizrilor relaionale, sistemul
Oracle9i permite crearea de vizualizri obiect sau vizualizri relaionale ce conin obiecte.
Nu exist restricii asupra tipurilor de date ale obiectelor coninute n aceste vizualizri. Sunt
permise tipuri scalare, definite de utilizator (tipuri obiect, referin i colecie) sau LOB. O vizualizare
obiect este o vizualizare n care fiecare linie este un obiect de un tip specificat, obiect ce poate fi
identificat n mod unic n sistem prin intermediul unui identificator obiect.
Avnd o schem relaional dat, procedura prin care se definete o vizualizare obiect
presupune succesiunea urmtoarelor etape:
stabilirea i crearea unui tip obiect n care fiecare atribut s corespund unei coloane din
tabelele de baz;
descrierea unei cereri care specific modalitatea de extragere a datelor din tabelele de
baz (coloanele returnate de cerere trebuie s corespund ca ordine i tip cu atributele
tipului obiect asociat);
specificarea unei chei unice, bazat pe atributele datelor din tabelele de baz, care
servete drept identificator obiect i permite crearea de referine ctre obiectele din
vizualizarea respectiv (de obicei, se utilizeaz cheia primar sau identificatorul generat
de sistem).
Dac este necesar modificarea ulterioar a datelor prin intermediul vizualizrii obiect i
atributele tipului obiect nu corespund cu exactitate coloanelor din tabelul asociat (de exemplu, dac
sunt incluse coloane calculate), mai trebuie urmat un pas. Se definete un declanator de tip INSTEAD
OF, care va fi invocat automat de fiecare dat cnd aplicaiile modific datele din vizualizarea obiect.
Dup executarea acestor pai, vizualizarea obiect poate fi folosit exact ca un tabel obiect.
Pentru a crea o vizualizare n propria schem, trebuie deinut privilegiul sistem CREATE
VIEW, iar pentru a putea crea o vizualizare n schema unui alt utilizator, este necesar privilegiul
sistem CREATE ANY VIEW. Pentru crearea unei subvizualizri este necesar privilegiul sistem
UNDER ANY VIEW sau privilegiul obiect UNDER asupra supervizualizrii respective.
Proprietarul schemei care conine vizualizarea trebuie s aib privilegiile necesare pentru a
selecta, insera, modifica sau terge linii din tabelele sau vizualizrile pe care se bazeaz aceasta.
Privilegiile trebuie s fie acordate n mod direct i nu prin intermediul unui role.
Pentru a folosi metoda constructor a unui tip obiect la crearea unei vizualizri obiect, trebuie
ca tipul obiect s aparin schemei curente sau ca utilizatorul s aib privilegiul sistem EXECUTE
ANY TYPE.
Comanda CREATE VIEW are urmtoarea sintax:
CREATE [OR REPLACE] [ {FORCE | NOFORCE} ]
VIEW [schema.]nume_vizualizare
[ {OF [schema.]nume_tip
{WITH OBJECT IDENTIFIER {DEFAULT | (atribut [, atribut] ) }
| UNDER [schema.]nume_supervizualizare}
( {atribut constr_atr [constr_atr] | constr_tabel_sau_viz}
104 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

[, {atribut constr_atr [constr_atr] | constr_tabel_sau_viz}] )


AS subcerere
[WITH {READ ONLY | CHECK OPTION [CONSTRAINT constr] } ];
Clauza OR REPLACE se specific pentru a recrea vizualizarea, dac aceasta exist deja,
schimbndu-i definiia fr a o terge i a reacorda privilegiile obiect necesare. La redefinirea unei
vizualizri, declanatorii de tip INSTEAD OF ataai acesteia sunt eliminai.
Opiunea FORCE este precizat dac se dorete crearea vizualizrii chiar atunci cnd tabelele
de baz ale acesteia i tipurile obiect referite nu exist sau proprietarul schemei ce conine
vizualizarea nu are privilegiile necesare asupra obiectelor referite. Aceste condiii trebuie s fie
ndeplinite naintea oricrei operaii LMD asupra vizualizrii. n caz contrar, vizualizarea rmne
invalid.
Clauza NOFORCE impune crearea vizualizrii doar dac sunt ndeplinite toate condiiile de
validitate (existena tabelelor de baz i a tipului asociat, privilegiile necesare). Aceast opiune este
implicit.
Atunci cnd se creeaz o vizualizare obiect nu se pot utiliza alias-uri.
Asupra vizualizrilor obiect se pot stabili constrngeri la nivel de atribut sau la nivel de
vizualizare. Aceste constrngeri sunt pur declarative, n sensul c nu sunt verificate de ctre sistem. n
general, operaiile asupra vizualizrilor sunt supuse constrngerilor de integritate definite asupra
tabelelor de baz. n cadrul vizualizrilor relaionale, nu sunt permise constrngeri la nivel de atribut
pentru coloanele obiect.
Dac definiia vizualizrii conine o constrngere care nu este ndeplinit la momentul crerii,
atunci comanda CREATE VIEWFORCE nu se execut cu succes. Orice constrngere referit n
cadrul comenzii trebuie s fie definit n tabelele de baz.
Clauza OF este specific definirii vizualizrilor obiect. Prin intermediul ei se precizeaz tipul
obiect asociat (nume_tip). Coloanele vizualizrii obiect corespund atributelor de pe primul nivel al
tipului. Fiecare linie conine cte o instan obiect i fiecare instan are asociat un identificator obiect
(OID) specificat n clauza WITH OBJECT IDENTIFIER. Dac se omite numele schemei, sistemul
creeaz vizualizarea obiect n schema curent.
Identificatorii obiect permit construirea de referine ctre liniile obiect ale vizualizrilor
obiect. n acest fel, obiectele din aceste vizualizri pot fi referite i ncrcate n memoria virtual
obiect. Deoarece datele vizualizrilor nu sunt stocate persistent, trebuie specificat un set de valori care
va fi utilizat pentru a defini identificatorii obiect. Valorile trebuie s fie unice n domeniul liniilor
selectate n vizualizare, deoarece duplicarea lor creeaz probleme atunci cnd se utilizeaz referinele
ctre obiecte.
Clauza WITH OBJECT IDENTIFIER se poate folosi doar pentru o vizualizare obiect de pe
primul nivel al unei ierarhii (vizualizare rdcin). Aceast opiune permite specificarea atributului
sau atributelor care vor fi utilizate pentru a identifica unic fiecare linie din vizualizarea obiect. n
majoritatea cazurilor, aceste atribute corespund coloanelor care compun cheia primar a tabelului de
baz.
Combinaia de atribute care candideaz pentru a deveni identitificator obiect trebuie s
identifice n mod unic o linie n vizualizare.
Restriciile legate de identificatorii obiect impun faptul c:
dac se utilizeaz o referin (prin derefereniere sau ncrcarea n memoria virtual a unei
chei primare de tip REF) care identific mai mult de o instan n vizualizarea obiect,
atunci este returnat o eroare;
Orientare pe obiecte n Oracle9i 105

clauza WITH OBJECT IDENTIFIER nu poate fi specificat la crearea unei subvizualizri,


deoarece subvizualizrile motenesc identificatorii obiect de la supervizualizrile lor.
Dac vizualizarea obiect este definit asupra unui tabel sau unei vizualizri obiect, atunci
exist deja identificatori obiect asociai fiecrei linii i se poate omite aceast clauz sau se poate
specifica opiunea DEFAULT. n acest fel, sistemul utilizeaz identificatorul obiect al tabelului sau al
vizualizrii obiect de baz (generat de sistem sau bazat pe cheia primar). Dac linia obiect este
sintetizat exclusiv din date relaionale, atunci trebuie specificat un set de atribute pentru a fi folosit
drept identificator obiect.
Clauza UNDER este folosit pentru a specifica o subvizualizare a unei vizualizri obiect
existente. Pentru a afla dac o vizualizare este supervizualizarea unei subvizualizri, se poate consulta
coloana SUPERVIEW_NAME a vizualizrii USER_VIEWS din dicionarul datelor.
Restriciile impuse la crearea subvizualizrilor sunt:
o subvizualizare trebuie s aparin aceleiai scheme din care face parte supervizualizarea
sa;
tipul obiect pe baza cruia se creeaz subvizualizarea trebuie s fie subtipul direct al
tipului asociat supervizualizrii;
se poate crea o singur subvizualizare de un anumit tip, n extensia aceleiai
supervizualizri.
La crearea vizualizrii este necesar o subcerere care s identifice coloanele i liniile tabelelor
de baz din care sunt extrase datele. Lista SELECT poate conine cel mult 1000 expresii. Dac se
creeaz vizualizri care refer tabele i vizualizri distante, legturile bazei de date specificate trebuie
s fie create utiliznd clauza CONNECT TO a comenzii CREATE DATABASE LINK, iar obiectele din
clauza FROM a subcererii trebuie calificate cu numele schemei din care fac parte.
Restriciile asupra subcererii unei vizualizri obiect sunt asemntoare celor precizate pentru
vizualizrile obinuite. n plus, pentru vizualizrile obiect trebuie ca expresiile din lista subcererii s
corespund ca numr, ordine i tip de date cu atributele de primul nivel ale tipului obiect.
Clauza de restricie a subcererii WITH READ ONLY interzice execuia operaiilor de
modificare a datelor prin intermediul vizualizrii. Clauza WITH CHECK OPTION garanteaz faptul
c, din inserrile i modificrile asupra vizualizrii, vor rezulta doar linii care ndeplinesc condiiile
din subcerere.
Opiunea WITH CHECK OPTION nu poate funciona dac:
exist o subcerere imbricat n cadrul subcererii vizualizrii sau ntr-una dintre
vizualizrile de baz;
operaiile de inserare, tergere i modificare se fac prin intermediul declanatorilor
INSTEAD OF.
Prin intermediul opiunii CONSTRAINT se poate da un nume constrngerii CHECK OPTION,
n caz contrar aceasta avnd unul implicit, generat de sistem, de forma SYS_Cn.
Comenzile ALTER VIEW i DROP VIEW, aplicate unor vizualizri obiect funcioneaz
similar celor referitoare la vizualizrile obinuite. Comanda ALTER VIEW este utilizat pentru
recompilarea unei vizualizri (opiunea COMPILE) sau pentru definirea, modificarea i suprimarea de
constrngeri. Comanda DROP VIEW permite tergerea unei vizualizri.
Exemplu:
S se defineasc o vizualizare obiect asupra picturilor din muzeu, fr a permite accesul la
106 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

valoarea acestora. Vizualizarea obiect conine obiecte de tip t_opera_de_arta, avnd atributele
cod_opera, tip, titlu, data_crearii, dimensiuni, data_achizitiei i polite. Pentru a obine valorile
coloanei cod a tabelului relaional tab_opere, se va utiliza atributul cod_opera al tipului asociat
vizualizrii obiect.
CREATE TABLE tab_opere (
cod NUMBER PRIMARY KEY,
tip VARCHAR2(10),
titlu VARCHAR2(200),
artist REF t_artist,
data_crearii DATE,
data_achizitiei DATE,
valoare NUMBER,
polite t_polite_ti,
dimensiuni t_dim_v)
NESTED TABLE polite STORE AS tstoc_pol;
CREATE TYPE t_opera_de_arta AS OBJECT (
cod_opera NUMBER,
tip VARCHAR2(10),
titlu VARCHAR2(200),
artist REF t_artist,
data_crearii DATE,
data_achizitiei DATE,
polite t_polite_ti,
dimensiuni t_dim_v);
/
CREATE VIEW viz_picturi OF t_opera_de_arta
WITH OBJECT IDENTIFIER (cod_opera)
AS SELECT o.cod, o.tip, o.titlu, o.artist,
o.data_crearii, o.data_achizitiei,
o.polite, o.dimensiuni
FROM tab_opere o
WHERE LOWER (tip) = 'pictura';
Clauza WITH OBJECT IDENTIFIER (cod_opera) din comanda CREATE VIEW stabilete ca
identificatorii obiect ai liniilor obiect din cadrul vizualizrii viz_picturi s fie bazai pe cheia primar
cod a tabelului relaional de baz, tab_opere. n cadrul vizualizrii, coloana cod devine atributul
cod_opera asociat tipului obiect. Cum acest atribut este unic n domeniul obiectelor vizualizrii i
diferit de null, el poate fi folosit ca identificator obiect.

5.2. Utilizarea vizualizrilor obiect n aplicaii


Dei datele sintetizate n cadrul unei vizualizri obiect pot proveni din mai multe tabele,
obiectul traverseaz reeaua printr-o singur transmisie. Instana este adus n memoria virtual client
sub forma unei structuri C/C++ sau variabil obiectual PL/SQL i poate fi prelucrat ca orice alt
structur nativ.
O vizualizare obiect poate fi referit n cadrul comenzilor SQL n acelai mod n care sunt
referite tabelele obiect. De exemplu, vizualizrile obiect pot aprea n clauza FROM a comenzii
SELECT, n clauza SET a comenzii UPDATE sau n condiia WHERE. De asemenea, este permis
definirea de vizualizri obiect care s aib la baz alte vizualizri obiect. La modificarea sau
Orientare pe obiecte n Oracle9i 107

eliminarea unui tip referit de o vizualizare obiect pe server, sistemul modific automat i vizualizrile
obiect asociate.

Imbricarea obiectelor n vizualizri obiect


Dac tipul obiect pe care se bazeaz vizualizarea obiect are la rndul su atribute de tip
obiect, atunci trebuie prevzute pentru acestea coloane obiect n specificaia vizualizrii. Dac n
tabelul relaional deja exist coloane de tipul atributului respectiv, atunci ele sunt doar selectate pentru
a face parte din vizualizare. n caz contrar, instanele obiect sunt sintetizate din datele relaionale de
baz, n aceeai manier ca i instanele asociate tipului vizualizrii. Obiectele sunt create prin
apelarea metodei constructor a tipului obiect respectiv i valorile atributelor sunt obinute din
coloanele relaionale specificate n constructor.
Exemplu:
Se consider tabelul relaional tab_galerii care conine informaii despre galeriile disponibile
muzeului. S se creeze o vizualizare obiect n care adresele s reprezinte obiecte imbricate n cadrul
liniilor obiect de tip de tip t_galerie. Acest lucru aduce flexibilitate i permite reutilizarea tipului
t_adresa n cadrul altor tipuri. S se defineasc tipurile t_adresa, t_galerie i vizualizarea viz_galerii,
care va conine pentru fiecare galerie codul, numele, numele cldirii i adresa. Obiectele de tip
t_adresa sunt construite din coloanele tabelului relaional corespunztor.
CREATE TABLE tab_galerii(
cod_gal NUMBER PRIMARY KEY,
nume_gal VARCHAR2(50),
nume_cladire VARCHAR2(30),
strada_gal VARCHAR2(20),
oras_gal VARCHAR2(10),
judet_gal CHAR(2),
codpostal VARCHAR2(10));
CREATE OR REPLACE TYPE t_adresa AS OBJECT (
strada VARCHAR2(20),
oras VARCHAR2(10),
judet CHAR(2),
codpostal VARCHAR2(10));
/
CREATE TYPE t_galerie AS OBJECT (
cod NUMBER,
nume_gal VARCHAR2(50),
nume_cladire VARCHAR2(30),
adresa_gal t_adresa);
/
CREATE VIEW viz_galerii OF t_galerie
WITH OBJECT IDENTIFIER (cod)
AS SELECT g.cod_gal, g.nume_gal, g.nume_cladire,
t_adresa (g.strada_gal, g.oras_gal,
g.judet_gal, g.codpostal) AS adresa_gal
FROM tab_galerii g;
Constructorul unui tip obiect nu returneaz niciodat valoarea null. Prin urmare, nici unul
dintre obiectele adresa_gal din vizualizarea obiect definit mai sus nu poate fi null, chiar atunci cnd
108 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

coloanele oras_gal, strada_gal, judet_gal i codpostal din tabelul relaional sunt null. n felul acesta,
spaiul este ocupat inutil cu instane care conin valoari null pentru fiecare atribut. Tabelul relaional
nu are coloane care s specifice dac adresa departamentului este completat sau nu. Dac se face
convenia ca o anumit coloan (de exemplu, strada_gal) s indice c o ntreag adres este null,
atunci se poate capta acest regul a aplicaiei folosind funcia DECODE.
CREATE VIEW viz_galerii OF t_galerie
WITH OBJECT IDENTIFIER (cod)
AS SELECT g.cod_gal, g.nume_gal, g.nume_cladire,
DECODE(g.strada_gal, NULL, NULL,
t_adresa(g.strada_gal, g.oras_gal, g.judet_gal,
g.codpostal)) AS adresa_gal
FROM tab_galerii g;
Dei n acest fel se implementeaz o regul a aplicaiei imposibil de inclus ntr-o structur
relaional, utilizarea ei n subcererea corespunztoare vizualizrii obiect are i un dezavantaj. Nu mai
este permis modificarea direct a adresei departamentului prin intermediul vizualizrii obiect. Acest
lucru nu este grav deoarece se poate defini un declanator de tip INSTEAD OF care s trateze
propagarea modificrilor fcute asupra vizualizrii obiect ctre tabelul de baz.

Utilizarea tipurilor colecie n vizualizri obiect


Coleciile, att tablourile imbricate ct i vectorii, pot fi coloane n cadrul vizualizrilor. Ele
pot fi sintetizate direct din coloanele de baz de tip colecie sau utiliznd subcereri i operatorul
CASTMULTISET.
Exemplu:
a) O galerie conine mai multe opere de art. S se reprezinte fiecare oper de art n tabelul
relaional tab_opere care conine coloanele cod, titlu, tip, valoare, cod_artist i cod_gal. S se impun
o constrngere de cheie primar asupra coloanei cod i una de cheie extern asupra coloanei cod_gal,
ce refer codul galeriei din care face parte o anumit oper de art.
CREATE TABLE tab_opere(
cod NUMBER PRIMARY KEY,
titlu VARCHAR2(20),
tip VARCHAR2(10),
valoare NUMBER,
cod_artist NUMBER,
cod_gal NUMBER REFERENCES tab_galerii(cod_gal));
b) S se creeze tipul t_opera cu atribute corespunztoare tabelului tab_opere (cod, titlu, tip,
valoare, cod_artist). S se defineasc un tip tablou imbricat t_opere_ti care s conin elemente de tip
t_opera. Acesta va fi necesar n modelarea relaiei de cardinalitate many-to-one dintre entitile opera
i galerie.
CREATE TYPE t_opera AS OBJECT (
cod NUMBER,
titlu VARCHAR2(20),
tip VARCHAR2(10),
valoare NUMBER,
cod_artist NUMBER);
Orientare pe obiecte n Oracle9i 109

/
CREATE TYPE t_opere_ti AS TABLE OF t_opera;
/
c) S se adauge tipului t_galerie un nou atribut, de tip t_opere_ti, care s includ lista
operelor expuse in acea galerie.
ALTER TYPE t_galerie
ADD ATTRIBUTE(lista_opere t_opere_ti)
CASCADE;
d) Utiliznd obiectele definite anterior, s se construiasc vizualizarea obiect viz_galerii,
care conine coloane pentru codul, numele, numele cldirii, adresa galeriei i colecia de opere de art
asociat galeriei respective. Vizualizarea obiect viz_galerii este bazat pe tipul obiect t_galerie, iar
datele din aceast vizualizare sunt sintetizate din tabelele relaionale tab_opere i tab_galerii. Pentru
sintetizarea datelor se va folosi funcia CASTMULTISET.
CREATE OR REPLACE VIEW viz_galerii OF t_galerie
WITH OBJECT IDENTIFIER (cod)
AS SELECT g.cod_gal, g.nume_gal, g.nume_cladire,
t_adresa (g.strada_gal, g.oras_gal,
g.judet_gal,g.codpostal) AS adresa_gal,
CAST (MULTISET (SELECT o.cod, o.titlu, o.tip,
o.valoare, o.cod_artist
FROM tab_opere o
WHERE o.cod_gal = g.cod_gal)
AS t_opere_ti)
AS lista_opere
FROM tab_galerii g;
Subcererea din cadrul blocului CASTMULTISET selecteaz operele care aparin galeriei
curente. Cuvntul cheie MULTISET indic faptul c lista dintre paranteze trebuie tratat ca o valoare
unitar. Operatorul CAST transform o expresie conform formatului specificat n clauza AS. Pentru
exemplul considerat, CAST transform rezultatul ntr-un tablou imbricat de tip t_opere_ti. O cerere
asupra vizualizrii viz_galerii returneaz lista galeriilor, fiecare linie coninnd codul, numele, numele
cldirii, adresa i colecia de opere expuse n cadrul galeriei.
Coleciile pe mai multe niveluri pot fi i ele utilizate n vizualizrile obiect. Pentru aceasta
trebuie create niveluri adiionale n cadrul tipului obiect corespunztor vizualizrii.
Urmtorul exemplu creeaz o vizualizare obiect care conine o colecie pe mai multe niveluri.
Se va implementa, n cadrul vizualizrii viz_galerii, faptul c fiecare oper de art are asociat o
mulime de polie de asigurare. Vizualizarea este bazat pe tabele relaionale simple, n sensul c
acestea nu conin colecii.
n primul rnd, trebuie create tipurile obiect i colecie care vor fi utilizate n cadrul
vizualizrii. Se definete cte un tip obiect corespunztor ca structur fiecrui tabel relaional (fiecrei
coloane din tabel i se asociaz un atribut de acelai tip n cadrul tipului obiect).
Exemplu:
a) S se defineasc tabelul relaional tab_polite, care conine informaii despre poliele de
asigurare corespunztoare operelor de art din muzeu. S se creeze tipul asociat tabelului (t_polita) i
tipul tablou imbricat t_polite_ti, cu elemente de tip t_polita. Se va aduga tipului t_opera un nou
atribut, lista_polite, pentru stocarea listei de polie asociate unei opere de art.
CREATE TABLE tab_polite(
110 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

cod_polita NUMBER,
descriere VARCHAR2(100),
firma VARCHAR2(20),
valoare NUMBER,
cod_opera NUMBER REFERENCES tab_opere (cod));
CREATE TYPE t_polita AS OBJECT (
cod_polita NUMBER,
descriere VARCHAR2(100),
firma VARCHAR2(20),
valoare NUMBER);
/
CREATE TYPE t_polite_ti AS TABLE OF t_polita;
/
ALTER TYPE t_opera
ADD ATTRIBUTE(lista_polite t_polite_ti)
CASCADE;
b) S se defineasc vizualizarea obiect asociat tabelelor relaionale i tipurilor definite mai
sus11.
CREATE OR REPLACE VIEW viz_galerii OF t_galerie
WITH OBJECT IDENTIFIER (cod)
AS SELECT g.cod_gal, g.nume_gal, g.nume_cladire,
t_adresa (g.strada_gal, g.oras_gal,
g.judet_gal,g.codpostal) AS adresa_gal,
CAST (MULTISET(
SELECT o.cod, o.titlu, o.tip,
o.valoare, o.cod_artist,
CAST (MULTISET (
SELECT p.cod_polita, p.descriere,
p.firma, p.valoare
FROM tab_polite p
WHERE p.cod_opera = o.cod)
AS t_polite_ti)
FROM tab_opere o
WHERE o.cod_gal = g.cod_gal)
AS t_opere_ti)
FROM tab_galerii g;
Tipul care implementeaz entitatea opera are un atribut de tip tablou imbricat (lista_polite) i
tipul t_galerie conine un tablou imbricat de opere de art. Prin urmare, tabloul de opere este o
colecie pe mai multe niveluri. Pentru a crea instanele acestui tip colecie se utilizeaz tot operatorul
CASTMULTISET n cadrul comenzii CREATE VIEW.

Crearea de referine la vizualizri obiect


Pentru a crea referine la obiectele coninute n vizualizri sau n tabele obiect se utilizeaz
operatorul MAKE_REF. Acesta utilizeaz cheile externe existente n modelul relaional. Funcia
MAKE_REF primete ca parametri numele vizualizrii sau tabelului obiect ctre care se creeaz
referina i o list de valori ale cheilor externe. Ea returneaz identificatorul obiectului referit.
11
Pentru vizualizrile ce folosesc i alte tipuri, n cazul n care nu se specific clauza WITH OBJECT IDENTIFIER apare
eroarea ORA-22974: missing WITH OBJECT OID clause.
Orientare pe obiecte n Oracle9i 111

O referin creat relativ la un obiect dintr-o vizualizare obiect respect tipul identificatorului
obiect specificat la nivel de vizualizare (bazat pe cheia primar sau generat de sistem). Ca i obiectele
sintetizate, pot fi selectate referine stocate persistent i reinute n coloanele unei vizualizri obiect.
Referinele create relativ la obiecte sintetizate prin intermediul vizualizrilor obiect nu pot fi, ns,
stocate persistent.
n exemplul expus anterior, fiecare obiect din vizualizarea obiect viz_galerii are un
identificator obiect unic, derivat din valoarea codului galeriei. n cazul relaional, legtura dintre
tab_opere i tab_galerii se face prin cheia extern cod_gal din tabelul tab_opere. Identificatorii
obiect din vizualizarea viz_galerii sunt bazai pe cheia primar. De aceea, este permis folosirea
valorii cheii externe n vizualizarea viz_opere, la crearea unei referine ctre un obiect din viz_galerii.
Exemplu:
a) S se modifice vizualizarea viz_opere, astfel nct s conin pentru fiecare oper de art
o referin la galeria din care face parte. Sunt necesare modificri asupra tipului t_opera creat anterior
i a vizualizrii viz_galerii, care va trebui s includ n definiia ei o valoare pentru noul atribut al
tipului t_opera.
ALTER TYPE t_opera
ADD ATTRIBUTE ref_gal REF t_galerie
CASCADE;
CREATE OR REPLACE VIEW viz_galerii OF t_galerie
WITH OBJECT IDENTIFIER (cod) AS
SELECT g.cod_gal, g.nume_gal, g.nume_cladire,
t_adresa (g.strada_gal, g.oras_gal,
g.judet_gal,g.codpostal) AS adresa_gal,
CAST (MULTISET(
SELECT o.cod, o.titlu, o.tip,
o.valoare, o.cod_artist,
CAST (MULTISET (
SELECT p.cod_polita, p.descriere,
p.firma, p.valoare
FROM tab_polite p
WHERE p.cod_opera = o.cod)
AS t_polite_ti), NULL
FROM tab_opere o
WHERE o.cod_gal = g.cod_gal)
AS t_opere_ti)
FROM tab_galerii g;
CREATE OR REPLACE VIEW viz_opere OF t_opera
WITH OBJECT IDENTIFIER(cod)
AS SELECT o.cod, o.titlu, o.tip,
o.valoare, o.cod_artist, NULL,
MAKE_REF(viz_galerii, o.cod_gal)
FROM tab_opere o;
b) tiind c ref_gal conine o referin ctre galerie, s se listeze toate operele din galeriile
cu locaia n Timioara.
SELECT o.cod, o.titlu, o.ref_gal.nume_gal
FROM viz_opere o
112 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

WHERE o.ref_gal.adresa_gal.oras = 'Timisoara';


c) S se implementeze alt modalitate de definire a vizualizrii viz_opere. Se va folosi
operatorul REF pentru a obine o referin ctre obiectul asociat din vizualizarea viz_galerii. n acest
caz, se realizeaz un join ntre vizualizarea viz_galerii i tabelul tab_opere, prin cheia cod_gal.
CREATE OR REPLACE VIEW viz_opere OF t_opera
WITH OBJECT IDENTIFIER(cod)
AS SELECT o.cod, o.titlu, o.tip,
o.valoare, o.cod_artist, NULL, REF(g)
FROM tab_opere o, viz_galerii g
WHERE o.cod_gal = g.cod;
Avantajul utilizrii operatorului MAKE_REF n loc de REF este acela c prin intermediul
primului se pot crea i referine circulare. De exemplu, se poate crea vizualizarea viz_opere astfel
nct fiecare linie s conin o referin ctre obiectul galerie asociat, iar vizualizarea viz_galerii s
aib ca atribut o list de referine ctre operele coninute.

Definirea relaiilor complexe dintre vizualizrile obiect


Referinele circulare dintre vizualizrile obiect (de exemplu, vizualizarea obiect a refer b
care la rndul ei refer a) pot fi definite utiliznd operatorul MAKE_REF. n acest fel, vizualizrile
obiect permit sinteza unei structuri complexe de date, cum ar fi un graf coninnd circuite.
Exist dou metode de a crea referine circulare ntre dou vizualizri obiect. Prima metod
const n a ajusta prima vizualizare dup crearea celei de-a doua. Ea presupune urmtorii pai:
crearea vizualizrii a fr referirea vizualizrii b;
crearea vizualizrii b, care include o referin la vizualizarea a;
nlocuirea vizualizrii a cu o nou definiie care include referina la vizualizarea b;
Cea de-a doua metod const n a crea prima vizualizare utiliznd cuvntul cheie FORCE i
presupune urmtorii pai:
crearea vizualizrii a cu referine la vizualizarea b, utiliznd cuvntul cheie FORCE
(vizualizarea a este invalid);
crearea vizualizrii b cu referin la vizualizarea a (la prima utilizare a vizualizrii a, ea
este validat i recompilat).
A doua metod are mai puini pai, dar este mai riscant pentru c opiunea FORCE poate
ascunde erori neprevzute n definiia vizualizrii. n acest caz trebuie interogat vizualizarea
USER_ERRORS din dicionarul datelor, pentru a vedea dac au aprut alte erori dect cele prevzute.
De asemenea, dac erorile persist i nu permit validarea vizualizrilor la prima utilizare, ele trebuie
remediate i vizualizarea trebuie recompilat manual, utiliznd comanda ALTER VIEWCOMPILE.
Relaiile one-to-one pot fi modelate cu ajutorul referinelor obiect circulare. Se presupune c
fiecare specialist are asociat un unic calculator personal i c acel calculator aparine doar unui
specialist. Un model relaional ar capta aceast situaie utiliznd o cheie extern de la tabelul de
specialiti ctre cel de calculatoare sau invers. Utilizarea vizualizrilor obiect permite modelarea
obiectelor astfel nct s existe o legtur dubl.
Exemplu:
Orientare pe obiecte n Oracle9i 113

Fie tabelele relaionale tab_specialiti i tab_computere. S se creeze tipurile t_computer,


t_specialist i vizualizrile viz_computere, viz_specialisti implementnd relaia one-to-one dintre
acestea prin referine circulare.
CREATE TABLE tab_computere(
cod NUMBER PRIMARY KEY,
tip VARCHAR2(10) DEFAULT 'desktop',
procesor VARCHAR2(40),
descriere VARCHAR2(200));
CREATE TABLE tab_specialisti(
cod NUMBER PRIMARY KEY,
nume VARCHAR2(50),
autorizatie VARCHAR2(5),
adresa REF t_adresa,
cod_computer NUMBER REFERENCES tab_computere (cod));
CREATE TYPE t_specialist;
/
CREATE TYPE t_computer AS OBJECT (
cod NUMBER,
tip VARCHAR2(10),
procesor VARCHAR2(40),
descriere VARCHAR2(200),
cod_spec REF t_specialist);
/
CREATE OR REPLACE TYPE t_specialist AS OBJECT (
cod NUMBER,
nume VARCHAR2(50),
autorizatie VARCHAR2(5),
adresa REF t_adresa,
cod_comp REF t_computer);
/
CREATE VIEW viz_computere OF t_computer
WITH OBJECT IDENTIFIER(cod)
AS SELECT c.cod, c.tip, c.procesor, c.descriere, NULL
FROM tab_computere c;
CREATE VIEW viz_specialisti OF t_specialist
WITH OBJECT IDENTIFIER(cod)
AS SELECT s.cod, s.nume, s.autorizatie,
s.adresa, MAKE_REF (viz_computere, s.cod_computer)
FROM tab_specialisti s;
CREATE OR REPLACE VIEW viz_computere OF t_computer
WITH OBJECT IDENTIFIER(cod)
AS SELECT c.cod, c.tip, c.procesor, c.descriere,
(SELECT MAKE_REF (viz_specialisti, c.cod)
FROM tab_specialisti s
WHERE c.cod = s.cod_computer)
FROM tab_computere c;
Relaiile one-to-many pot fi modelate prin utilizarea referinelor obiect sau prin legarea
direct a obiectelor. Acest tip de relaii pot fi reprezentate cu ajutorul unor colecii de obiecte sau de
referine obiect corespunztoare cardinalitii many.
114 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Se consider cazul entitilor galerie i opera. n modelul relaional clasic, cheia extern se
afl n tabelul cu opere de art. Se poate, ns, proiecta relaia dintre galerii i opere utiliznd colecii
n cadrul vizualizrilor obiect. Aa cum s-a exemplificat mai sus, vizualizarea viz_galerii poate
conine o colecie de opere de art, iar vizualizarea viz_opere o referin ctre galerie sau chiar
coloane de tipul asociat entitii galerie. Astfel, relaia este implementat n ambele sensuri ntre cele
dou entiti, att de la opera la galerie, ct i invers. Pentru a conserva spaiu, exist posibilitatea ca
vizualizarea viz_galerii s conin o colecie de referine ctre obiecte de tip t_opera_de_arta i nu
obiectele materializate propriu-zise. Cum tipul obiect asociat entitaii opera conine o referin ctre
galeria din care face parte, apar referine circulare ntre vizualizrile viz_galerii i viz_opere.
Exemplu:
Se consider tabelele tab_opere i tab_galerii definite anterior. Tipul t_opera conine o
coloan de tip referin la t_galerie. Lista de referine la operele de art va fi implementat sub forma
unui tabel imbricat. Se modific tipul t_galerie, astfel nct s conin o coloan de tip
t_lista_ref_opere. S se defineasc vizualizrile folosind cele dou metode descrise mai sus.
DROP VIEW viz_galerii FORCE;
DROP VIEW viz_opere FORCE;
CREATE TYPE t_lista_ref_opere AS TABLE OF REF t_opera;
/
ALTER TYPE t_galerie
DROP ATTRIBUTE lista_opere
CASCADE;
ALTER TYPE t_galerie
ADD ATTRIBUTE lista_ref_opere t_lista_ref_opere
CASCADE;
ALTER TYPE t_opera
DROP ATTRIBUTE lista_polite
CASCADE;
Metoda 1:
CREATE VIEW viz_opere OF t_opera
WITH OBJECT IDENTIFIER(cod)
AS SELECT o.cod, o.titlu, o.tip, o.valoare,
o.cod_artist, NULL
FROM tab_opere o;
CREATE VIEW viz_galerii OF t_galerie
WITH OBJECT IDENTIFIER(cod)
AS SELECT g.cod_gal, g.nume_gal, g.nume_cladire,
t_adresa(g.strada_gal, g.oras_gal,
g.judet_gal, g.codpostal),
CAST (MULTISET (
SELECT MAKE_REF(viz_opere, o.cod)
FROM tab_opere o
WHERE o.cod_gal = g.cod_gal)
AS t_lista_ref_opere)
FROM tab_galerii g;
CREATE OR REPLACE VIEW viz_opere OF t_opera
WITH OBJECT IDENTIFIER(cod)
AS SELECT o.cod, o.titlu, o.tip, o.valoare,
o.cod_artist, MAKE_REF(viz_galerii, o.cod_gal)
FROM tab_opere o;
Orientare pe obiecte n Oracle9i 115

Metoda 2:
CREATE FORCE VIEW viz_opere OF t_opera
WITH OBJECT IDENTIFIER(cod)
AS SELECT o.cod, o.titlu, o.tip, o.valoare,
o.cod_artist, MAKE_REF(viz_galerii, o.cod_gal)
FROM tab_opere o;
CREATE VIEW viz_galerii OF t_galerie
WITH OBJECT IDENTIFIER(cod)
AS SELECT g.cod_gal, g.nume_gal, g.nume_cladire,
t_adresa(g.strada_gal, g.oras_gal,
g.judet_gal, g.codpostal),
CAST (MULTISET (
SELECT MAKE_REF(viz_opere, o.cod)
FROM tab_opere o
WHERE o.cod_gal = g.cod_gal)
AS t_lista_ref_opere)
FROM tab_galerii g;
Exemplu:
a) S se listeze informaii complete despre operele de art din galeria avnd codul 1. Ambele
metode de creare prezentate mai sus permit interogarea vizualizrilor viz_galerii, viz_opere i
dereferenierea elementelor tabloului imbricat lista_ref_opere, referite prin cuvntul cheie
COLUMN_VALUE.
SELECT DEREF(o.COLUMN_VALUE)
FROM TABLE(SELECT g.lista_ref_opere
FROM viz_galerii g
WHERE g.cod = 1) o;
b) S se selecteze codurile operelor de art al cror titlu conine irul de caractere flori i
aparin galeriei avnd codul 1.
SELECT o.COLUMN_VALUE.cod
FROM TABLE(SELECT g.lista_ref_opere
FROM viz_galerii g
WHERE g.cod = 1) o;
WHERE LOWER(o.COLUMN_VALUE.titlu) LIKE '%flori%';
c) S se selecteze numele galeriei, codul i titlul operei de art pentru acele opere care fac
parte din galeria avnd codul 1 i care conin n titlu secvena flori. Pentru ca rezultatul s fie
tabelar, se poate distribui lista de referine prin introducerea unui join ntre vizualizare i coloana de
tip tablou imbricat.
SELECT g.nume_gal, o.COLUMN_VALUE.cod, o.COLUMN_VALUE.titlu
FROM viz_galerii g, TABLE(g.lista_ref_opere) o
WHERE LOWER(o.COLUMN_VALUE.titlu) like '%flori%'
AND d.cod = 1;
d) S se rescrie interogarea de la punctul anterior, utiliznd referinele coninute n
vizualizarea viz_opere, n sens invers.
SELECT o.ref_gal.nume_gal, DEREF(o.COLUMN_VALUE)
116 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

FROM viz_opere o, TABLE(o.ref_gal.lista_ref_opere) o


WHERE o.ref_dep.cod = 1
AND LOWER(o.COLUMN_VALUE.titlu) like '%flori%';

Vizualizri obiect asupra tabelelor distante


Un avantaj important al vizualizrilor obiect este c, prin intermediul lor, se pot accesa
tabelele distante sub form obiectual. Nu exist alt modalitate de a face acest lucru, nefiind permis
accesul direct asupra tabelelor obiect distante.
Exemplu:
Se consider un muzeu cu dou filiale, unul n Bucuresti i altul n Iai. Fiecare locaie are
cte un tabel n care sunt nregistrate operele de art. Dac la un moment dat se dorete o situaie
centralizat asupra tuturor picturilor aparinnd muzeului respectiv, atunci se pot crea dou vizualizri
generale asupra tabelelor distante, i apoi o vizualizare ce va selecta doar picturile din ambele surse de
date.
CREATE VIEW viz_opere_iasi
(cod, titlu, tip, valoare, cod_artist)
AS SELECT o.cod, o.titlu, o.tip, o.valoare, o.cod_artist
FROM tab_opere@legatura_iasi o;
CREATE VIEW viz_opere_bucuresti
(cod, titlu, tip, valoare, cod_artist)
AS SELECT o.cod, o.titlu, o.tip, o.valoare, o.cod_artist
FROM tab_opere@legatura_bucuresti o;
CREATE VIEW viz_toate_picturile OF t_opera
WITH OBJECT IDENTIFIER (cod)
AS SELECT oi.cod, oi.titlu, oi.tip, oi.valoare, oi.cod_artist
FROM viz_opere_iasi oi
WHERE oi.tip = 'pictura'
UNION
SELECT ob.cod, ob.titlu, ob.tip, ob.valoare, ob.cod_artist
FROM viz_opere_bucuresti ob
WHERE ob.tip = 'pictura';

5.3. Ierarhii de vizualizri obiect


O ierarhie de vizualizri obiect este un set de vizualizri obiect bazate pe cte un tip diferit
aparinnd unei ierarhii de tipuri. Asemntor mecanismului de extindere de la tipuri, subvizualizrile
dintr-o ierarhie obiect sunt create extinznd o supervizualizare (prin intermediul cuvntului cheie
UNDER).
Fiecare vizualizare obiect dintr-o ierarhie de vizualizri conine obiecte de un singur tip, dar
interogrile adreseaz implicit i subvizualizrile. Prin urmare, o astfel de ierarhie reprezint o
modalitate simpl de implementare a interogrilor ce returneaz un set polimorfic de obiecte, la un
nivel de specializare dat.
Exemplele din aceast seciune vor fi bazate pe ierarhia de tipuri creat anterior. Tipul
t_persoana este tipul rdcin i are doi copii, t_artist i t_autor. Tipul t_autor are, la rndul lui,
specializarea t_jurnalist.
Dac se creeaz o ierarhie de vizualizri bazat pe aceast ierarhie de tipuri, avnd cte o
Orientare pe obiecte n Oracle9i 117

vizualizare obiect construit pentru fiecare tip, atunci se poate interoga vizualizarea obiect care
corespunde nivelului de specializare necesar la un moment dat. De exemplu, se poate interoga
vizualizarea asociat tipului t_autor pentru a determina un set de rezultate referitor doar la autori,
inclusiv jurnaliti.
Vizualizarea rdcin poate fi asociat oricruia dintre tipurile din ierarhia de tipuri. Nu este
obligatoriu s se asocieze o vizualizare obiect tipului rdcin. De asemenea, nu este necesar
extinderea ierarhiei pn la tipurile frunze ale ierarhiei de tipuri i nici nu trebuie acoperite toate
ramurile acesteia. n schimb, nu se pot omite subtipuri intermediare pe vreo linie descendent a
ierarhiei. Orice subvizualizare trebuie bazat pe un subtip direct al tipului supervizualizrii ei.
O vizualizare obiect poate avea mai multe subvizualizri. Subvizualizrile bazate pe un tip dat
pot participa doar ntr-o singur ierarhie de vizualizri obiect. Diferite ierarhii nu pot conine
vizualizri asociate aceluiai tip.
O subvizualizare motenete identificatorul obiect de la supervizualizare. Acesta poate fi
definit n mod explicit doar n vizualizarea rdcin a ierarhiei. Nu se poate specifica explicit un
identificator obiect ntr-o subvizualizare. Dac acesta este identificatorul generat de sistem sau clauza
nu este specificat n vizualizarea rdcin, atunci pot fi create subvizualizri doar dac vizualizarea
rdcin este bazat pe un tabel sau o vizualizare care utilizeaz tot un identificator obiect generat de
sistem.
Pentru subvizualizri se aplic aceleai reguli ca i la vizualizri obinuite, cu privire la
situaiile n care pot fi modificate prin comenzi LMD. Dac o subvizualizare este inerent
nemodificabil i trebuie modificat, atunci se definesc declanatori de tip INSTEAD OF specifici.
Declanatorii de tip INSTEAD OF nu se motenesc. Toate vizualizrile dintr-o ierarhie trebuie s
aparin aceleiai scheme.
Versiunea Oracle9i permite crearea de vizualizri asociate tipurilor neinstaniabile. Un tip
neinstaniabil nu poate avea instane aa c, la prima vedere, nu ar fi util crearea unei vizualizri
obiect asociate. Un tip neinstaniabil poate avea ns, subtipuri instaniabile, iar posibilitatea definirii
vizualizrilor obiect pentru tipuri neinstaniabile permite construirea ierarhiilor de vizualizri obiect
asociate unor ierarhii de tipuri care conin tipuri neinstaniabile.

Crearea ierarhiilor de vizualizri obiect


O ierarhie de vizualizri obiect se construiete prin crearea de subvizualizri corespunztoare
subtipurilor tipului asociat vizualizrii rdcin.
O astfel de ierarhie poate fi bazat pe diferite modele relaionale de stocare a datelor, deci
poate fi produs dintr-o varietate de tabele de baz. Alegerea modelului de stocare are implicaii
asupra performanei i flexibilitii modificrii ierarhiei de vizualizri obiect.
Sunt exemplificate trei posibiliti de stocare.
modelul flat, n care toate vizualizrile din ierarhia obiect sunt bazate pe acelai tabel;
modelul orizontal, n care fiecare vizualizare are o coresponden one-to-one cu fiecare
tabel;
modelul vertical, n care vizualizrile sunt construite folosind join-uri ntre tabelele de
baz.

Modelul flat
n modelul flat, toate vizualizrile din ierarhie sunt bazate pe acelai tabel. n exemplul ce
118 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

urmeaz, unicul tabel relaional de baz (ToatePersoanele) conine coloane pentru toate atributele
tipurilor t_persoana, t_autor i t_artist.
CREATE TABLE ToatePersoanele (
cod_tip NUMBER(1), -- cod asociat tipului
cod NUMBER, -- persoana
nume VARCHAR2(50),
cod_autor NUMBER, -- autor
ocupatie VARCHAR2(30),
descriere VARCHAR2(200),
cod_artist NUMBER, -- artist
an_nastere VARCHAR2(4),
an_moarte VARCHAR2(4),
nationalitate VARCHAR2(40));
A fost introdus o coloan suplimentar (cod_tip) care desemneaz tipul nregistrrii. Ea
poate avea trei valori (1, 2 sau 3) n funcie de tipul care trebuie asociat liniei respective (t_persoana,
t_autor, respectiv t_artist). Vizualizrile din ierarhia de vizualizri obiect sunt definite dup cum
urmeaz. Fiecare instan obiect sintetizat n cadrul unei vizualizri corespunde unei linii din tabel.
CREATE VIEW viz_persoane OF t_persoana
WITH OBJECT IDENTIFIER(cod)
AS SELECT cod, nume
FROM ToatePersoanele
WHERE cod_tip = 1;
CREATE VIEW viz_autori OF t_autor UNDER viz_persoane
AS SELECT cod, nume, cod_autor, ocupatie, descriere
FROM ToatePersoanele
WHERE cod_tip = 2;
CREATE VIEW viz_artisti OF t_artist UNDER viz_persoane
AS SELECT cod, nume, cod_artist,
an_nastere, an_moarte, nationalitate
FROM ToatePersoanele
WHERE cod_tip = 3;
Modelul flat are avantajul simplitii i nu genereaz nici un obstacol n crearea indecilor i a
constrngerilor.
Unul dintre dezavantajele acestui model este c un singur tabel poate avea cel mult 1000 de
coloane. Astfel, modelul flat impune aceast limit asupra numrului total de coloane pe care le poate
conine ierarhia de vizualizri obiect. De asemenea, fiecare linie a tabelului are multe valori null
asociate atributelor care nu aparin celui mai specific tip al liniei curente. Aceste valori pot afecta
performanele operaiilor asupra vizualizrilor.

Modelul orizontal
n modelul orizontal, fiecrei vizualizri sau subvizualizri i corespunde un tabel distinct.
Tabelele de baz pot fi relaionale, respectiv tabele obiect pentru care substituibilitatea coloanelor este
dezactivat.
CREATE TABLE doar_persoane (
cod NUMBER,
nume VARCHAR2(50));
CREATE TABLE doar_autori (
Orientare pe obiecte n Oracle9i 119

cod NUMBER,
nume VARCHAR2(50),
cod_autor NUMBER,
ocupatie VARCHAR2(30),
descriere VARCHAR2(200));
CREATE TABLE doar_artisti (
cod NUMBER,
nume VARCHAR2(50),
cod_artist NUMBER,
an_nastere VARCHAR2(4),
an_moarte VARCHAR2(4),
nationalitate VARCHAR2(40));
n acest caz, la construirea vizualizrilor nu sunt necesare join-uri. Fiecrei vizualizri din
ierarhie i corespunde un tabel relaional. De asemenea, o instan obiect este sintetizat dintr-o
singur linie a unui tabel de baz al modelului.
CREATE VIEW viz_persoane OF t_persoana
WITH OBJECT IDENTIFIER(cod)
AS SELECT *
FROM doar_persoane ;
CREATE VIEW viz_autori OF t_autor UNDER viz_persoane
AS SELECT *
FROM doar_autori;
CREATE VIEW viz_artisti OF t_artist UNDER viz_persoane
AS SELECT *
FROM doar_artisti;
Modelul orizontal este util pentru executarea eficient a interogrilor care selecteaz
nregistrri corespunztoare unui anumit nivel de specializare.
Exemplu:
S se selecteze informaii complete despre toi artitii din vizualizarea viz_persoane. Trebuie
afiate informaii referitoare numai la instanele care au cel mai specific tip t_artist.
SELECT VALUE(p)
FROM viz_persoane p
WHERE VALUE(p) IS OF (ONLY t_artist);
Astfel de cereri acceseaz un singur tabel fizic pentru a returna obiectele de tipul specificat.
Dezavantajele modelului sunt acelea c interogrile de tipul SELECT * FROM vizualizare necesit
executarea unui operator UNION asupra tuturor tabelelor de baz i apoi proiectarea liniilor doar
asupra coloanelor din vizualizarea dat. De asemenea, modelul nu permite crearea de indeci sau
constrngeri de tip UNIQUE asupra atributelor tipurilor. Acestea ar trebui s acioneze asupra mai
multor tabele i acest lucru nu este posibil.

Modelul vertical
n modelul vertical nu exist o coresponden ntre un tabel fizic i o vizualizare din ierarhie.
Fiecare tabel fizic stocheaz doar acele atribute care sunt unice subtipului corespondent lui.
CREATE TABLE ToatePersoanele (
cod_tip NUMBER,
cod NUMBER,
120 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

nume VARCHAR2(50));
CREATE TABLE TotiAutorii (
cod NUMBER,
cod_autor NUMBER,
ocupatie VARCHAR2(30),
descriere VARCHAR2(200));
CREATE TABLE TotiArtistii (
cod NUMBER,
cod_artist NUMBER,
an_nastere VARCHAR2(4),
an_moarte VARCHAR2(4),
nationalitate VARCHAR2(40));
Similar modelului flat, este necesar definirea unei coloane suplimentare pentru identificarea
tipului (cod_tip). Aceast coloan este inclus numai n tabelul referitor la persoane
(ToatePersoanele). O instan obiect este sintetizat din unul sau mai multe tabele relaionale ale
modelului. Atributele specifice fiecrui tip obiect din ierarhia implementat sunt obinute prin
intermediul join-ului dintre tabelele asociate tuturor tipurilor ce apar pe drumul de la tipul rdcin
pn la tipul respectiv. Legtura dintre tabelele modelului, se face prin cheia primar cod, care este
utilizat i ca identificator obiect.
CREATE VIEW viz_persoane OF t_persoana
WITH OBJECT IDENTIFIER (cod)
AS SELECT cod, nume
FROM ToatePersoanele
WHERE cod_tip = 1;
CREATE VIEW viz_studenti OF t_autor UNDER viz_persoane
AS SELECT p.cod, p.nume,
au.cod_autor, au.ocupatie, au.descriere
FROM ToatePersoanele p, TotiAutorii au
WHERE p.cod_tip = 2
AND au.cod = p.cod;
CREATE VIEW viz_artisti OF t_artist UNDER viz_persoane
AS SELECT p.cod, p.nume, ar.cod_artist, ar.an_nastere,
ar.an_moarte, ar.nationalitate
FROM ToatePersoanele p, TotiArtistii ar
WHERE p.cod_tip = 3
AND ar.cod = ar.cod;
Folosind modelul vertical, se pot procesa eficient cererile de tip SELECT * FROM
viz_rdcina. De asemenea, este posibil s se indexeze i s se impun constrngeri de unicitate
asupra atributelor individuale. n schimb, pentru a recrea o instan a unui tip, altul dect tipul
rdcin, trebuie executat cel puin un join. Acest lucru poate reduce din performane.

Interogarea unei vizualizri dintr-o ierarhie


Orice vizualizare sau subvizualizare dintr-o ierarhie de vizualizri obiect poate fi interogat,
fiind returnate liniile corespunztoare att tipului asociat vizualizrii interogate, ct i ale subtipurilor
acestuia.
De exemplu, n ierarhia de vizualizri obiect bazat pe ierarhia de tipuri cu rdcina
t_persoana, se poate interoga vizualizarea viz_persoane pentru a regsi o mulime rezultat care
Orientare pe obiecte n Oracle9i 121

conine toate persoanele, inclusiv autori i artiti. Similar interogrii tabelelor obiect, n lista SELECT
pot fi incluse funciile REF i VALUE, ce returneaz instane obiect, sau se pot specifica atributele
obiectelor de tipul declarat al vizualizrii (de exemplu, nume i cod pentru tipul t_persoana).
Att specificarea atributelor asociate tipului declarat al unei vizualizri, ct i utilizarea
funciilor care ntorc instane obiect asigur returnarea unui set polimorfic de date, adic instane de
tipul vizualizrii i de subtipurile acestuia.
Exemplu:
S se introduc nregistrri corespunztoare fiecrui tip de date din ierarhia avnd tipul
rdcin t_persoana (se consider modelul orizontal). S se afieze instanele persoanelor, artitilor,
autorilor i referinele la aceste instane.
INSERT INTO doar_persoane (cod, nume)
VALUES (1, 'George Ionescu');
INSERT INTO doar_artisti
(cod, nume, cod_artist, an_nastere, an_moarte, nationalitate)
VALUES (2, 'Constantin Brancusi', 1, 1876, 1957, 'romana');
INSERT INTO doar_autori
(cod, nume, cod_autor, ocupatie, descriere)
VALUES (3, 'Irving Stone', 1, 'scriitor', 'Michelangelo');
COMMIT;
SELECT VALUE (p) , REF (p)
FROM viz_persoane p;
n cazul specificrii n lista SELECT a atributelor individuale ale tipului asociat vizualizrii
sau a caracterului *, liniile sunt proiectate pe coloanele asociate atributelor tipului declarat al
vizualizrii i nu sunt afiate dect aceste coloane. Cu alte cuvinte, subtipurile sunt afiate respectnd
doar atributele pe care le motenesc de la tipul declarat al vizualizrii.
Pentru a exclude subvizualizrile din rezultat, se folosete cuvntul cheie ONLY. Acesta
rafineaz selecia, permind obinerea doar a obiectelor pentru care cel mai specific tip este identic cu
tipul vizualizrii interogate.
Exemplu:
S se afieze informaii complete despre toate persoanele (inclusiv artitii i autorii).
Rezultatul utilizeaz doar coloanele corespunztoare atributelor tipului t_persoana (nume i cod) i nu
listeaz atributele specifice subtipurilor. De asemenea, s se afieze codul i numele persoanelor,
excluzndu-le pe cele care sunt artiti sau autori.
SELECT * FROM viz_persoane;
SELECT VALUE(p) FROM ONLY (viz_persoane) p;

Privilegii asupra ierarhiilor obiectuale

De obicei, o cerere asupra unei vizualizri care are subvizualizri necesit privilegiul SELECT
doar asupra vizualizrii referite i nici un privilegiu explicit asupra subvizualizrilor. De exemplu,
cererea SELECT * FROM viz_persoane impune existena privilegiului SELECT asupra vizualizrii
viz_persoane, dar nu i asupra subvizualizrilor acesteia, viz_artisti i viz_autori.
O interogare care selecteaz toate atributele din subtipuri, dar nu utilizeaz tipul rdcin
necesit privilegiul SELECT asupra tuturor subvizualizrilor. Acest lucru se ntmpl deoarece
atributele subtipurilor pot conine informaii importante care necesit privilegii adiionale de acces.
122 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

n consecin, pentru cererea SELECT VALUE(p) FROM viz_persoane p este necesar


privilegiul SELECT att asupra viz_persoane, ct i asupra subvizualizrilor viz_autori, viz_artisti
(sau asupra oricrei alte subvizualizri a lui viz_persoane).
Pentru a facilita procesul de acordare a privilegiilor SELECT asupra unei ntregi ierarhii, se
poate utiliza opiunea HIERARCHY. Aceast clauz determin acordarea automat a privilegiului
SELECT asupra tuturor subvizualizrilor curente i viitoare ale vizualizrii respective.
Exemplu:
S i se acorde utilizatorului student privilegiul de selectare asupra vizualizrii viz_persoane i
asupra tuturor subvizualizrilor acesteia.
GRANT SELECT ON viz_persoane TO student
WITH HIERARCHY OPTION;
Informaia relativ la cel mai specific tip al instanelor selectate dintr-o vizualizare poate fi
important. De aceea, o cerere care exclude liniile ce aparin unor subvizualizri presupune acordarea
privilegiilor SELECT asupra tuturor subvizualizrilor. De exemplu, cererea SELECT * FROM ONLY
(viz_persoane) necesit privilegii de selectare asupra tuturor subvizualizrilor lui viz_persoane.

5.4. Modificarea vizualizrilor obiect


Asupra unei vizualizri obiect se pot executa operaii LMD n mod similar tabelelor obiect. La
iniierea unei comenzi LMD, dac nu exist vreo amiguitate n definiia vizualizrii, sistemul modific
tabelele de baz ale acesteia.
Dup cum s-a precizat, o vizualizare nu poate fi modificat prin comenzi LMD dac
interogarea asociat vizualizrii conine join-uri, operatori SET, funcii grup, clauze GROUP BY sau
DISTINCT. De asemenea, coloanele individuale ale unei vizualizri nu se pot modifica dac sunt
bazate pe pseudocoloane sau expresii.
Chiar dac o vizualizare nu este modificabil n mod direct, ea poate fi totui modificat n
mod indirect, utiliznd declanatori de tip INSTEAD OF. ntr-un declanator de acest tip se
implementeaz operaiile care trebuie s aib loc asupra tabelelor de baz ale vizualizrii obiect, la
iniierea unei comenzi LMD. Atunci cnd se lanseaz o comand LMD pentru care este prevzut un
declanator, sistemul execut n mod transparent declanatorul asociat.
ntr-o ierarhie de vizualizri obiect, legtura dintre acestea rmne vie. De aceea, la fel ca
interogrile asupra vizualizrilor obiect, comenzile UPDATE i DELETE opereaz polimorfic. Cu alte
cuvinte, setul de linii afectate de o comand UPDATE sau DELETE asupra unei vizualizri include n
mod implicit liniile care ndeplinesc condiia respectiv din orice subvizualizare.
Exemplu:
a) S se elimine nregistrrile din vizualizarea viz_persoane, inclusiv cele referitoare la
artiti i autori. Apoi, s se elimine nregistrrile din aceast vizualizare, excluzndu-le pe cele relative
la artiti sau autori.
DELETE FROM viz_persoane;
ROLLBACK;
DELETE FROM ONLY (viz_persoane);
b) S se modifice numele tuturor persoanelor ce nu sunt autori sau artiti.
UPDATE ONLY (viz_persoane)
Orientare pe obiecte n Oracle9i 123

SET nume = 'Nume nou';


Asemntor unui tabel obinuit, un tablou imbricat poate fi modificat prin inserarea de noi
elemente, prin actualizarea sau tergerea elementelor existente. n general, coloanele de tip tablou
imbricat sintetizate n cadrul unei vizualizri nu se pot modifica direct. n schimb, sistemul Oracle
permite crearea declanatorilor INSTEAD OF asupra coloanelor de tip tablou imbricat.
Declanatorul de tip INSTEAD OF definit asupra unei coloane de tip tablou imbricat dintr-o
vizualizare se execut cnd coloana respectiv este modificat. Dac ntreaga colecie este nlocuit
(de exemplu, printr-o modificare a liniei printe), declanatorul asociat coloanei de tip tablou
imbricat nu este executat.
Declanatorii INSTEAD OF asigur o modalitate de modificare a vizualizrilor complexe care
altfel nu ar putea fi modificate. De asemenea, ei pot fi folosii pentru asigurarea constrngerilor,
verificarea privilegiilor sau validarea operaiilor LMD. Utiliznd aceti declanatori se pot controla
obiectele n schimbare (mutating) prin intermediul vizualizrii obiect.
Exemplu:
S se creeze un declanator care s implementeze constrngerea prin care numrul operelor de
art dintr-o galerie nu poate depi 100. Se presupune c tabelul tab_opere are o coloan de tip
referin, ref_gal, ce adreseaz galeria din care face parte fiecare oper de art. Pentru materializarea
obiectului referit de coloana ref_gal se utilizeaz procedura SELECT_OBJECT din pachetul
UTL_REF.
CREATE OR REPLACE TRIGGER t_ins_opere
INSTEAD OF INSERT ON viz_opere
FOR EACH ROW
DECLARE
v_gal t_galerie;
v_nr_opere PLS_INTEGER;
BEGIN
--mai intai gaseste codul galeriei utilizand referinta
UTL_REF.SELECT_OBJECT (:NEW.ref_gal, v_gal);
SELECT COUNT(cod) INTO v_nr_opere
FROM tab_opere
WHERE cod_gal = v_gal.cod;
IF v_nr_opere < 99 THEN
--se poate insera
INSERT INTO tab_opere
(cod, titlu, tip, valoare, cod_artist, cod_gal)
VALUES (:NEW.cod, :NEW.titlu, :NEW.tip, :NEW.valoare,
:NEW.cod_artist, v_gal.cod);
ELSE
RAISE_APPLICATION_ERROR (-20101, 'Galeria avand codul '||
v_gal.cod || ' a atins limita de 100 de opere de arta');
END IF;
END;
/
124 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

6. Large Objects

nc de la mijlocul anilor '90, productorii sistemelor de gestiune a bazelor de date au luat n


considerare necesitatea implementrii unor modaliti de organizare i prelucrare a datelor
nestructurate (text, imagine, video, sunet). Aceasta a generat apariia unor noi tipuri de date, care
faciliteaz adaptarea sistemelor de baze de date pentru domenii noi de aplicaii n informatic (sisteme
geografice, medicale, tiinifice etc.).

Preliminarii
Deoarece aplicaiile de baze de date trebuie s asigure o semantic din ce n ce mai complex,
apare necesitatea de a organiza informaia utiliznd diverse categorii de date, simplu i complex
structurate, semistructurate sau nestructurate.
Modelul relaional este potrivit pentru stocarea datelor simplu structurate. Sistemul Oracle a
adugat caracteristicile obiectuale, astfel nct aplicaiile s poat lucra cu date complex structurate
(colecii, referine, obiecte). Tehnologiile Oracle de gestiune a cozilor de mesaje, cum ar fi Advanced
Queueing, lucreaz cu date semistructurate (de exemplu, date n format XML).
Pentru a asigura gestiunea datelor nestructurate, au fost introduse tipurile de date LOB.
Principalele caracteristici ale datelor nestructurate sunt urmtoarele:
nu pot fi descompuse n componente standard (de exemplu, dac i se asociaz fiecrei
opere de art o imagine, atunci, din punct de vedere fizic, informaia este un ir de bii
care nu poate fi stocat folosind tipurile standard ale bazei de date);
au dimensiuni mari (o nregistrare de tip t_opera_de_arta poate avea cteva sute de
octei, dar chiar i cele mai restrnse date multimedia poate avea de o mie de ori mai
mult);
pot fi stocate n fiierele sistemului de operare gazd, dar trebuie s poat fi accesate n
mod eficient de ctre baza de date.
Odat cu rspndirea Internet-ului i a aplicaiilor bazate pe coninut, a devenit imperativ ca
baza de date:
s asigure tipuri de date pentru stocarea informaiilor nestructurate;
s fie optimizat pentru gestiunea cantitilor mari de date;
s asigure o modalitate uniform de acces la datele nestructurate, stocate n interiorulul
bazei de date sau n afara ei.

Tipuri de date i obiecte LOB


Obiectele LOB (large object) sunt folosite pentru stocarea, n interiorul sau exteriorul bazei de
date, a unui volum mare de date complexe, nestructurate, n format text sau binar. Tipul de date LOB
permite stocarea unor blocuri de date avnd cel mult 4 GB.
Orientare pe obiecte n Oracle9i 125

n Oracle7, aplicaiile care stocau cantiti mari de date nestructurate utilizau tipurile LONG
sau LONG RAW. Avantajele utilizrii tipurilor LOB din versiunile Oracle8i i Oracle9i fa de tipurile
LONG i LONG RAW, care au fost pstrate pentru compatibilitate, sunt urmtoarele:
capacitatea superioar a tipurilor LOB (obiectele de tip LOB au capacitatea de dou ori
mai mare);
posibilitatea definirii mai multor coloane LOB ntr-un tabel (un tabel n Oracle9i poate
avea mai multe coloane de tip LOB, fiecare de un tip diferit, n timp ce tipurile LONG sau
LONG RAW pot fi folosite cel mult o dat ntr-un tabel);
accesul aleator pe seciuni care nu este valabil n cazul tipului LONG.
Urmtoarele restricii referitoare la tipul LOB au fost eliminate n Oracle9i.
Se pot defini orice tip de declanatori asupra tabelelor ce conin coloane de tip LOB.
Suportul pentru atributele NEW asociate declanatorilor de tip BEFORE la nivel de linie a
fost extins pentru coloanele de tip LOB.
Se pot defini coloane de tip LOB n cadrul spaiilor tabel gestionate local (locally
managed tablespaces) i a celor cu gestiune automat a segmentelor (AUTO segment-
managed tablespaces).
Tipul NCLOB este permis pentru a defini atribute ale tipurilor obiect.
Se pot crea tabele partiionate organizate pe baz de index care s conin obiecte de tip
LOB.
Rutinele pachetului DBMS_LOB pot fi invocate n procedurile de pe maina client (client-
side).
Este permis inserarea i modificarea nregistrrilor ce conin obiecte de tip LOB, n cazul
unei vizualizri asupra creia s-a definit un declanator de tip INSTEAD OF.
n funcie de localizarea lor fa de baza de date, sistemul Oracle9i mparte tipurile de date
LOB n dou categorii:
tipuri interne (BLOB, CLOB i NCLOB), stocate n baza de date;
tipuri externe (BFILE), stocate n fiierele sistemului de operare.
Obiectele LOB interne pot fi persistente sau temporare. Datele de tip LOB interne sunt stocate
n cadrul spaiilor tabel ale bazei de date, astfel nct se optimizez utilizarea spaiului de stocare i se
asigur acces eficient la informaii.
Exist trei tipuri de date LOB interne:
tipul BLOB (Binary Large Object), ale crui valori sunt compuse din date binare
nestructurate;
tipul CLOB (Character Large Object), ale crui valori sunt compuse din iruri de
caractere, ce aparin setului de caractere specificat la nivelul bazei de date (DCS);
tipul NCLOB (National Character Large Object), ale crui valori conin iruri de
caractere, ce aparin mulimii de caractere naionale (NCS) definit la nivel de nivelul
bazei de date.
Obiectele LOB externe (BFILE - binary file) sunt structuri de dimensiuni mari ce conin date
binare, stocate n afara spaiilor tabel ale bazei de date.
Tipul de date BFILE asigur acces secvenial de tip read-only asupra datelor din fiierele
sistemului gazd ale server-ului de baze de date. Singura condiie este ca sistemul de operare al
server-ului s permit acces secvenial asupra acestor fiiere.
126 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Valori LOB i locatori


Un obiect de tip LOB are dou componente:
valoarea propriu-zis;
locatorul obiectului (o adres care permite regsirea informaiei).
Valoarea unui obiect LOB intern poate s fie stocat n cadrul tabelului, mpreun cu celelalte
date din nregistrare sau n afara acestuia. Dac nu se dezactiveaz stocarea la nivel de nregistrare
(inline) prin intermediul opiunii DISABLE STORAGE IN ROW din comanda CREATE TABLE, iar
valoarea de tip LOB este mai mic de 4 KB, atunci ea este stocat inline. n caz contrar, valoarea este
stocat n afara tabelului (out-of-line). Deoarece obiectele LOB sunt adesea de dimensiune mare,
stocarea inline va fi relevant doar dac aplicaia folosete att obiecte LOB de dimensiune redus, ct
i obiecte mari.
Chiar dac este specificat modalitatea de stocare, sistemul detecteaz automat i stocheaz
out-of-line, obiectele de tip LOB a cror dimensiune depete limita admis de 4 KB.
Locatorul este similar unei referine la locaia real a valorii LOB. Acesta este stocat
ntotdeauna inline. Un locator se numete intern sau extern dup cum valoarea LOB asociat este
stocat intern, respectiv extern.
Pentru obiectele LOB interne, coloana LOB menine un locator ctre valoarea LOB care este
stocat ntr-un spaiu tabel al bazei de date. Fiecare valoare LOB dintr-o nregistrare, respectiv atribut
al unui obiect are propriul locator i cte o copie distinct a valorii LOB, stocat n spaiul tabel
corespunztor tabelului din care face parte.
Pentru obiectele LOB externe, coloanele stocheaz doar locatorii ctre fiierele asociate din
sistemului de operare. Fiecare valoare sau atribut BFILE al unei nregistrri are propriul locator
BFILE. Dou nregistrri diferite pot conine un locator care s refere acelai fiier al sistemului de
operare.
Utilizarea obiectelor de tip LOB
Tipurile de date LOB pot fi folosite pentru definirea de atribute sau coloane n cadrul tipurilor
obiect, respectiv n cadrul tabelelor relaionale. ntr-un tabel pot exista mai multe coloane de tip LOB,
iar tipurile obiect pot utiliza valori LOB att pentru atribute, ct i pentru parametrii metodelor
asociate.
Exemplu:
S se defineasc tipul obiect t_opera care s conin coloanele descriere de tip CLOB, foto de
tip BLOB i reportaj de tip BFILE.
CREATE OR REPLACE TYPE t_opera AS OBJECT (
cod NUMBER,
titlu VARCHAR2(30),
tip VARCHAR2(10),
cod_artist NUMBER,
descriere CLOB,
foto BLOB,
reportaj BFILE);
/
Pentru a crea obiectele LOB interne, mai nti se folosc comenzi SQL pentru definirea
tabelelor care conin coloane LOB i pentru iniializarea locatorilor asociai acestor coloane.
nainte de a utiliza un obiect LOB intern, coloana sau atributul corespunztor LOB trebuie s
conin un locator. De aceea, iniializarea obiectului LOB cu unul vid este obligatorie (un obiect vid
Orientare pe obiecte n Oracle9i 127

este diferit de un obiect null prin faptul c acesta din urm nu conine un locator). Acest lucru se poate
realiza n SQL sau PL/SQL utiliznd funciile predefinite EMPTY_BLOB() pentru BLOB i
EMPTY_CLOB() pentru CLOB sau NCLOB.
Exemplu:
S se defineasc tabelul obiect tab_opere, asociat tipului t_opera creat anterior. S se insereze
i s se modifice o nregistrare n acest tabel.
CREATE TABLE tab_opere OF t_opera
(CONSTRAINT cod_nn CHECK (cod IS NOT NULL),
descriere DEFAULT EMPTY_CLOB());
INSERT INTO tab_opere
(cod, titlu, tip, cod_artist, foto, reportaj)
VALUES (15, 'Spirit', 'sculptura', 1, EMPTY_BLOB(), NULL);
UPDATE tab_opere
SET descriere = 'Material%Lemn%An%1857%Stil%modern%'
WHERE cod = 15;
Similar definirii tabelelor externe, pentru a crea obiecte LOB externe trebuie creat un obiect
de tip DIRECTORY (director logic). Acesta este un obiect al schemei prin care se specific un alias
pentru un director fizic, ce va conine obiectele LOB externe care vor fi accesate. Pentru a fi procesate
de ctre server-ul Oracle, fiierele referite trebuie s existe i s aib permisiuni de citire.
Alias-ul trebuie creat nainte de a efectua operaii asupra obiectelor BFILE. Comanda de
creare a unui director are urmtoarea form:
CREATE DIRECTORY nume_dir AS 'cale';
Identificatorul cale este un ir de caractere care determin adresa directorului fizic respectiv.
Dac sistemul de operare utilizeaz identificatori case sensitive, atunci specificarea directorului fizic
trebuie s respecte acest lucru.
Suprimarea unui director din dicionarul datelor se face prin comanda:
DROP DIRECTORY nume_dir;
Similar obiectelor interne, obiectele LOB externe (BFILE) trebuie s fie iniializate astfel
nct s refere un fiier al sistemului de operare. Acest lucru se realizeaz prin intermediul funciei
BFILENAME(), care primete ca parametri un director logic creat anterior i numele fiierului asociat.
De remarcat c funcia BFILENAME() nu verific existena fizic a directorului.
Exemplu:
S se introduc o nregistrare n tabelul tab_opere. S se ataeze celor dou nregistrri
existente n tabel, fiierele externe ce conin reportajele asociate. Se presupune c aceste fiiere se afl
n directorul fizic E:\reportaje\.
CREATE OR REPLACE DIRECTORY dir_reportaje AS
'E:\reportaje\';
INSERT INTO tab_opere
(cod, titlu, tip, cod_artist, descriere, foto, reportaj)
VALUES (25, 'Soare', 'pictura', 1,
'Material%Panza%An%1858%Stil%cubist%', EMPTY_BLOB(),
BFILENAME ('dir_reportaje', 'soare.mpeg'));
UPDATE tab_opere
SET reportaj = BFILENAME('dir_reportaje','spirit.mpeg')
128 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

WHERE cod = 15;


Prelucrarea i gestiunea cmpurilor de tip LOB se face fie integral, cu ajutorul comenzilor
LMD, fie pe poriuni, folosind pachetul DBMS_LOB.
n operaiile de prelucrare, pentru obiectele LOB interne se utilizeaz semantica de copiere (se
copiaz att locatorul ct i valoarea LOB), iar pentru obiectele LOB externe se utilizeaz semantica
referin (este copiat doar locatorul).
Semantica de copiere folosit de obiectele LOB interne (persistente sau temporare) presupune
c, atunci cnd se insereaz sau se actualizeaz un obiect de tip LOB, este copiat ntreaga valoare
LOB. Astfel, n urma operaiei rezult doi locatori diferii i dou copii diferite ale valorii LOB.
Aceast aciune nu necesit o comand de tip SELECTFOR UPDATE, deoarece blocarea
nregistrrii se face doar atunci cnd se fac modificri pe poriuni.
Semantica referin utilizat de obiectele LOB externe presupune c, atunci cnd este copiat
un obiect BFILE din nregistrarea unui tabel n alt coloan de tip BFILE, se reine doar locatorul
asociat.
Pentru tergerea unei nregistrri care conine un cmp de tip LOB se utilizeaz comanda
DELETE. n acest fel, se terge i valoarea intern a obiectului LOB. Pentru a terge doar instana
LOB, i nu ntreaga nregistrare, se atribuie cmpului LOB valoarea null, irul vid sau rezultatul unei
funcii de tip EMPTY (EMPTY_BLOB sau EMPTY_CLOB).
n cazul unui fiier BFILE, fiierul asociat nu este eliminat automat, el trebuie ters n mod
explicit, utiliznd comenzi ale sistemului de operare.
Exemplu:
S se elimine valorile de tip LOB din tabelul tab_opere, iar apoi s se anuleze comenzile.
-- se elimina intreaga inregistrare
DELETE FROM tab_opere
WHERE cod = 15;
-- se elimina doar instantele LOB
BEGIN
UPDATE tab_opere
SET foto = EMPTY_BLOB(),
reportaj = NULL,
descriere = EMPTY_CLOB()
WHERE cod = 25;
END;
/
ROLLBACK;
Sistemul Oracle asigur suport pentru funcionalitatea necesar obiectelor LOB n opt
interfee i precompilatoare specifice diferitelor limbaje i medii de programare existente. Acestea
sunt prezentate n tabelul care urmeaz.
Medii de programare care suport funcionalitatea LOB
Limbaj/Mediu de programare Precompilator sau interfa
PL/SQL Pachetul predefinit DBMS_LOB
C Oracle Call Interface pentru C (OCI)
C++ Oracle Call Interface for C++ (OCCI)
C/C++ Precompilatorul Pro*C/C++
COBOL Precompilatorul Pro*COBOL
Visual Basic Oracle Objects for OLE (OO4O)
Orientare pe obiecte n Oracle9i 129

Java JDBC Application Programatic Interface (API)


OLEDB OraOLEDB

Pachetul DBMS_LOB
Pachetul DBMS_LOB conine subprograme pentru prelucrarea datelor de tip BLOB, CLOB,
NCLOB, BFILE i pentru obiectele de tip LOB temporare.
Pachetul DBMS_LOB poate fi folosit pentru a efectua:
operaii de citire sau modificare, n ntregime ori pe seciuni, asupra obiectelor LOB
interne, att persistente, ct i temporare;
operaii de citire pentru obiectele de tip BFILE.
Rutinele DBMS_LOB utilizeaz locatorii LOB. Pentru succesul unei rutine DBMS_LOB
trebuie furnizat un locator valid, diferit de null, care garanteaz existena valorii LOB la invocarea
rutinei.
Locatorii LOB corespunztori obiectelor stocate pot fi selectai ntr-o variabil local PL/SQL.
Aceast variabil se poate utiliza ca parametru de intrare n subprogramele DBMS_LOB pentru
accesarea valorii LOB. Utilizarea unui locator care a fost setat null, pentru a accesa sau prelucra o
valoare LOB, va duce la apariia unei excepii (INVALID_ARGVAL).
Procedurile PL/SQL de pe maina client (de exemplu, cele utilizate de Oracle Forms) nu pot
accesa rutinele DBMS_LOB. n schimb, procedurile stocate pe server sau blocurile anonime
Pro*C/C++ pot apela aceste rutine.
Pachetul DBMS_LOB conine urmtoarele constante:
FILE_READONLY de tip BINARY_INTEGER (valoarea 0);
LOB_READONLY de tip BINARY_INTEGER (valoarea 0);
LOB_READWRITE de tip BINARY_INTEGER (valoarea 1);
LOBMAXSIZE de tip INTEGER (valoarea 4294967295);
CALL de tip PLS_INTEGER (valoarea 12);
SESSION de tip PLS_INTEGER (valoarea 10).
Ca regul general a rutinelor DBMS_LOB, parametrii de tip CLOB i NCLOB sunt
specificai n caractere, iar parametrii de tip BLOB i BFILE n octei. De asemenea, parametrii de tip
ntreg care determin poziia sau cantitatea corespunztoare unui obiect de tip LOB sunt exprimai n
numr de caractere pentru NCLOB i CLOB, iar pentru BFILE i BLOB, n octei. De obicei,
parametrii care determin poziia ntr-o valoare LOB au valoarea implicit 1.
Pentru citirea sau examinarea valorilor LOB interne sau externe, se pot utiliza rutinele
prezentate n cele ce urmeaz.
Funcia COMPARE (lob_1, lob_2, cantitate, poz_1, poz_2) compar dou valori de tip
LOB (interne sau externe). Aceast funcie returneaz 0 dac cele dou valori sunt egale i
o valoare diferit de zero, n caz contrar. Valoarea returnat este null dac poz_1, poz_2
sau cantitate nu sunt cuprinse ntre 1 i LOBMAXSIZE.
Funcia GETCHUNKSIZE (locator) returneaz dimensiunea unitii folosite la
citire/scriere (permis doar cu valori de tip LOB interne).
Funcia GETLENGTH (lob_locator) returneaz dimensiunea valorii de tip LOB (intern
sau extern).
Funcia INSTR (locator, text, poz, n) returneaz poziia celei de-a n-a apariii a unui text
ntr-o valoare de tip LOB (intern sau extern), cutarea ncepnd de la poziia specificat.
130 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Procedura READ (locator, cantitate, poz, buffer) citete o anumit cantitate de date dintr-
o valoare de tip LOB, ncepnd de la poziia specificat (dac se ajunge la sfritul
obiectului este declanat eroarea NO_DATA_FOUND).
Funcia SUBSTR (locator, cantitate, poz) returneaz o poriune din valoarea de tip LOB,
ncepnd de la poziia specificat.
Exemplu:
S se selecteze informaiile coninute n descrierea operei de art avnd codul 15. n cmpul
descriere sunt stocate materialul, anul crerii i stilul, n aceast ordine. Caracterul de separare este
%. De asemenea, se va lista lungimea descrierii i dimensiunea unitii de citire/scriere pentru
fotografia ataat operei.
DECLARE
v_descriere CLOB;
v_foto BLOB;
v_cod tab_opere.cod%TYPE := 15;
v_material VARCHAR2(20);
v_an NUMBER;
v_stil VARCHAR2(20);
v_final BOOLEAN;
TYPE t_tabel IS TABLE OF VARCHAR2(20)
INDEX BY PLS_INTEGER;
info t_tabel;
i PLS_INTEGER;
pos_in PLS_INTEGER;
pos_fin PLS_INTEGER;
v_ecod NUMBER;
v_errm VARCHAR2(150);
BEGIN
SELECT descriere, foto INTO v_descriere, v_foto
FROM tab_opere
WHERE cod = v_cod;
DBMS_OUTPUT.PUT_LINE('Dimensiune CLOB este: ' ||
DBMS_LOB.GETLENGTH(v_descriere));
DBMS_OUTPUT.PUT_LINE('Dimensiune unitate BLOB este: ' ||
DBMS_LOB.GETCHUNKSIZE (v_foto));
v_final := FALSE;
i := 1;
pos_in := 0;
pos_fin := INSTR (v_descriere, '%', 1, i);
LOOP
IF pos_fin != 0 THEN
info (i) := SUBSTR (v_descriere,
Pos_in + 1, pos_fin - pos_in - 1);
i := i + 1;
pos_in := pos_fin;
pos_fin := INSTR(v_descriere, '%', 1, i);
ELSE
v_final := TRUE;
END IF;
EXIT WHEN v_final;
END LOOP;
FOR i IN info.FIRST..info.LAST LOOP
DBMS_OUTPUT.PUT (info(i) ||'-');
Orientare pe obiecte n Oracle9i 131

IF i MOD 2 = 0 THEN
DBMS_OUTPUT.NEW_LINE;
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
v_ecod := SQLCODE;
v_errm := SUBSTR( SQLERRM, 1, 150);
RAISE_APPLICATION_ERROR (-20100, v_ecod || '-' || v_errm);
END;
/
Rezultatul execuiei blocului PL/SQL anterior este urmtorul:
Dimensiune LOB este: 34
Dimensiune unitate BLOB este: 8132
Material-Lemn-
An-1857-
Stil-modern-
Urmtoarele subprograme din pachetul DBMS_LOB sunt prevzute pentru prelucrarea
obiectelor LOB temporare.
Procedura CREATETEMPORARY (locator, cache, durata) creeaz un obiect de tip LOB
intern temporar. Valoarea boolean cache specific dac obiectul va fi adus n zona de
memorie cache, iar durata este un cod (10 sau 12) care precizeaz durata de via a
obiectului temporar. Durata poate fi sesiunea curent (DBMS_LOB.SESSION) sau apelul
curent (DBMS_LOB.CALL).
Funcia ISTEMPORARY (locator) verific dac un obiect LOB intern este obiect
temporar. n caz afirmativ, funcia returneaz valoarea 1.
Procedura FREETEMPORARY (locator) elibereaz o valoare de tip LOB temporar.
Locatorul dat ca parametru este marcat invalid.
Exemplu:
S se creeze i s se iniializeze dou obiecte de tip LOB temporare, pentru stocarea irurilor
de caractere. S se compare parial cele dou obiecte.
DECLARE
v_temp1 CLOB;
v_temp2 CLOB;
v_sir VARCHAR2(10) := '1234567890';
buffer1 VARCHAR2(1);
buffer2 VARCHAR2(2);
v_cant PLS_INTEGER := 1;
v_ecod NUMBER;
v_errm VARCHAR2(150);
BEGIN
DBMS_LOB.CREATETEMPORARY (v_temp1, TRUE, DBMS_LOB.SESSION);
DBMS_LOB.CREATETEMPORARY (v_temp2, TRUE, DBMS_LOB.SESSION);
DBMS_LOB.WRITE (v_temp1, LENGTH(v_sir), 1, v_sir);
-- v_temp1 contine 1234567890
DBMS_OUTPUT.PUT_LINE (DBMS_LOB.SUBSTR (v_temp1, 10));
DBMS_LOB.COPY (v_temp2, v_temp1, 5, 1, 5);
-- v_temp2 contine 56789
DBMS_OUTPUT.PUT_LINE (DBMS_LOB.SUBSTR (v_temp2, 5));
132 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

-- se compara al saselea caracter din v_temp1 cu


-- al doilea caracter din v_temp2
DBMS_LOB.READ (v_temp1, v_cant, 6, buffer1);
DBMS_LOB.READ (v_temp2, v_cant, 2, buffer2);
DBMS_OUTPUT.PUT (' se compara caracterul ' || buffer1
|| ' cu ' || buffer2 || ' rezultatul fiind:' );
DBMS_OUTPUT.PUT_LINE (
DBMS_LOB.COMPARE (v_temp1, v_temp2, 1, 6, 2));
IF DBMS_LOB.ISTEMPORARY (v_temp1) = 1 THEN
DBMS_OUTPUT.PUT_LINE ('elibereaza spatiul ocupat de '||
' obiectul temporar v_temp1');
DBMS_LOB.FREETEMPORARY (v_temp1);
END IF;
-- eliberarea spatiului se poate face si prin
-- atribuirea unei valori temporare goale
v_temp2 := v_temp1;
END;
Pentru modificarea valorilor LOB interne se pot utiliza urmtoarele rutine:
procedura APPEND (lob_dest, lob_surs) adaug coninutul unei valori de tip LOB surs
la o valoare destinaie;
procedura COPY (lob_dest, lob_surs, cantitate, poz_dest, poz_surs) permite copierea
total sau parial a unui obiect LOB surs ntr-un obiect LOB destinaie (copierea se face
ntre valori LOB de acelai tip);
procedura ERASE (locator, cantitate, poz) terge total sau parial o valoare de tip LOB,
ncepnd cu poziia specificat (dup tergere dimensiunea valorii rmne neschimbat,
poriunea tears fiind completat cu spaii pentru obiectele CLOB i NCLOB sau cu null
pentru obiectele BLOB);
procedura LOADFROMFILE (lob_dest, fiier_surs, cantitate, poz_dest, poz_surs)
ncarc total sau parial date de tip BFILE ntr-un obiect LOB intern (parametrul lob_dest
trebuie s fie un locator valid);
procedura LOADBLOBFROMFILE (lob_dest, fiier_surs, cantitate, poz_dest,
poz_surs), nou n Oracle9i, permite ncrcarea datelor binare din fiiere ale sistemului
de operare n obiecte interne BLOB, temporare sau persistente (similar procedurii
LOADFROMFILE);
procedura LOADCLOBFROMFILE (lob_dest, fiier_surs, cantitate, poz_dest,
poz_surs, set_caract_surs, context_limbaj, mesaj), nou n Oracle9i, permite
ncrcarea datelor de tip ir de caractere din fiierele sistemului de operare n obiecte
CLOB sau NCLOB, temporare sau persistente (conversia datelor de la setul de caractere al
sursei la cel al bazei de date se face automat);
procedura TRIM (locator, lungime_nou) truncheaz o valoare de tip LOB intern pn la
lungimea specificat (spre deosebire de ERASE, TRIM determin tergerea efectiv i
micorarea lungimii interne a valorii respective);
procedura WRITE (locator, cantitate, poz, buffer) scrie o anumit cantitate de date ntr-un
obiect LOB, ncepnd de la poziia specificat;
procedura WRITEAPPEND (locator, cantitate, buffer) scrie date la sfritul unei valori
LOB interne.
Funciile i procedurile utilizate n lucrul cu obiectele de tip BFILE sunt urmtoarele:
Orientare pe obiecte n Oracle9i 133

procedura FILECLOSE (locator_fiier) nchide fiierul specificat (se poate folosi i


CLOSE);
procedura FILECLOSEALL nchide toate fiierele deschise la momentul curent;
funcia FILEEXISTS (locator_fiier) verific dac fiierul exist n sistemul de operare al
server-ului;
funcia FILEGETNAME (locator_fiier, alias_director, nume_fiier) returneaz alias-ul
directorului i numele fiierului pentru un BFILE;
funcia FILEISOPEN (locator_fiier) verific dac un fiier asociat unui BFILE este
deschis (se poate folosi i ISOPEN);
procedura FILEOPEN (locator_fiier, mod_deschidere) deschide un fiier ataat unui
BFILE (se poate folosi i OPEN).
Din anumite puncte de vedere, modalitatea de prelucrare a obiectelor LOB este similar
fiierelor. Pentru deschiderea obiectelor LOB, n vederea scrierii sau citirii, respectiv pentru
nchiderea acestora sunt disponibile rutinele:
procedura OPEN (locator_lob, mod_deschidere) deschide o valoare de tip LOB pentru
citire sau scriere;
funcia ISOPEN (locator_lob) verific dac o valoare de tip LOB este deschis;
procedura CLOSE (locator_lob) nchide o valoare de tip LOB.
O alt modalitate frecvent utilizat pentru gestiunea i prelucrarea obiectelor de tip LOB este
reprezentat de utilitarul Oracle Call Interface (OCI). Rutinele COMPARE, INSTR, SUBSTR i
LOADFROMFILE prezente n pachetul DBMS_LOB, nu exist n OCI.
Exemplu:
a) S se ncarce fotografia fiecrei opere de art dintr-un fiier care are extensia jpg i
acelai nume ca opera respectiv (titlu). S se elimine din coloana descriere informaiile referitoare la
stilul operei. Se presupune c fiierele *.jpg corespunztoare sunt valide i se afl n directorul
D:\Imagini.
CREATE OR REPLACE DIRECTORY Imagini AS 'D:\Imagini\';
DECLARE
CURSOR c_opere IS SELECT titlu, descriere, foto
FROM student.tab_opere
FOR UPDATE OF descriere, foto;
v_fisier BFILE;
v_blob BLOB;
v_cant PLS_INTEGER := 4000;
v_pos PLS_INTEGER;
v_lung PLS_INTEGER;
v_fara_stil VARCHAR2(100);
v_ecod NUMBER;
v_errm VARCHAR2(150);
BEGIN
FOR v_rec IN c_opere LOOP
DBMS_OUTPUT.PUT_LINE (v_rec.titlu || '.jpg');
v_fisier := BFILENAME('Imagini', v_rec.titlu || '.jpg');
IF DBMS_LOB.FILEISOPEN (v_fisier) = 1 THEN
-- inchide fisierul daca era deschis
DBMS_LOB.FILECLOSE (v_fisier);
END IF;
-- deschide fisierul pentru citire
134 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

DBMS_LOB.FILEOPEN (v_fisier, DBMS_LOB.FILE_READONLY);


--incarca o cantitate de date din fisier in obiectul blob
DBMS_LOB.LOADFROMFILE (v_blob, v_fisier, v_cant);
-- inchide fisierul
DBMS_LOB.FILECLOSE (v_fisier);
-- elimina inforamtiile realtiv de stil din descriere
v_pos := DBMS_LOB.INSTR (v_rec.descriere, '%Stil');
v_lung := DBMS_LOB.GETLENGTH (v_rec.descriere);
IF v_pos = 0 THEN
v_pos := v_lung;
END IF;
v_fara_stil := DBMS_LOB.SUBSTR (v_rec.descriere,
v_pos - 1, 1);
DBMS_OUTPUT.PUT_LINE (v_fara_stil);
UPDATE student.tab_opere
SET foto = v_blob,
descriere = v_fara_stil
WHERE CURRENT OF c_opere;
-- sau cu procedura ERASE
--v_cant := v_lung - v_pos ;
--DBMS_LOB.ERASE (v_rec.descriere, v_cant, v_pos - 1);
-- sau cu procedura TRIM
--DBMS_LOB.TRIM (v_rec.descriere, v_cant);
END LOOP;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
v_ecod := SQLCODE;
v_errm := SUBSTR( SQLERRM, 1, 150);
RAISE_APPLICATION_ERROR (-20100, v_ecod || '-' || v_errm);
END;
b) Pentru toate operele de art pentru care nu s-a asociat o poz n tabelul tab_opere, s se
completeze coloana foto de tip BLOB, ncrcnd datele din fiierul referit de locatorul coninut n
coloana reportaj.
DECLARE
CURSOR c_opere_fara_poza IS
SELECT reportaj, foto
FROM student.tab_opere
WHERE foto IS NULL;
v_reportaj BFILE;
v_foto BLOB;
v_cant PLS_INTEGER := 32767;
v_pos PLS_INTEGER := 1;
v_buffer RAW(4000);
v_ecod NUMBER;
v_errm VARCHAR2(150);
BEGIN
OPEN c_opere_fara_poza;
FETCH c_opere_fara_poza INTO v_reportaj, v_foto;
IF c_opere_fara_poza%NOTFOUND THEN
CLOSE c_opere_fara_poza;
ELSE
Orientare pe obiecte n Oracle9i 135

CLOSE c_opere_fara_poza;
DBMS_LOB.FILEOPEN (v_reportaj, DBMS_LOB.FILE_READONLY);
IF DBMS_LOB.GETLENGTH (v_reportaj) < v_cant THEN
-- se poate incarca tot fisierul o data
v_cant := DBMS_LOB.GETLENGTH (v_reportaj);
DBMS_LOB.READ (v_reportaj, v_cant, 1, v_buffer);
DBMS_LOB.WRITE (v_foto, v_cant, 1, v_buffer);
DBMS_LOB.FILECLOSE(v_reportaj);
ELSE -- trebuie creat un ciclu pentru incarcarea datelor
BEGIN
v_pos := 1;
LOOP
DBMS_LOB.READ (v_reportaj, v_cant, v_pos, v_buffer);
DBMS_LOB.WRITE (v_foto, v_cant, v_pos, v_buffer);
v_pos := v_pos + v_cant;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN -- s-a terminat fisierul
DBMS_LOB.FILECLOSE (v_reportaj);
END;
END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
v_ecod := SQLCODE;
v_errm := SUBSTR( SQLERRM, 1, 150);
RAISE_APPLICATION_ERROR (-20100, v_ecod || '-' || v_errm);
END;
c) S se creeze o procedur care compar dou obiecte de tip BFILE i returneaz o valoare
boolean ce reflect egalitatea acestora. Se presupune c directorul logic dat ca parametru exist n
sistemul de operare gazd, iar fiierele ce vor fi comparate sunt plasate corect n acest director.
CREATE OR REPLACE FUNCTION comparare (
p_director VARCHAR2,
p_fis1 VARCHAR2,
p_fis2 VARCHAR2) RETURN BOOLEAN AS
v_fis1 BFILE := BFILENAME (p_director, p_fis1);
v_fis2 BFILE := BFILENAME (p_director, p_fis2);
v_rezultat BOOLEAN := FALSE;
BEGIN
DBMS_LOB.FILEOPEN (v_fis1, DBMS_LOB.FILE_READONLY);
DBMS_LOB.FILEOPEN (v_fis2, DBMS_LOB.FILE_READONLY);
v_rezultat := (DBMS_LOB.COMPARE (v_fis1, v_fis2,
DBMS_LOB.GETLENGTH (v_fis1)) = 0);
RETURN v_rezultat;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE (' A aparut o eroare ');
RETURN v_rezultat;
END;
/
136 BAZE DE DATE RELAIONALE ORIENTATE PE OBIECTE

Dintre excepiile predefinite care pot aprea n lucrul cu subprogramele din din pachetul
DBMS_LOB, se enumer:
ACCESS_ERROR, care indic depirea dimensiunii maxime permise pentru un obiect
LOB (cod eroare 22925);
INVALID_ARGVAL, care sesizeaz dac un argument este null, invalid sau n afara
domeniului (cod eroare 21560);
INVALID_DIRECTORY, care semnaleaz dac directorul referit este invalid sau a fost
modificat (cod eroare 22287);
NO_DATA_FOUND, care se declaneaz n situaia n care, la citire, se ajunge la sfritul
fiierului (cod eroare 100);
NOEXISTS_DIRECTORY, care marcheaz inexistena directorului referit ntr-o comand
(cod eroare 22285);
NOPRIV_DIRECTORY, care semnaleaz c utilizatorul nu are privilegiile necesare
asupra directorului referit (cod eroare 22285);
OPEN_TOOMANY, care se declaneaz dac s-a atins numrul maxim de fiiere ce pot fi
deschise n acelai timp (cod eroare 22290);
OPERATION_FAILED, care indic eecul unei operaii asupra unui fiier al sistemului de
operare (cod eroare 22288);
UNOPENED_FILE, care sesizeaz situaia n care o anumit operaie nu poate fi
executat asupra unui fiier, din cauz c acesta nu este deschis (cod eroare 22289).
Orientare pe obiecte n Oracle9i 137

Bibliografie
[1] Alecu A., Cristea G., Popescu I., Velcescu L. - Programare avansat n Oracle9i, Editura Tehnic, mai
2004.
[2] Codd E. F. - Derivability, Redundancy and Consistency of Relations Stored in Large Data Banks, IBM
Research report RJ599, 19 aug.1969.
[3] Codd E. F. A Relational Model for Large Shared Data Banks, Communications of the ACM, Vol. 13,
No6, 1970.
[4] Codd E.F. Further Normalisation of the Data Base Relational Model, Database Systems, Courant
Computer Science Symposia Series 6, Prentice Hall, 1972.
[5] Codd E.F. - Recent Investigations into Relational Database Systems, Proceedings of the IFIP, Stockholm,
1974.
[6] Popescu I. - Modelarea bazelor de date, Editura Tehnic, 2001.
[7] Popovici,D.M.,Popovici,I.M.,Tanase,I. - C++ Tehnologie orientata pe obiecte. Aplicatii, Ed.Teora, 1996.
[8] Soutou C. - De UML SQL Conception de bases de donnes, Eyrolles, 2002.
[9] Soutou C. - Objet-relationnel sous Oracle8, Modelisation avecUML, Eyrolles, 1999.
[10] *** Oracle9i Application Developer's Guide Large Objects (LOBs) Release 2 (9.2), Oracle Corporation, 2002.
[11] *** Oracle9i Application Developer's Guide - Object-Relational Features Release 2 (9.2), Oracle Corporation, 2002.
*** Oracle9i Database Concepts Release 2 (9.2), Oracle Corporation, 2002.

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