Sunteți pe pagina 1din 9

Proprieti obiectual-relaionale n standardul SQL

prof. dr. ing. Mircea Petrescu


Tipuri construite interne (build-in)
Din faza iniial a existenei sale, SQL a permis utilizarea tipurilor atomice pentru definirea
coloanelor, variabilelor i parametrilor. Tot acolo a fost introdus o clas de tipuri de date numite
tipuri construite. Acestea sunt tipuri definite de utilizator (UDT), tipuri referin, tipuri linie (rnd),
precum i tipuri colecie.
Tipurile construite pot conine mai mult dect o valoare. Din cele patru componente ale familiei
tipurilor construite, ultimele dou (tipurile rnd i tipurile colecie) sunt interne (build-in), iar
primele dou (UDT i referin) pot fi folosite de utilizator pentru a defini, prin extindere, tipuri noi,
pe lng cele interne.
Tipuri linie (rnd)
n accepiunea obinuit folosit n contextul modelului relaional, o linie (rnd) este o colecie
nevid de valori, n care tipul fiecrei valori corespunde unei definiii de coloan dintr-o tabel.
Dup cum tim, o tabel relaional convenional (relaie) este format din linii (rnduri) cu
proprietatea c fiecare valoare de coloan, n fiecare linie, trebuie s fie atomic, aceasta fiind
definiia FN1.
Standardul SQL lrgete cerinele FN1, prin introducerea tipului linie (rnd), care admite ca o linie
s conin o alt linie, aceasta fiind introdus ca o valoare de coloan. Se observ c tipul linie
(rnd) este asemntor cu structurile de nregistrare din limbajele de programare i cu tipul struct
din limbajul obiectual ODL.

birouri (N:M)
persistent
Arhitect

*
membru

*
membruAl

persistent
Persoana
Idp
datanast
prenume
nume

{disjunct, mandatory}

persistent
BirouArhitectura
Idb
nume

consiliere (N:1)
*
0..1
raspundeDe
analistsist

persistent
AnalistiSistematiza
re

adresa
tel

status

functie

1
participare
*

persistent
Edificii
cod
nume
getAnalistSistematizare
getArhitect

create table birouArhitectura(


idb varchar(10),

avizeaz

avizare

*
Inspectare
*

nume varchar(50) not null,


adresa row (strada varchar(30), cladirea varchar(5), camera varchar(5)),
analistsistematizare varchar(11) references arhitecti(idp),
primary key (idb));

Constructorul de linie (rnd) se folosete pentru a atribui valori cmpurilor unei linii. Valorile
folosite de constructorul de linie pot fi o list de valori, sau rezultatul unei interogri. n fiecare din
aceste cazuri, tipurile valorilor trebuie s corespund tipurilor de cmp folosite n definiia tipului
linie. Exemplu:
insert into birouArhitectura values(
BA101,
Birou Arhitect Univ,
row(Spaiul Independentei, Cladire centrala, cam 301),
DA110);

n comanda de mai sus, adresa biroului de arhitectur este reprezentat ca o coloan n tabel, ns
aceast adres este o valoare nonatomic format din trei valori de iruri de caractere separate. De
asemenea, DA are sensul de Director Arhitect.
Valorile unui tip (rnd) pot fi extrase folosind notaia cu punct pentru a realiza accesul la
cmpurile individuale care sunt pri ale coloanei. De exemplu:
select b.adresa.strada, b.adresa.cladirea, b.adresa.camera
from birouArhitectura b
where b.nume = Birou Arhitect Univ;

Tablouri de colecii
Valorile nonatomice din schemele relaionale pot fi reprezentate i prin tipul colecie. n general, o
colecie poate fi o structur de date din categoria mulimilor, listelor, multiset-urilor sau tablourilor.
Standardul SQL permite, n forma sa actual, numai tipul tablou.
O coloan a unei tabele poate fi definit (specificat) ca un tablou, adugnd la tipul de date al
coloanei cuvntul cheie array. La rndul su, acest cuvnt cheie este urmat de numrul maxim de
elemente pe care le poate conine, nscris ntre paranteze drepte. Accesul la prima poziie dintr-o
tabel este realizat cu o valoare de index de unu.
n exemplul care urmeaz se arat cum pot fi memorate direct identificatoarele membrilor biroului
de arhitectur n interiorul fiecrei linii (rnd) a tabelei (relaiei) birouArhitectura, folosind atributul
cu numele membri:
create table birouArhitectura(
Idb varchar(10),
nume varchar(50),
adresa row(strada varchar(30), cladirea varchar(5), camera varchar(5)),
analistsistematizare varchar(11) references architect(Idp),
membri varchar(11) array[50] references architect(Idp),
primary key (Idb));

Constructorul de tip array este folosit pentru a rezerva spatiu structurii tablou i, de asemenea,
servete la atribuirea de valori elementelor tabloului. Pentru a iniializa structura tabloului membrii
la o valoare vid se folosete instruciunea insert cu un constructor de tip array fr elemente:
insert into birouArhitectura values(
BA101,
Birou Arhitect Univ,

row(Spl Independentei, Cladire centrala, Cam 301), AS110,


array[]);

n continuare, structurii tablou i se pot aduga identificatoarele specifice ale membrilor biroului de
arhitectur, cu ajutorul constructorului de tablou, n cadrul unei instruciuni update. Pentru
atribuirea de valori primelor trei poziii ale structurii tablou membrii se folosete aseriunea:
update birouArhitectura
set membri=array[,,]
where nume=Birou Arhitect Univ;

Atribuiri de valori ale poziiilor individuale n interiorul unei structuri tablou se pot efectua, de
asemenea, cu ajutorul unei valori de index specifice:
update birouArhitectura
set membri[4]=
where nume=Birou Arhitect Univ;

Pentru a realiza accesul la o poziie anumit ntr-un tablou, se folosete un index. De pild, pentru a
extrage identificatorul celui de al doilea element al unui birou de arhitectur folosim instruciunile:
select membri[2]
from birouArhitectura
where nume=Birou Arhitect Univ;

Pentru determinarea dimensiunii (lungimii) unui tablou se folosete funcia cardinality. Aceast
funcie este util pentru realizarea iteraiilor n interiorul unui tablou, n rutinele SQL. De exemplu,
pentru a gsi lungimea curent a tabloului membri, admind c n tabela birouArhitectura se
folosete un cursor C, este introdus comanda cardinality(C.membri).
Folosirea general a tablourilor const n reprezentarea atributelor multi-valoare. De asemenea,
tablourile sunt utile n modelarea prii multi a asocierilor 1:N sau M:N, inclusiv n cazul limbajului
de definire ODL.
Tipuri definite de utilizator (UDT)
Termenul UDT este standard n SQL, avnd acelai neles ca termenul tip abstract de date. n
legtur cu acest ultim concept, ne reamintim c utilizatorul definete tipuri noi care au o anumit
form a structurii interne, fiind de asemenea definite metode care descriu comportarea acelor tipuri.
Reprezentarea intern a unui tip este ncapsulat de comportarea acestuia, ceea ce nseamn c
implementarea intern a tipului de date este ascuns fa de lumea exterioar. Aceast implementare
se poate schimba, fr a influena modul n care un utilizator interacioneaz cu tipul de date.
n standardul SQL, tipurile definite de utilizator sunt ns ntructva diferite fa de definiia strict
a tipurilor abstracte de date. Diferena provine n special din faptul c att toate atributele interne ale
unui UDT, ct i metodele asociate, sunt publice. Aceste elemente nu pot fi mascate ca fiind
protejate sau private, aa cum se procedeaz n limbaje ca Java sau C++.
Folosirea atributelor publice i a metodelor d posibilitatea ca structura intern a unei instane a
tipului introdus de utilizator s fie integrat printr-un limbaj ca SQL. Virtutea principal a UDT st
n faptul c ele permit proiectanilor de baze de date s defineasc tipuri noi de date, orientate ctre
aplicaie, n afar de tipurile atomice i construite din categoria build-in, iar apoi s foloseasc
noile tipuri n definirea de tabele (relaii). Desigur, cu ajutorul UDT pot fi create tabele n mediul
relaional.
3

Sintaxa SQL pentru crearea tipurilor definite de utilizator (UDT)


create table <user_defined_type_body>
<user_defined_type_body> ::= <user_defined_type_name>
[under <user_defined_type_name>]
[as <representation>]
[[not] <instantiable>]
[[not] final]
[ref
is
system
generated
|
ref
using
<predefined_type>
|
ref
from
<attribute_name> [{, attribute_name} ]]
[<method_specification_list>]
<representation> ::= <predefined_type> | <member_list>
<member_list> ::= (<attribute_definition>) [{, <attribute_definition>} ]
<attribute_definition> ::= <attribute_name> {<data_type> | <collection_type>}
[<reference_scope_ check>] [default <default_value>]
<data_type> ::= <predefined_type> | <reference_type>
<collection_type> ::= <data_type> array [unsigned_integer] /* [] part of syntax
*/
<method_specification_list>
::=
<method_specification>
[{,
<method_specification>} ]
<method_specification>
::=
<partial_method_specification>
|
<overriding_method_specification>
<overrinding_method_specification> ::= overriding <partial_method_specification>
<partial_method_specification>
::=
[constructor]
method
<method_name>
<SQL_parameter_declarations> returns <data_type>

Tipuri distincte
Folosesc pentru asocierea unei nelegeri speciale cu un tip atomic existent. De fapt, definesc o
form nou a unui tip atomic. Exemplu:
create type varsta as integer final;
create type greutate as integer final;
create table persoana(
Idpersoana varchar(3),
Varstapersoana varsta,
Greutatepersoana greutate,
primary key (Idpersoana));

Cuvntul cheie final reprezint elementul de sintax pentru tipurile distincte n standardul SQL
actual, indicnd faptul c nu poate fi definit un subtip al tipului distinct. Mai observm c odat
definite valorile varsta i greutate de mai sus nu pot fi comparate. Aceste valori nu pot fi
amestecate cu tipul integer normal, ntruct varsta, greutate si integer sunt, conceptual, tipuri
diferite. Totui, remarcm c folosirea n aceeai construcie a tipurilor distincte i a tipurilor
atomice pe care ele se bazeaz este posibil dar numai atunci cnd folosim (adugm) funcia
cast. Exemplu:
select Idpersoana
from persoana
where cast(varstapersoana as integer)*2 < cast(greutate persoana as integer);

Tipuri structurate
Sunt compuse din cteva componente interne, fiecare din acestea putnd fi de un tip diferit. O
instan a unui tip structurat este o valoare compus, deoarece tipul conine mai multe componente.
Exemplu:

create type adresaUdt as(


strada varchar(90),
cladirea varchar(5),
camera varchar(5)) not final;

Mai sus, clauza not final indic posibilitatea definirii de sub-tupluri ale tipului structurat.
Menionm c atributele tipului structurat pot aparine unor tipuri build-in atomice, construite sau
chiar UDT.
Tipul adresaUdt definit poate, la rndul su, contribui la definirea tipului coloanei adresa n tabela
birouArhitectura:
create table birouArhitectura(
Idb varchar(10),
nume varchar(50) not null,
adresa adresaUdt,
analistsist varchar(11) references analistsistematizare(Idp),
membri varchar(11) array[50] references architect(Idp),
primary key (Idp));

Metode interne pentru tipurile structurate


ntr-un tabel anterior, am artat, mai nainte, n contextul rutinelor menionate (invocate) n cadrul
SQL, c sunt trei tipuri de proceduri stocate: funcii, proceduri i metode. Metodele sunt asociate n
special cu tipurile structurate, ele fiind de fapt funcii strns legate cu definirea acestor tipuri. Ca
urmare, tipurile structurate permit ncapsularea un tip de acest fel fiind manipulat (prelucrat)
numai n metode definite de el. n standardul SQL, metodele pot fi definite ca proceduri. O excepie
Oracle, care admite definirea metodelor ca funcii i proceduri.
Tipuri de metode interne (build-in) pentru tipurile structurale de date: funcia constructor, funcia
observer (observator), funcia mutator. Aceste metode sunt coninute automat n definirea tipurilor.
Funcia constructor are acelai nume ca i tipul, i este folosit n crearea de instane ale tipului,
fiind invocat prin expresia new. Funcia observer este folosit pentru extragerea valorilor unui tip
structurat; pentru fiecare atribut al tipului structurat exist o funcie observer, cu acelai nume ca
atributul. Funcia mutator este folosit pentru modificarea valorilor atributelor unui tip structurat.
Funciile observer si mutator sunt menionate (invocate, de fapt) prin notaia punct (dot):
(Variabil.NumeFuncie). Aceast notaie st n locul notaiei convenionale (NumeFuncie
(parametrii)), folosit numai pentru funciile care nu sunt metode.
Exemplu rutin SQL prin care se creaz o instan de tipul adresaUdt, folosind funciile
constructor i mutator:
begin

end.

declare adr adresaUdt


/* invocare functie constructor */
set adr = new adresaUdt();
/* invocare functie mutator */
set adr.strada = Spl Independentei;
set adr.cladirea = Cladire Centrala;
set adr.camera = cam 301;
insert into birouArhitectura values(
BA101,
Birou Arhitect Univ,
adr, /* initializare adresa */
AS110,
Array[]);

Pentru a extrage valori de atribute ale tipului structurat se folosete funcia observer, ca n exemplul:
select nume, c.adresa.strada, c.adresa.cladirea, c.adresa.camera
from birouArhitectura c
where nume = Birou Arhitect Univ;

Metode definite de utilizator pentru tipurile structurale


Utilizatorul definete semntura fiecrei metode, prin introducerea numelui metodei, a numelor
parametrilor si a tipurilor acestora. Exemplu: definirea metodei cu numele suma pentru tipul
structurat cu numele treiNumere. Semntura arat c aceast metod nu are parametrii explicii
definii. Metoda are ca rezultat o valoare de tip integer. De obicei ns, fiecare metod are un
parametru implicit, care este instana tipului de date pentru care se definete metoda. Valoarea
parametrului implicit este obinut n implementarea metodei prin cuvntul cheie self. Iat definiia
metodei:
create type treiNumere as
(unu integer,
doi integer,
trei integer) not final;
method suma() returns integer;
create method suma() returns integer for treiNumere
begin
return self.unu + self.doi + self.trei;
end.

Utilizatorul / programatorul poate ignora funcia constructor a unui tip structurat. Deoarece funcia
constructor definit de sistem nu admite parametrii, prin ignorarea funciei constructor se realizeaz
o form diferit a funciei, care poate fi folosit pentru a preciza valorile atributelor specifice n
momentul n care este creat o instan a tipului de date.
n continuare, este prezentat un exemplu privind ignorarea funciei constructor a tipului adresaUdt.
Potrivit sintaxei SQL pentru crearea UDT, cuvntul cheie overriding trebuie specificat neaprat,
pentru a indica faptul c metoda suprascrie o funcie existent:
create type adresaUdt as(
strada varchar(30),
cladirea varchar(5),
camera varchar(5)) not final;
overriding constructor method /**/
adresaUdt(strada varchar(30), cladirea varchar(5), camera varchar(5))
returns adresaUdt;
create method adresaUdt(str varchar(30), clad varchar(5), cam varchar(5))
returns adresaUdt for adresaUdt
begin
set self.strada = str;
set self.cladirea = clad;
set self.camera = cam;
end.

Cuvntul cheie constructor trebuie specificat mai sus deoarece metoda care se ignor este, n acelai
timp, o funcie constructor. Desigur, numele metodei este acelai ca numele funciei constructor
definit de sistem (adresaUdt). Definiia metodei conine specificarea parametrilor i tipurilor
acestora. Implementarea metodei arat modul n care se folosesc parametri pentru a atribui valori
unei instane prin funcii mutator. De observat c metoda extrage self ca o valoare, care este instana
modificat de tipul adresaUdt.
6

Funcia constructor definit de utilizator poate fi acu folosit pentru a crea o instan nou de tipul
adresaUdt i, n acelai timp, de a introduce valori ale atributelor acesteia:
declare adr adresaUdt;
set adr = new adresaUdt(Spl Independentei, Cladire Centrala, Cam 301);

Tabele tipizate
n standardul SQL, o instan a unui UDT este o valoare. Pentru a crea conceptul de obiect, ca n
tehnologia bazelor de date orientate obiect, trebuie folosit un UDT mpreun cu o tabel tipizat.
Tabela tipizat este o form nou de tabel n standardul SQL, asociat ntotdeauna cu un anumit tip
structurat. Pentru fiecare atribut al tipului structurat pe care se sprijin, o tabel tipizat are o
coloan. n plus, va avea o coloan cu auto-referire, care conine un identificator unic de obiect
pentru fiecare linie (rnd) al tabelei. Acest identificator se numete referire.
Cnd pentru definirea unei tabele tipizate se folosete un tip structurat, o instan a acestui tip este
vzut ca un obiect, al crui identificator este dat de coloana cu auto referire. Spre deosebire de
identificatoarele de obiecte folosite n bazele de date orientate obiect, un identificator de obiect este
unuic numai n contextul unei tabele tipizate specifice. Deci dou tabele tipizate pot avea linii cu
valori cu auto-referire identice.
Pentru a exemplifica folosirea tabelelor tipizate, s admitem c dorim implementarea clasei Edificii
din diagrama de clase Persoana-Arhitect-Edificii, ca o tabel tipizat. Mai nti, definim tipul
structurat edificiiUdt:
create type edificiiUdt as(
cod varchar(3),
nume varchar(40))
instantiable not final ref is system generated;

n codul de mai sus, edificiiUdt definete atributele cod i nume. Observm ns prezena a dou
clauze, instantiable i ref, care au fost introduse anterior, prin sintaxa SQL pentru crearea UDT.
Clauza instantiable arat c pentru tipul creat exist o funcie constructor i astfel utilizatorul
(prgramatorul) poate crea direct instane ale acestui tip. Dac ns tipul creat este specificat ca fiind
ne-instaniabil, prin clauza not-instantiable, nu va exista o funcie constructor pentru acest tip.
Folosirea ultimei clauze, de ne-instaniere, are sens numai pentru un tip care posed un sub-tip, caz
n care instanele tipului sunt create numai la nivel de sub-tip. Ierarhiile de tipuri se vor examina
mai trziu. Un tip structurat folosit mpreun cu o tabel tipizat trebuie ntotdeauna specificat ca
instaniabil.
Clauza ref permite programatorului s specifice modul (mijloacele) de generare a valorii pentru
referirea unui obiect. Sunt trei forme a clauzei ref:
a) ref operaiunea de referire este generat de sistem; n acest caz, sistemul de baz de date
este rspunztor de generarea unei referiri unice de obiect pentru instanele tipului.
b) ref using arat c referirea este generat de programator. Aceasta trebuie s introduc o
referire unic pentru fiecare instan a tipului, valoarea referirii fiind de tipul indicat n
clauz.
c) ref from arat c programatorul este cel care trebuie s dea lista atributelor tipului
structurat, care va fi folosit pentru a obine o referire unic de obiect.

n contextul de aici, se utilizeaz numai referirile generate de sistem, ca cea mai adecvat pentru
nelegerea folosirii obiectelor.
Sintaxa SQL pentru crearea tabelelor tipizate
Dup ce a fost definit UDT, ca mai sus, se creaz o tabel tipizat corespunztoare structurii
acesteia. Iat sintaxa pentru crearea tabelelor tipizate:
create table <table_name> of <user_defined_type_name> [under <supertable_name>]
[<table_element_list>]
<table_element_list> ::= (<table_element> [{, <table_element>} ])
<table_element> ::= <table_constraint> | <self_referencing_column_specification>
| <column_options>
<self_referencing_column_specification>
::=
ref
is
<self_referencing_column_name> <reference_generation>
<reference_generation> ::= system generated | user generated | derived
<column_options> ::= <column_name> with options <column_option_list>
<column_option_list> ::= [scope <table_name> [<reference_scope_check>]] [default
<default_value>] [<column_constraint> ]

S definim, pe aceast baz, tabela tipizat edificii:


create table edificii of edificiiUdt(
primary key (cod),
ref is edificiiID system generated);

Clauza of, mai sus, arat pe ce tip structurat se bazeaz tabela tipizat. Ca urmare, tabela va avea, n
mod automat, coloane care corespund atributelor tipului structurat. Remarcm c definiia tabelelor
tipizate accept aceleai restricii pentru tabel i coloane, ca cele din cazul tabelelor relaionale
convenionale. De pild, n definiia tabelei edificii, atributul cod al tuplului edificiiUdt este luat ca
cheie primar. De asemenea, se pot specifica restricii ca unique sau not null, n formatul
restriciilor de tabel sau de coloan. n definiia unei tabele tipizate sunt indicate numai atributele
cu restricii.
Potrivit sintaxei de mai sus, definiia unei tabele tipizate trebuie s repete specificaia generrii
referirilor ntr-o manier consistent cu specificaia generrii referirilor tipului structurat: system
generated, user generated, derived.
De asemenea, prin clauza ref is trebuie atribuit un nume coloanei cu auto-referire. Acest nume (n
cazul nostru edificiiID) poate fi folosit pentru manipularea coloanei cu auto-referire n cazul
referirilor definite de utilizator. Pentru a avea acces la valoarea de auto-referire se folosete
coloana cu auto-referire.
Pentru a introduce linii (rnduri) n o tabel tipizat se folosete comanda insert, n mod
concurenial. De exemplu:
insert into edificii values(
SIC, Stiinta si Ingineria Calculatoarelor);
insert into edificii values(
IM, Inginerie Mecanica);

Liniiile (rndurile) care se repet n tabela tipizat edificii vor fi:


(coloana cu auto-referire) edificiiID
cod
nume
10287534556
SIC
Stiinta si Ingineria Calculatoarelor
90324854948
IM
Inginerie Mecanica
8

Valorile pentru coloana cu auto-referire sunt generate de sistem. Dac referirea este definit de
utilizator, comanda insert trebuie s conin valoarea pentru coloana cu auto-referire. Dac
referirea este derivat din atributele tipului, restricia primary key sau restriciile unique i not null
pot fi prezente n definiia tabelei, pentru a asigura o valoare unic de referire pentru atribute.
Tipurile referire
Anterior, a fost examinat folosirea coloanei cu auto-referire, care este, de fapt, un identificator
intern de obiect, sau referire, ctre o linie (rnd). Aceast referire este un tip de date numit tip
referire (reference type), sau ref. Sintaxa este:
<reference_type>
::=
ref
(<referenced_type>)
[<scope_clause>]
[array
[usingend_integer]] [reference_scope_check] /* [] part of syntax */
<scope_clause> ::= scope <table_name>
<refenced_type> ::= <user_defined_type_name>
<reference_scope_check> ::= references are [not] checked [on delete <action>]

Sintaxa pentru definirea tipurilor referire


Ca exemplu, s considerm din nou diagrama de clase Persoana-Arhitect-Edificii. ntre
BirouArhitectura i AnalistSistematizare avem o asociere (legtur) 1:N. De asemenea, ntre
BirouArhitectur i Arhitect avem o asociere M:N. Putem acum redefinii tipul BirouArhitectUdt,
pentru a folosi tipuri referire ca un mijloc de descriere a asocierilor cu obiectele
AnalistSistematizare i arhitect:
create type birouArhitectUdt as(
Idb varchar(10),
nume varchar(50) not null,
adresa adresaUdt,
tel varchar(12),
analistSistemtizare ref(analistSistematizareUdt),
membri ref(arhitectUdt) array[50])
instantiable not final ref is system generated;
create table birouArhitecturaUdt(
primary key (Idb),
ref is birouArhitecturaID system generated);

Exemplul de mai sus numai pentru a ilustra crearea tipurilor referire. Verificarea referirilor i
interogarea acestor tipuri mai trziu.

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