Sunteți pe pagina 1din 94

UNIVERSITATEA SPIRU HARET

FACULTATEA DE MATEMATICĂ - INFORMATICĂ

CURS: SGBD

TIP CURS : OBLIGATORIU LA SECTIA DE MATEMATICA INFORMATICA, ANUL III, SEMESTRUL 6,


LA TOATE FORMELE DE INVATAMANT
DURATA: SEMESTRUL II, 2 ORE DE CURS, 2 ORE DE LABORATOR
TITULAR: LECTOR DR. FLORENTINA RODICA NICULESCU
E-MAIL: rodicaniculescu@gmail.com

I. CONłINUTUL TEMATIC AL DISCIPLINEI

• SGBD Oracle – concepte generale


• Oracle SQL*Plus
• Oracle SQL – Limbajul de definire a datelor, instrucŃiuni DDL (Data Definition Language)
− CREATE - Creează în baza de date un nou obiect, de tipul specificat în instrucŃiune,
CREATE TABLE, CREATE INDEX şi CREATE VIEW.
− ALTER - Modifică definiŃia unui obiect existent în baza de date, de tipul
specificat în instrucŃiune : ALTER TABLE
− D R O P - Şterge un obiect existent în baza de date, de tipul specificat în instrucŃiune
DROP TABLE, DROP INDEX şi DROP VIEW.
• Oracle SQL – Limbajul de interogare a datelor, instrucŃiuni DQL (Data Query Language)
include o singură comandă SELECT, care este cea mai folosită pentru a obŃine date din baza de
date, astfel încât acestea să fie prelucrate de o anumită aplicaŃie sau să fie afişate. Interogari
monorelatie, interogari multirelatie(Uniuni (join), Uniuni de egalitate (equijoin), Uniuni
naturale (natural join), Uniuni externe (outer joins), Auto-uniuni (seif joins), Uniuni încrucişate
(cross joins)), subcereri (cu si fara sincronizare), gruparea datelor(group by), operatori,
operatori pe multimi(union, minus, intersect), functii single row(sysdate, trim, upper, etc.),
functii multiple row(min, max, avg, count, sum, etc).
• Oracle SQL – Limbajul de manipulare a datelor, instructiuni DML(Data Manipulation
Language)
− INSERT Adaugă noi rânduri într-un tabel al bazei de date.
− UPDATE Actualizeaza rândurile existente intr-un tabel al bazei de date.
− DELETE Sterge rânduri dintr-un tabel al bazei de date
• Oracle SQL – Limbajul de control al datelor, instructiuni DCL (Data Control Language)
− COMMIT
− ROLLBACK
− SAVEPOINT
II. SINTEZE ASUPRA PROGRAMEI ANALITICE

1. GENERALITĂłI DESPRE BAZE DE DATE

1.1. Introducere

Baza de date este un ansamblu structurat de date coerente, fără redondanŃă inutilă, astfel
încât acestea pot fi prelucrate eficient de mai mulŃi utilizatori într-un mod concurent.
Baza de date este o colecŃie de date pe rsistente, care sunt folosite de către sistemele de
aplicaŃii ale unei anumite „întreprinderi“. Datele din baza de date persistă deoarece, după ce au fost
acceptate de către sistemul de gestiune pentru introducerea în baza de date, ele pot fi şterse din bază
numai printr-o cerere explicită adresată sistemului de gestiune.
Aici, termenul de „întreprindere“ este un cuvânt generic, utilizat pentru a desemna orice
organizaŃie independentă, de natură tehnică, comercială, ştiinŃifică sau de alt tip. Întreprinderea poate
fi, de exemplu, un spital, o bancă, o facultate, o fabrică, un aeroport etc. Fiecare întreprindere are
regulile proprii de funcŃionare şi conŃine o mulŃime de date referitoare la modul său de operare.
Datele din baza de date pot fi atît integrate, cât şi partajate. NoŃiunea de integrat se referă la
faptul că baza de date poate fi considerată ca o unificare a mai multor fişiere, iar prin partajare se
înŃelege că baza de date poate fi partajată concurent între diferiŃi utilizatori.

Un sistem de gestiune a bazelor de date (SGBD – Data Base Management System) este un
produs software care asigură interacŃiunea cu o bază de date, permiŃând definirea, consultarea şi
actualizarea datelor din baza de date. Toate cererile de acces la baza de date sunt tratate şi controlate
de către SGBD.
DicŃionarul datelor (catalog de sistem), structurat şi administrat ca o bază de date (metabază
de date), contine „date despre date“, furnizează descrierea tuturor obiectelor unei baze de date, starea
acestor obiecte, diversele constrângeri de securitate şi de integritate etc. DicŃionarul poate fi
interogat, la fel, ca orice altă bază de date.

1.2. Gestiunea bazelor de date

Un sistem de baze de date presupune următoarele componente principale, care definesc


arhitectura acestuia:
• baza de date propriu-zisă în care se memorează datele;
• sistemul de gestiune a bazei de date, care realizează gestionarea şi prelucrarea complexă
a datelor;
• un dicŃionar al bazei de date (metabaza de date), ce conŃine informaŃii despre date,
structura acestora, statistici, documentaŃie;
• mijloace hardware (comune sau specializate);
• reglementări administrative destinate bunei funcŃionări a sistemului;
• personalul implicat (utilizatori finali, administratorul datelor, administratorul bazei de
date, proiectanŃi, programatori de aplicaŃii).

Se pot identifica patru categorii de persoane implicate în mediul bazelor de date:


• administratorii de date şi baze de date,
• proiectanŃii (designeri) de baze de date,
• programatorii de aplicaŃii,
• utilizatorii finali.
Administratorul de date (DA) este un manager, nu un tehnician, ce:
• decide care date trebuie stocate în baza de date;
• stabileşte regulile de întreŃinere şi de tratare a acestor date după ce sunt stocate. De
exemplu, o regulă ar putea fi aceea prin care se stabilesc pentru utilizatori privilegii
asupra informaŃiilor din baza de date, cu alte cuvinte o anumită politică de securitate a
datelor.
Administratorul bazei de date (DBA) este responsabil cu implementarea deciziilor
administratorului de date şi cu controlul general al sistemului, la nivel tehnic. El este un profesionist
în domeniul IT, care:
• creează baza de date reală;
• implementează elementele tehnice de control;
• este responsabil cu asigurarea funcŃionării sistemului la performanŃe adecvate, cu
monitorizarea performanŃelor;
• furnizează diverse servicii tehnice etc.
ProiectanŃii de baze de date pot acoperi atât aspectul fizic, cât şi cel logic al concepŃiei.
Proiectantul de baze de date care abordează direcŃia logică trebuie să posede o cunoaştere
completă şi amănunŃită a modelului real de proiectat şi a regulilor de funcŃionare ale acestuia.
Practic, acesta proiectează conceptual baza de date, iar modelul creat este independent de programele
de aplicaŃii, de limbajele de programare. De asemenea, va proiecta logic baza de date, proiectare care
este îndreptată spre un anumit model de date (relaŃional, orientat obiect, ierarhic etc.).
Proiectantul de baze de date fizice preia modelul logic de date şi stabileşte cum va fi realizat
fizic. Acesta trebuie să cunoască funcŃionalităŃile SGBD-ului, avantajele şi dezavantajele fiecărei
alternative corespunzătoare unei implementări. Practic, se face transpunerea modelului logic într-un
set de tabele supuse unor constrângeri, se selectează structuri de stocare şi metode de acces specifice,
astfel încât să se asigure performanŃe, se iau măsuri privind securitatea datelor.
Utilizatorii finali sunt cei care accesează interactiv baza de date. Aceasta a fost proiectată,
implementată, întreŃinută pentru a satisface necesităŃile informaŃionale ale clienŃilor. Utilizatorii
finali pot fi utilizatori simpli, care nu cunosc nimic despre baza de date, despre SGBD, dar accesează
baza prin intermediul unor programe de aplicaŃie. În general, această clasă de utilizatori alege
anumite opŃiuni din meniul aplicaŃiei. Există utilizatori finali sofisticaŃi, care sunt familiarizaŃi cu
structura bazei de date. Ei pot utiliza limbaje speciale pentru a exploata posibilităŃile oferite de baza
de date.
Programatori de aplicaŃii sunt responsabili de scrierea programelor aplicaŃie ce conferă
funcŃionalitatea cerută de utilizatorii finali. Programele pot fi scrise în diferite limbaje de programare
(C++, PL/SQL, Java etc.).

CerinŃe minimale care se impun unei baze de date:


• asigurarea unei redundanŃe minime în date;
• furnizarea în timp util a informaŃiilor solicitate (timpul de răspuns la o interogare);
• asigurarea unor costuri minime în prelucrarea şi întreŃinerea informaŃiei;
• capacitatea de a satisface, cu aceleaşi date, necesităŃi informaŃionale ale unui număr mare
de utilizatori,
• posibilitatea de adaptare la cerinŃe noi, răspunsuri la interogări neprevăzute iniŃial
(flexibilitate);
• exploatarea simultană a datelor de către mai mulŃi utilizatori (sincronizare);
• asigurarea securităŃii datelor prin mecanisme de protecŃie împotriva accesului neautorizat
(confidenŃialitate);
• înglobarea unor facilităŃi destinate validării datelor şi recuperării lor în cazul unor
deteriorări accidentale, garantarea (atât cât este posibil) că datele din baza de date sunt
corecte (integritate);
• posibilitatea de valorificare a eforturilor anterioare şi anticiparea nevoilor viitoare
(compatibilitate şi expandabilitate);
• permisivitatea, prin ierarhizarea datelor după criteriul frecvenŃei acceselor, a unor
reorganizări (eventual dinamice) care sporesc performanŃele bazei.
În cadrul unei baze de date putem vorbi de patru niveluri de abstractizare şi de percepŃie a
datelor: intern, conceptual, logic şi extern. Datele există doar la nivel fizic, iar celelalte trei niveluri
reprezintă virtualizări ale acestora.
• Nivelul fizic (intern) este descris de schema fizică a datelor (bit, octet, adresă);
• Nivelul conceptual este descris de schema conceptuală a datelor (articol, înregistrare,
zonă) şi reprezintă viziunea programatorilor de sistem asupra datelor;
• Nivelul logic este descris de una din schemele logice posibile ale datelor şi reprezintă
viziunea programatorului de aplicaŃie asupra datelor;
• Nivelul virtual (extern) reprezintă viziunea utilizatorului final asupra datelor.
IndependenŃa datelor cuprinde două aspecte fundamentale: o modificare a structurii fizice
nu va afecta aplicaŃia şi reciproc, modificări ale aplicaŃiei vor lăsa nealterată structura fizică de date.
• IndependenŃa fizică: posibilitatea modificării schemei fizice a datelor fără ca aceasta să
implice modificarea schemei conceptuale, a schemei logice şi a programelor de aplicaŃie.
Este vorba despre imunitatea programelor de aplicaŃie faŃă de modificările modului în
care datele sunt stocate fizic şi accesate.
• IndependenŃa logică: posibilitatea modificării schemei conceptuale a datelor fără ca
aceasta să implice modificarea schemei logice şi a programelor de aplicaŃie. Prin
independenŃa logică a datelor se urmăreşte a se crea fiecărui utilizator iluzia că este
singurul beneficiar al unor date pe care, în realitate, le foloseşte în comun cu alŃi
utilizatori.
IndependenŃă faŃă de strategiile de acces permite programului să precizeze data pe care
doreşte să o acceseze, dar nu modul cum accesează această dată. SGBD-ul va stabili drumul optim de
acces la date.
În limbajele de programare uzuale declaraŃiile şi instrucŃiunile executabile aparŃin aceluiaşi
limbaj. În lumea bazelor de date, funcŃiile de declarare şi de prelucrare a datelor sunt realizate cu
ajutorul unor limbaje diferite, numite limbaje pentru baze de date.
• Limbaje pentru definirea datelor (LDD – Data Description Language). Descrierea
concretă a unui LDD este specifică fiecărui sistem de gestiune, dar funcŃiile principale
sunt aceleaşi. La nivel conceptual, LDD realizează definirea entităŃilor şi a atributelor
acestora, sunt precizate relaŃiile dintre date şi strategiile de acces la ele, sunt stabilite
criterii diferenŃiate de confidenŃialitate şi de validare automată a datelor utilizate.
• Limbaje pentru prelucrarea datelor (LMD – Data Manipulation Language). OperaŃiile
executate în cadrul unei baze de date presupun existenŃa unui limbaj specializat, în care
comenzile se exprimă prin fraze ce descriu acŃiuni asupra bazei. În general, o comandă
are următoarea structură: operaŃia (calcul aritmetic sau logic, editare, extragere,
deschidere-închidere, adăugare, ştergere, căutare, reactualizare etc.), criterii de selecŃie,
mod de acces (secvenŃial, indexat etc.), format de editare. Există limbaje LMD
procedurale, care specifică cum se obŃine rezultatul unei comenzi LMD şi limbaje
neprocedurale, care descriu doar datele ce vor fi obŃinute şi nu modalitatea de obŃinere a
acestora.
• Limbaje pentru controlul datelor (LCD – Data Control Language). Controlul unei baze de
date se referă la asigurarea confidenŃialităŃii şi integrităŃii datelor, la salvarea informaŃiei
în cazul unor defecŃiuni, la obŃinerea unor performanŃe, la rezolvarea unor probleme de
concurenŃă.
Limbajele universale nu se utilizează frecvent pentru gestionarea unei baze de date, dar există
această posibilitate. De exemplu, sistemul Oracle este dotat cu precompilatoare (C, Pascal, ADA,
Cobol, PL/1, Fortran) care ajută la incorporarea de instrucŃiuni SQL sau blocuri PL/SQL în programe
scrise în alte limbaje, de nivel înalt, numite limbaje gazdă.
Sistemul de gestiune a bazelor de date interacŃionează cu programele de aplicaŃie ale
utilizatorului şi cu baza de date, oferind o mulŃime de facilităŃi. Realizarea optimă a acestor facilităŃi
este asigurată de obiectivele fundamentale ale unui sistem de gestiune. Câteva dintre aceste obiective
vor fi enumerate în continuare.
• IndependenŃa fizică. Obiectivul esenŃial este acela de a permite realizarea independenŃei
structurilor de stocare în raport cu structurile de date din lumea reală. Se defineşte
mulŃimea de date indiferent de forma acesteia din lumea reală, Ńinând seama doar de a
realiza un acces simplu la date şi de a obŃine anumite performanŃe.
• IndependenŃa logică. Grupul de lucru care exploatează baza de date poate să utilizeze
diferite informaŃii de bază (nu aceleaşi), pentru a-şi construi entităŃi şi relaŃii. Fiecare
grup de lucru poate să cunoască doar o parte a semanticii datelor, să vadă doar o
submulŃime a datelor şi numai sub forma în care le doreşte. Această independenŃă asigură
imunitatea schemelor externe faŃă de modificările făcute în schema conceptuală.
• Prelucrarea datelor de către neinformaticieni. Neinformaticienii văd datele independent
de implementarea lor şi pot exploata aceste date prin intermediul unui sistem de meniuri
oferit de aplicaŃia pe care o exploatează.
• Administrarea centralizată a datelor. Administrarea datelor presupune definirea structurii
datelor şi a modului de stocare a acestora. Administrarea este în general centralizată şi
permite o organizare coerentă şi eficace a informaŃiei.
• CoerenŃa datelor. InformaŃia trebuie să satisfacă constrângeri statice sau dinamice, locale
sau generale.

• NeredundanŃa datelor. Fiecare aplicaŃie posedă datele sale proprii şi aceasta conduce la
numeroase dubluri. De asemenea, organizarea nejudicioasă a relaŃiilor poate să genereze
redundanŃă în date. Administrarea coerentă a datelor trebuie să asigure neduplicarea
fizică a datelor. Totuşi, nu sunt excluse nici cazurile în care, pentru a realiza performanŃe
referitoare la timpul de acces la date şi răspuns la solicitările utilizatorilor, să se accepte o
anumită redundanŃă a datelor.
• Partajabilitatea datelor. Aceasta permite ca aplicaŃiile să partajeze datele din baza de date
în timp şi simultan. O aplicaŃie poate folosi date ca şi cum ar fi singura care le utilizează,
fără a şti că altă aplicaŃie, concurent, le poate modifica.
• Securitatea şi confidenŃialitatea datelor. Datele trebuie protejate de un acces neautorizat
sau rău intenŃionat. Există mecanisme care permit identificarea şi autentificarea
utilizatorilor şi există proceduri de acces autorizat care depind de date şi de utilizator.
Sistemul de gestiune trebuie să asigure securitatea fizică şi logică a informaŃiei şi să
garanteze că numai utilizatorii autorizaŃi pot efectua operaŃii corecte asupra bazei de date.
Sistemele de gestiune a bazelor de date au, din nefericire, şi dezavantaje dintre care se
remarcă:
• complexitatea şi dimensiunea sistemelor pot să crească considerabil, datorită necesităŃii
extinderii funcŃionalităŃilor sistemului;
• costul, care variază în funcŃie de mediu şi funcŃionalitatea oferită, la care se adugă
cheltuieli periodice de întreŃinere;
• costuri adiŃionale pentru elemente de hardware;
• costul conversiei aplicaŃiilor existente, necesară pentru ca acestea să poată funcŃiona în
noua configuraŃie hardware şi software;
• impactul unei defecŃiuni asupra aplicaŃiilor, bazei de date sau sistemului de gestiune.
Structura unui sistem de gestiune a bazelor de date este de complexitate variabilă, iar nivelul
real de funcŃionalitate diferă de la produs la produs. În orice moment apar noi necesităŃi, care cer o
nouă funcŃionalitate, astfel încât aceasta nu va putea deveni niciodată statică. În general, un SGBD
trebuie să includă cel puŃin cinci clase de module:
• programe de gestiune a bazei de date (PGBD), care realizează accesul fizic la date ca
urmare a unei comenzi;
• module pentru tratarea limbajului de definire a datelor, ce permit traducerea unor
informaŃii (care realizează descrierea datelor, a legăturilor logice dintre acestea şi a
constrângerilor la care sunt supuse), în obiecte ce pot fi apoi exploatate în manieră
procedurală sau neprocedurală;
• module pentru tratarea limbajului de prelucrare a datelor (interpretativ, compilativ,
generare de programe), care permit utilizatorilor inserarea, ştergerea, reactualizarea sau
consultarea informaŃiei dintr-o bază de date;
• module utilitare, care asigură întreŃinerea, prelucrarea, exploatarea corectă şi uşoară a
bazei de date;
• module de control, care permit controlul programelor de aplicaŃie, asigurarea
confidenŃialităŃii şi integrităŃii datelor, rezolvarea unor probleme de concurenŃă,
recuperarea informaŃiei în cazul unor avarii sau defecŃiuni hardware sau software etc.
Modulele PGBD asigură accesul fizic la date ca urmare a unei comenzi. Cum lucrează aceste
module?
• găsesc descrierea datelor implicate în comandă;
• identifică datele şi tipul acestora;
• identifică informaŃii ce permit accesul la structurile fizice de stocare (fişiere, volume etc.);
• verifică dacă datele sunt disponibile;
• extrag datele, fac conversiile, plasează datele în spaŃiul de memorie al utilizatorului;
• transmit informaŃii de control necesare execuŃiei comenzii, în spaŃiul de memorie al
utilizatorului;
• transferă controlul programului de aplicaŃie.
Prin urmare, din punct de vedere conceptual:
• utilizatorul lansează o cerere de acces;
• SGBD-ul acceptă cererea şi o analizează;
• SGBD-ul inspectează pe rând, schema internă corespunzatoare utilizatorului, schema
conceptuală, definiŃia structurii de stocare şi corespondenŃele corespunzătoare;
• SGBD-ul execută operaŃiile necesare în baza de date stocată.
1.3. Arhitectura sistemelor de gestiune a bazelor de date

Asigurarea independenŃei fizice şi logice a datelor impune adoptarea unei arhitecturi de baze
de date organizată pe trei niveluri:
• nivelul intern (baza de date fizică);
• nivelul conceptual (modelul conceptual, schema conceptuală);
• nivelul extern (modelul extern, subschema, vizualizarea).
Nivelul central este nivelul conceptual. Acesta corespunde structurii canonice a datelor ce
caracterizează procesul de modelat, adică structura semantică a datelor fără implementarea pe
calculator. Schema conceptuală permite definirea tipurilor de date ce caracterizează proprietăŃile
elementare ale entităŃilor, definirea tipurilor de date compuse care permit regruparea atributelor
pentru a descrie entităŃile modelului şi legăturile între aceste entităŃi, definirea regulilor pe care
trebuie să le respecte datele etc.
Nivelul intern corespunde structurii interne de stocare a datelor. Schema internă permite
descrierea datelor unei baze sub forma în care sunt stocate în memoria calculatorului. Sunt definite
fişierele care conŃin aceste date, articolele din fişiere, drumurile de acces la aceste articole etc.
La nivel conceptual sau intern, schemele descriu o bază de date. La nivel extern schemele
descriu doar o parte din date care prezintă interes pentru un utilizator sau un grup de utilizatori.
Schema externă reprezintă o descriere a unei părŃi a bazei de date ce corespunde viziunii unui
program sau unui utilizator. Modelul extern folosit este dependent de limbajul utilizat pentru
prelucrarea bazei de date. Schema externă permite asigurarea unei securităŃi a datelor. Un grup de
lucru va accesa doar datele descrise în schema sa externă, iar restul datelor sunt protejate împotriva
accesului neautorizat sau rău intenŃionat.
Pentru o bază de date particulară există o singură schemă internă, o singură schemă
conceptuală, dar există mai multe scheme externe.
În afară de aceste trei niveluri, arhitectura presupune şi anumite corespondenŃe dintre acestea:
• corespondenŃa conceptual-intern defineşte relaŃia dintre nivelul conceptual şi baza de
date stocată, specificând modul în care înregistrările şi câmpurile conceptuale sunt
reprezentate la nivel intern;
• corespondenŃa extern-conceptual defineşte relaŃia dintre o anumită vizualizare externă şi
nivelul (vizualizarea) conceptual, reprezentând cheia independenŃei logice de date;
• corespondenŃa extern-extern permite definirea unor vizualizări externe în funcŃie de
altele, fără a necesita o definiŃie explicită a corespondenŃei cu nivelul conceptual.
Arhitectura funcŃională de referinŃă propusă de grupul de lucru ANSI/X3/SPARC este
axată pe dicŃionarul datelor şi cuprinde două părŃi:
• prima, permite descrierea datelor (compoziŃia dicŃionarului datelor);
• a doua, permite prelucrarea datelor (interogarea şi reactualizarea bazei de date).
În fiecare parte se regăsesc cele trei niveluri: intern, conceptual şi extern. Acestea nu sunt
neapărat distincte pentru orice SGBD.
InterfeŃele numerotate din figura 1.1, ce descriu arhitectura de referinŃă a unui SGBD,
corespund următoarelor transformări:
a) Limbaj de descriere a datelor conceptuale, format sursă – permite administratorului
întreprinderii să definească schema conceptuală, format sursă.
b) Limbaj de descriere a datelor conceptuale, format obiect – se obŃine din compilarea celui
precedent şi permite aranjarea schemei obiect în dicŃionarul datelor.
c) Limbaj de descriere a datelor conceptuale, format editare – permite administratorilor
aplicaŃiilor şi a bazelor să consulte schema conceptuală pentru a defini reguli de
corespondenŃă.
d) Limbaje de descriere a datelor externe, format sursă – permit administratorilor
aplicaŃiilor să definească scheme externe corespunzând schemei conceptuale. Deoarece
sistemele de gestiune pot suporta mai multe modele externe, pot exista mai multe limbaje
de descriere a datelor externe.
e) Limbaje de descriere a datelor externe, format obiect – corespund formelor compilate ale
celor precedente şi permit aranjarea schemelor externe (obiect) în dicŃionarul datelor.
f) Limbaj de descriere a datelor interne, format sursă – permite administratorului bazei de
date să definească schema internă şi regulile de corespondenŃă cu schema conceptuală.
g) Limbaj de descriere a datelor interne, format obiect – corespunde formei compilate a
celui precedent şi permite aranjarea schemei interne (obiect) în dicŃionarul datelor.
h) Limbaje de prelucrare a datelor externe, format sursă – permit programatorilor de
aplicaŃii sau utilizatorilor neinformaticieni să manipuleze date externe (view).
i) Limbaje de prelucrare a datelor externe, format obiect – corespund formelor compilate
ale celor precedente.
j) Limbaj de prelucrare a datelor conceptuale, format obiect – produs de procesorul de
transformare extern/ conceptual pentru a manipula datele externe.
k) Limbaj de prelucrare a datelor interne, format obiect –produs de procesorul de
transformare conceptual/intern pentru a gestiona datele interne.
l) Limbaj de stocare a datelor, format obiect – corespunde interfeŃei cu sistemul de stocare
a datelor.
m) InterfaŃa cu memoria secundară – permite efectuarea de intrări/ieşiri în/din unitatea de
memorie secundară.
n) InterfaŃa de acces la dicŃionarul datelor – permite diverselor procesoare de transformare
să acceseze scheme obiect şi reguli de corespondenŃă.

Procesoarele din figura 1.1 au următoarele funcŃii:


• procesorul schemei conceptuale compilează schema conceptuală şi dacă nu sunt erori
depune schema compilată în dicŃionarul datelor;
• procesorul schemei externe compilează schemele externe şi regulile de corespondenŃă
externă şi dacă nu sunt erori aranjează schema compilată şi regulile de corespondenŃă în
dicŃionarul datelor;
• procesorul schemei interne are rol similar pentru schema internă;
• procesorul de transformare extern/conceptual transformă manipulările externe în
manipulări conceptuale şi invers, datele conceptuale în date externe;
• procesorul de transformare conceptual/intern transformă manipulările conceptuale în
manipulări interne şi invers, datele interne în date conceptuale;
• procesorul de transformare intern/stocare transformă manipulările interne în primitive ale
sistemului de stocare şi invers, eliberează datele stocate într-un format corespunzător
schemei interne.
administrator
întreprindere

a
administratorul c procesor c administratorul

DESCRIERE
bazei de date schema aplicaŃiilor
conceptuală

b
f d

g e
procesor dicŃionarul procesor
schema datelor schema
internă externă

procesor k procesor j procesor


intern/ conceptual/ extern/
alocare intern conceptual

l i

PRELUCRARE
sistem program
de aplicaŃii
alocare extern

h h
m
programator
aplicaŃie utilizatori

memorii
secundare

Fig. 1.1. Arhitectura de referinŃă a unui SGBD.


Gardarin a propus o arhitectură funcŃională apropiată de arhitectura sistemelor de gestiune
actuale care are la bază doar două niveluri:
• schema, care corespunde integrării schemelor interne şi conceptuale;
• vizualizarea, care este o schemă externă.
Sistemul de gestiune gestionează un dicŃionar de date care este alimentat prin comenzi de
definire a schemei şi prin comenzi de definire a vizualizărilor.
Aceste comenzi, precum şi cererile de prelucrare sunt analizate şi tratate de un procesor
numit analizor. Analizorul realizează analiza sintactică şi semantică a cererii şi o traduce în format
intern. O cerere în format intern care face referinŃă la o vizualizare este tradusă în una sau mai multe
cereri care fac referinŃă la obiecte ce există în baza de date (modificarea cererilor).
În cadrul acestei arhitecturi există un procesor, numit translator, care realizează modificarea
cererilor, asigură controlul drepturilor de acces şi controlul integrităŃii în cazul reactualizărilor.
Componenta cheie a sistemului de gestiune este procesorul optimizor care elaborează un
plan de acces optim pentru a trata cererea. Acest procesor descompune cererea în operaŃii de acces
elementare şi alege o ordine de execuŃie optimală. De asemenea, evaluează costul planului de acces
înaintea execuŃiei sale.
Planul de acces ales şi elaborat de optimizor este executat de un procesor numit executor. La
acest nivel este gestionat controlul concurenŃei.

1.4. EvoluŃia bazelor de date

Istoria bazelor de date şi a sistemelor de gestiune a bazelor de date poate fi rezumată în trei
generaŃii:
• sisteme ierarhice şi reŃea,
• sisteme relaŃionale,
• sisteme avansate (orientate obiect, relaŃionale orientate obiect, deductive, distribuite,
multimedia, multibaze, active, temporale, decizionale, magazii de date etc.).

Baze de date ierarhice şi reŃea


Pentru modelele ierarhice şi reŃea, datele sunt reprezentate la nivel de articol prin legături
ierarhice (arbore) sau de tip graf. Slaba independenŃă fizică a datelor complică administrarea şi
prelucrarea acestora. Limbajul de prelucrare a datelor impune programatorului să specifice drumurile
de acces la date.

Baze de date relaŃionale


A doua generaŃie de SGBD-uri este legată de apariŃia modelelor relaŃionale (1970), care
tratează entităŃile ca nişte relaŃii. PiaŃa actuală de baze de date este acoperită în majoritate de sisteme
relaŃionale. Bazele de date relaŃionale sunt caracterizate de:
• structuri de date simple, intuitive,
• inexistenŃa pointerilor vizibili pentru utilizator,
• constrângeri de integritate,
• operatori aplicaŃi relaŃiilor care permit definirea, căutarea şi reactualizarea datelor.
Dezvoltarea unei aplicaŃii riguroase utilizand o bază de date relaŃionale necesită cunoaşterea a
trei niveluri de instrumente, eterogene din punct de vedere conceptual:
• nivelul instrumentelor grafice (interfaŃa);
• nivelul aplicaŃie, cu limbajele sale de dezvoltare;
• nivelul SGBD, cu standardul SQL (Structured Query Language) ce permite definirea,
prelucrarea şi controlul bazei de date.

Baze de date orientate obiect


Bazele de date relaŃionale nu folosesc însă obiecte complexe şi dinamice, nu realizează
gestiunea datelor distribuite şi nici gestiunea cunoştinŃelor. A treia generaŃie de SGBD-uri, sistemele
avansate, încearcă să depăşească aceste limite ale sistemului relaŃional.
Suportul obiectelor complexe şi dinamice şi prelucrarea acestora este dificilă pentru sistemele
relaŃionale, deoarece tipul datelor este limitat la câteva domenii alfanumerice, iar structura datelor
este simplă. Sistemele relaŃionale nu modelează obiecte complexe ca grafuri, liste etc. Un obiect
complex poate să fie descompus în relaŃii, dar apar dificultăŃi atât la descompunerea, cât şi la
refacerea acestuia prin compunere. De asemenea, limbajele modelului relaŃional permit prelucrarea
cu dificultate a obiectelor complexe.
Un sistem relaŃional nu suportă obiecte dinamice care incorporează atât partea de date
(informaŃii) efective, cât şi o parte relativă la tratarea acestora.
Îmbinarea tehnicii limbajelor orientate obiect cu a bazelor de date a permis realizarea bazelor
de date orientate obiect. Acestea permit organizarea coerentă a obiectelor partajate între utilizatori
concurenŃi. Sistemele de gestiune de baze de date orientate obiect (SGBDOO) prezintă o serie de
avantaje:

• realizează o modelare superioară a informaŃiei,


• furnizează posibilităŃi superioare de deducŃie (ierarhie de clase, moştenire),
• permit luarea în considerare a aspectelor dinamice şi integrarea descrierii structurale şi
comportamentale,
• asigură îmbunătăŃirea interfeŃei cu utilizatorul.
Cu toate avantajele incontestabile oferite de SGBDOO-uri, impunerea lor pe piaŃa bazelor de
date nu a fost uşoară. Câteva motivaŃii a acestei situaŃii:
• absenŃa unei fundamentări teoretice face imposibilă definirea unui SGBDOO de referinŃă;
• gestiunea obiectelor complexe este mai dificilă decât accesul la relaŃii prin cereri SQL;
• utilizatorii au investit sume uriaşe în sistemele relaŃionale şi nu le pot abandona cu
uşurinŃă. Trecerea la noua tehnologie orientată obiect implică investiŃii mari şi nu
păstrează aproape nimic din vechile soluŃii.

Baze de date relaŃionale orientate obiect


Simplitatea modelului relaŃional, combinată cu puterea tehnologiei orientate obiect a generat
un domeniu nou şi promiŃător în lumea bazelor de date, şi anume bazele de date relaŃionale orientate
obiect.
ConstrucŃia unui sistem de gestiune de baze de date relaŃionale orientate obiect (SGBDROO)
trebuie să pornească de la cele existente. Aceasta se poate realiza în două moduri: dezvoltând un
sistem relaŃional prin adăugarea caracteristicilor obiectuale necesare sau pornind de la un sistem
orientat obiect şi adăugând caracteristicile relaŃionale.

Baze de date deductive


O relaŃie este o mulŃime de înregistrări ce reprezintă fapte. CunoştinŃele sunt aserŃiuni
generale şi abstracte asupra faptelor. CunoştinŃele permit să raŃionezi, ceea ce permite deducerea de
noi fapte, plecând de la fapte cunoscute. Un SGBD relaŃional suportă o formă limitată de cunoştinŃe,
şi anume constrângerile de integritate, iar restul trebuie integrate în programele de aplicaŃie. Aceasta
generează probleme deoarece cunoştinŃele trebuie codificate în programe şi apare imposibilitatea de
a partaja cunoştinŃe între utilizatori. Totul se complică dacă există un volum mare de fapte.
Bazele de date deductive, utilizând programarea logică, gestionează cunoştinŃe relativ la baze
de date care, în general, sunt relaŃionale. Bazele de date deductive permit deducerea de noi
informaŃii, plecând de la informaŃiile stocate în baza de date. Un SGBD deductiv posedă:
• un limbaj de definire a datelor care permite definirea structurii predicatelor sub formă de
relaŃii şi constrângeri de integritate asociate;
• un limbaj de prelucrare a datelor care permite efectuarea reactualizărilor asupra datelor şi
formularea unor cereri;
• un limbaj de reguli de deducŃie care permite ca, plecând cu predicatele definite anterior,
să se specifice cum pot fi construite predicate derivate.

Baze de date distribuite


Un sistem distribuit este un ansamblu de maşini ce sunt interconectate printr-o reŃea de
comunicaŃie şi utilizate într-un scop global. Administrarea şi prelucrarea datelor distribuite, situate pe
diferite calculatoare şi exploatate de sisteme eterogene este obiectivul fundamental al bazelor de date
distribuite.
Bazele de date distribuite sunt sisteme de baze de date cooperante care rezidă pe maşini
diferite, în locuri diferite. Această mulŃime de baze de date este exploatată de utilizator ca şi cum ar
fi o singură bază de date. Programul de aplicaŃie care exploatează o bază de date distribuite poate
avea acces la date rezidente pe mai multe maşini, fără ca programatorul să cunoască localizarea
datelor.
Modelul relaŃional a rămas instrumentul principal prin care se realizează prelucrarea datelor
distribuite.
Câteva dintre argumentele pentru a justifica această afirmaŃie sunt:
• bazele relaŃionale oferă flexibilitate de descompunere în vederea distribuirii;
• operatorii relaŃionali pot fi folosiŃi pentru combinaŃii dinamice ale informaŃiilor
descentralizate;
• limbajele sistemelor relaŃionale sunt concise şi asigură o economie considerabilă a
transmiterii datelor. Ele fac posibil, pentru un nod oarecare al reŃelei, să analizeze intenŃia
unei tranzacŃii, să o descompună rapid în componente ce pot fi realizate local şi
componente ce pot fi transportate altor noduri.

Calculatoare şi maşini baze de date


SoluŃia pentru a descentraliza prelucrarea datelor, în scopul evitării saturării memoriei şi a
procesoarelor calculatorului central, a fost apariŃia calculatoarelor baze de date şi a maşinilor baze de
date. Descentralizarea presupune transferarea unei părŃi din funcŃiile unui SGBD către un calculator
periferic (calculator backend) adică deplasarea algoritmilor de căutare şi a celor de actualizare a
datelor mai aproape de memoria secundară. Acest calculator periferic permite utilizarea optimă a
resurselor şi realizarea paralelismului în tratarea cererilor de informaŃii.
Calculatorul periferic poate fi un calculator clasic, dar cu un software specific de SGBD
(calculator bază de date) sau poate fi o maşină cu hardware specializat în gestiunea bazelor de date
(maşină bază de date). Maşinile baze de date sunt înzestrate cu arhitecturi paralele special adaptate
pentru gestionarea unui volum mare de date. Tratarea paralelă a cererilor permite reducerea timpului
total de execuŃie a acestora.
O execuŃie în paralel solicită, fie descompunerea unui program în module, care pot fi
executate în paralel (descompunere funcŃională), fie descompunerea datelor în subgrupe, astfel încât
toate procesoarele să execute acelaşi lucru, dar pe date diferite. PerformanŃele tratării paralele depind
de modul în care sunt efectuate descompunerile.

Multibaze de date
Diferite departamente ale unei organizaŃii mai mari pot folosi diferite sisteme de gestiune. Cu
toate că fiecare sistem este dezvoltat pentru a satisface nevoile propriului său departament,
informaŃiile cu care lucrează pot fi utile şi altor departamente. De aceea, pentru ca organizaŃia să
funcŃioneze bine, trebuie să existe o modalitate globală da a vedea datele din fiecare sistem. Există
două caracteristici ale unor astfel de sisteme care fac acceasarea datelor în acest mediu integrat
greoaie, uneori chiar imposibilă:
• autonomie – fiecare SGBD are o autonomie completă, ceea ce înseamnă că fiecare
manager are control deplin asupra sistemului;
• eterogenitate – sistemele pot opera pe diferite platforme, cu diferite modele de date şi
limbajele de interogare.
Una dintre soluŃiile folosite pentru a depăşi dificultăŃile întâmpinate în respectarea autonomiei şi
a eterogenităŃii este utilizarea sistemelor multibaze de date.
Un sistem multibaze de date (SMB) este alcătuit din mai multe sisteme de baze de date privite
integrat, în care se construiesc una sau mai multe scheme globale pe baza schemelor fiecărei baze de
date componente, astfel încât să se poată realiza accesul uniform şi integrat la fiecare din bazele de date
componente. Fiecare schemă globală este construită pe baza unui model particular de date. De exemplu,
se poate construi o schemă globală ce are la bază modelul relaŃional pentru utilizatorii care sunt
familiarizaŃi cu acest model, dar se poate construi o schemă globală bazată pe modelul orientat obiect
pentru utilizatorii bazelor de date orientate obiect.
Pentru o schemă globală dată, un sistem multibaze de date constă din sistemele componente
împreună cu un sistem front-end, care suportă un singur model de date şi un singur limbaj de interogare.
Principalele sarcini ale sistemului front-end sunt gestionarea schemei globale şi procesarea cererilor
globale.
Un avantaj major al acestui model, faŃă de altele, este faptul că o singură interogare poate accesa
date din mai multe baze de date într-un mod integrat, fără să afecteze nici o aplicaŃie care este scrisă
utilizând una dintre bazele de date componente.

Baze de date cu suport decizional


Sistemele informatice, în particular bazele de date, au ajuns la maturitate. Marile companii au
acumulat o mare cantitate de informaŃii din domeniul lor de activitate, pe care le păstrează în tabele
istorice şi sunt nefolositoare sistemelor operaŃionale ale companiei, care funcŃionează cu date
curente. Analizate, aceste date ar putea oferi informaŃii despre tendinŃe şi evoluŃii care ar putea
interesa compania. Pentru a putea analiza aceste mari cantităŃi de date este nevoie de tehnologii şi
instrumente speciale.
Ideea de a analiza colecŃii de date provenind din sistemele operaŃionale ale companiei sau din
surse externe pentru a le folosi ca suport în procesul de decizie nu aparŃine ultimului deceniu, dar
baze de date care să funcŃioneze eficient după aceste criterii au fost studiate şi implementate în
ultimii ani. Principalul scop al acestor baze de date a fost de a întâmpina nevoile sistemelor
operaŃionale, a căror natură este inerent tranzacŃională.
Sistemele tranzacŃionale sunt interesate, în primul rând, să controleze la un moment dat o
singură tranzacŃie. De exemplu, într-un sistem bancar, atunci când clientul face un depozit, sistemul
operaŃional bancar este responsabil de a înregistra tranzacŃia într-un tabel al tranzacŃiilor şi de a
creşte nivelul curent al contului clientului, stocat în alt tabel.
Un sistem operaŃional tipic operează cu evenimente predefinite şi, datorită naturii lor,
necesită acces rapid la date. Uzual, fiecare tranzacŃie operează cu cantităŃi mici de date.
De-a lungul timpului, nevoile sistemelor operaŃionale nu se schimbă mult. AplicaŃia care
înregistrează tranzacŃia, ca şi cea care controlează accesul utilizatorului la informaŃie (partea de
raportare a sistemului bancar), nu se modifică prea mult. În acest tip de sistem, informaŃia necesară
în momentul în care un client iniŃiază o tranzacŃie trebuie sa fie actuală. Înainte ca o bancă să aprobe
un împrumut este nevoie să se asigure de situaŃia financiară stabilă a clientului în acel moment, şi nu
cu un an înainte.
În ultimii ani s-au pus la punct principii şi tehnologii noi care să servească procesului de
analiză şi administrare a datelor. O bază de date optimizată în acest scop defineşte o Data
Warehouse (magazie de date), iar principiul pe care îl urmează este cunoscut sub numele de
procesare analitică (OLAP – On Line Analytical Processing). Spre deosebire de acesta, principiul pe
care se bazează sistemele tranzacŃionale a fost numit procesare tranzacŃională (OLTP – On Line
Transactional Processing).
AplicaŃiile unei Data Warehouse trebuie să ofere răspunsuri unor întrebări de tipul: „Care zi
din săptămână este cea mai aglomerată?“ „Ce clienŃi, cu care avem relaŃii intense, nu au beneficiat de
reduceri de preŃuri?“. O caracteristică a bazelor de date analitice este că interogările la care acestea
trebuie să răspundă sunt ad-hoc, nu sunt predefinite, iar baza de date trebuie optimizată astfel încât să
fie capabilă să răspundă la orice fel de întrebare care poate implica mai multe tabele.
În această abordare, organele generale de decizie necesită accesul la toate datele organizaŃiei,
oriunde s-ar afla acestea. Pentru o analiză corespunzătoare a organizaŃiei, afacerilor, cerinŃelor,
tendinŃelor este necesară nu numai accesarea valorilor curente din baza de date, ci şi a datelor
istorice. Prin urmare, pentru a facilita acest tip specific de analiză a informaŃiei a fost creată magazia
de date, care conŃine informaŃii extrase din diverse surse, întreŃinute de diverse unităŃi
operative, împreună cu istoricul şi rezumatul tranzacŃiilor.
Sursele de date pentru o magazie cuprind:
• date operaŃionale, păstrate în baze de date ierarhice, de prima generaŃie;
• date departamentale, păstrate în sisteme de fişiere patentate;
• date cu caracter personal, păstrate pe staŃii de lucru şi servere personale;
• sisteme externe (baze de date comerciale, Internet etc.)

Data warehouse este o colecŃie de date:


• orientate spre subiect (principalele subiecte ale modelului sunt clienŃii, produsele,
vânzările, în loc de domeniile de activitate),
• nevolatile (datele nu sunt reactualizate, înlocuite în timp real, ci sunt adăugate ca un
supliment al bazei),
• integrate (transpunerea datelor provenite din diverse surse de informaŃii se face într-un
format consistent),
• variabile în timp (concentrarea depozitului de date se face asupra schimbărilor care au loc
în timp).

Administrator Depozit de Utilitare


date cereri,
META- rapoarte
FLUX
Sursa 1 Metadate
Date
Date cu nivel
operationale
mare de Utilitar
Administrato agregare Administrat e
FLUX r incarcare or cereri OLAP
INTERN date
FLUX
Date cu nivel
EXTERN
mic de FLUX
agregare ASCENDENT
Date detaliate Utilitare
SGB Data
D mining
Sursa n
Date Administrator Depozit de
operationale date
Utilitare pentru
Arhive/ date FLUX accesul
backup DESCENDEN utilizatorilor
T
Fig 1.2. Arhitectura unui depozit de date
Înmagazinarea datelor se concentrează asupra gestionării a cinci fluxuri de informaŃii:
• fluxul intern, care reprezintă procesele asociate extragerii şi încărcării datelor din fişierele
sursă în magazia de date;
• fluxul ascendent, care reprezintă procesele asociate adăugării de valoare datelor din
magazie, cu ajutorul împachetării şi distribuirii;
• fluxul descendent, care reprezintă procesele asociate arhivării, salvării, refacerii datelor
din magazie;
• fluxul extern, care reprezintă procesele asociate punerii la dispoziŃie a datelor pentru
utilizatorii finali;
• meta-fluxul, care reprezintă procesele asociate gestionării meta-datelor (date despre date).
În arhitectura depozitului de date intervin câteva componente specifice acestei structuri.
• Administratorul pentru încărcarea datelor (componenta front-end) realizează toate
operaŃiile asociate cu obŃinerea (extragerea) şi încărcarea datelor operaŃionale într-un
depozit de date.
• Administratorul depozitului de date realizează toate operaŃiile legate de administrarea
datelor din depozit. OperaŃiile realizate de componenta de administrare a depozitului de
date includ: analiza datelor pentru a asigura consistenŃa acestora; transformarea şi mutarea
datelor sursă din structurile temporare de stocare în tabelele depozitului de date; crearea
de indecşi şi vizualizări asupra tabelelor de bază; generarea denormalizării (dacă este
necesar); generarea agregărilor; crearea arhivelor şi a backup-urilor.
• Administratorul cererilor (componenta back-end) realizează toate operaŃiile legate de
administrarea cererilor utilizator. Această componentă este construită folosind utilitarele
de acces la date disponibile utilizatorilor finali, utilitarele de monitorizare a depozitului de
date, facilităŃile oferite de sistemul de baze de date şi programele personalizate.
• În zona ce include date agregate sunt stocate toate agregările predefinite de date, pe
diferite niveluri. Scopul, menŃinerii acestora, este de a mări performanŃa cererilor care
necesită agregări. Datele agregate sunt actualizate permanent, pe măsură ce sunt încărcate
noi informaŃii în depozit.
• Scopul principal al depozitelor de date este de a oferi informaŃii necesare utilizatorilor
pentru luarea deciziilor strategice de marketing. Aceşti utilizatori interacŃionează cu
depozitul de date prin diferite utilitare de acces (utilitare pentru rapoarte şi cereri, utilitare
pentru dezvoltarea aplicaŃiilor, utilitare pentru procesarea analitică on-line (OLAP),
utilitare data mining) etc.
Instrumentele de acces pentru utilizatorii finali ai magaziilor de date:
• prelucrarea analitică on-line;
• extensiile limbajului SQL;
• instrumentele de extragere a datelor.
Prelucrarea analitică on-line (OLAP) reprezintă sinteza, analiza şi consolidarea dinamică a
unor volume mari de date multidimensionale. Serverele de baze de date OLAP utilizează structuri
multidimensionale pentru stocarea datelor şi a relaŃiilor dintre date. Aceste structuri pot fi vizualizate
prin cuburi de date şi cuburi în cadrul cuburilor etc. Fiecare latură a cubului reprezintă o dimensiune.
Serverele de baze de date OLAP multidimensionale acceptă operaŃiile analitice uzuale: consolidarea
(gruparea), parcurgerea în jos (inversul consolidării), tranşarea, tăierea. OLAP necesită o modalitate
de agregare a datelor conform mai multor grupări diferite, în număr foarte mare, iar utilizatorii
trebuie să le aibă în vedere pe toate.
Instrumentele OLAP presupun organizarea informaŃiei într-un model multidimensional care
este susŃinut de o bază de date:
• multidimensională (MOLAP), în care datele sunt stocate conceptual în celulele unui
tablou multidimensional;
• relaŃională (ROLAP), proiectată pentru a permite interogări multidimensionale.
În acest context, a devenit o necesitate extinderea limbajului SQL prin operaŃii puternice,
necesare pentru rezolvarea noului tip de abordare. Au fost introduse noi funcŃii numerice (limita
inferioară, limita superioară etc.), noi funcŃii statistice (distribuŃie, distribuŃie inversă, corelaŃie etc.),
noi operatori de agregare, extensii ale clauzei GROUP BY etc.
De exemplu, RISQL (Red Brick Intelligent SQL), proiectat pentru analiştii din domeniul
afacerilor, permite: ordonare după rang (pe diferite niveluri - de exemplu, gruparea filialelor în trei
categorii pe baza venitului generat în anul precedent), partajarea pieŃei, compararea anului curent cu
cel precedent etc.
O altă problemă esenŃială este extragerea datelor şi utilizarea acestora pentru luarea de decizii
cruciale în domeniul afacerilor. Descoperirea unor noi corelaŃii, tipare, tendinŃe, prin extragerea unor
cantităŃi mari de date folosind strategia inteligenŃei artificiale este una din modalităŃile de rezolvare.
Extragerea datelor presupune capacitatea de a construi modele mai degrabă previzibile, decât
retrospective. Modelarea predictivă utilizează informaŃii pentru a forma un model al caracteristicilor
importante ale unui fenomen.
Tehnicile asociate operaŃiilor fundamentale de extragere sunt:
• modelarea predictivă (clasificarea cu ajutorul unei reŃele neurale sau al unei inducŃii de
tip arbore şi previziunea valorilor, utilizând tehnici de regresie);
• segmentarea bazei de date (comasarea demografică şi comasarea neurală care se
deosebesc prin metodele uilizate pentru a calcula distanŃa dintre înregistrări, prin intrările
de date permise);
• analiza legăturilor (descoperirea asocierilor, descoperirea tiparelor, descoperirea
secvenŃelor de timp similare);
• detectarea deviaŃiilor (statistici şi vizualizări pentru identificarea împrăştierii datelor,
utilizând tehnici moderne de vizualizare grafică). În această clasă pot fi considerate, de
exemplu, detectarea fraudelor privind utilizarea cărŃilor de credit, pretenŃiile de
despăgubire ale asiguraŃilor etc.
În concluzie, spre deosebire de un sistem OLTP, Data Warehouse este o bază de date a cărei
structură este proiectată pentru a facilita analiza datelor. Un sistem de suport decizional urmăreşte, în
primul rând, obŃinerea de informaŃii din baza de date, în timp ce unul OLTP urmăreşte introducerea
de informaŃii în baza de date. Datorită acestor diferenŃe, structura optimă a unei Data Warehouse este
radical diferită de cea a unui sistem OLTP.
Depozitele de date şi sistemele OLTP sunt supuse unor cerinŃe diferite, dintre care cele mai
semnificative se referă la operaŃii, actualizarea datelor, proiectare, operaŃii tipice şi date istorice.
• OperaŃii. Depozitele sunt create pentru a permite interogări ad hoc. Ele trebuie să fie
suficient de flexibile pentru a putea răspunde interogărilor spontane ale utilizatorilor.
Sistemele OLTP suportă numai operaŃii predefinite. AplicaŃiile pot fi optimizate sau
create special numai pentru acele operaŃii.
• Actualizarea datelor. Utilizatorii finali ai unui depozit de date nu fac în mod direct
actualizări ale depozitului. În sistemele OLTP, utilizatorii realizează, de obicei, în mod
individual procedurile de modificare a bazei de date. În acest fel, baza de date OLTP este
întotdeauna la zi şi reflectă starea curentă a fiecărei tranzacŃii.
• Proiectare. Depozitele de date folosesc, în mod uzual, scheme denormalizate, în timp ce
sistemele OLTP folosesc scheme normalizate pentru a optimiza performanŃele operaŃiilor.
• OperaŃii tipice. O simplă interogare a depozitului de date poate scana mii sau chiar
milioane de înregistrări (de exemplu, cererea „Care sunt vânzările totale către toŃi clienŃii
din luna trecută?“), în timp ce o operaŃie tipică OLTP accesează doar o parte mai mică din
înregistrări.
• Date istorice. Depozitele de date stochează datele pe o perioadă lungă de timp, luni sau
ani. Acest lucru oferă suport pentru analiza istorică a informaŃiei. Sistemele OLTP reŃin
date istorice atât timp cât este necesar pentru a îndeplini cu succes cerinŃele tranzacŃiilor
curente.

Sistemele OLTP Data Warehouse


Păstrează date curente Păstrează date istorice
Stochează date detaliate, agregate uşor
Stochează date detaliate
sau puternic
Datele sunt dinamice Datele sunt în mare măsură statice
Prelucrare ad-hoc, nestructurată şi
Prelucrare repetitivă
euristică
Nivel înalt de transfer al Nivel mediu sau scăzut de transfer al
tranzacŃiilor tranzacŃiilor
Tipar de utilizare previzibil Tipar de utilizare imprevizibil
Conduse prin tranzacŃii Conduse prin analiză
SusŃin deciziile de zi cu zi SusŃin deciziile strategice
Deservesc un număr mare de Deservesc un număr relativ redus de
utilizatori utilizatori din administraŃie
Orientate spre aplicaŃii Orientate spre subiect

Fig. 1.3. OLTP versus Data Warehouse


O bază de date OLAP poate fi relaŃională, dar datorită naturii ei orientate spre dimensiuni, au
fost dezvoltate pentru gestionarea acestor baze de date construcŃii multidimensionale, mai potrivite
pentru o raportare flexibilă. Spre deosebire de bazele de date relaŃionale, structura unei baze de date
multidimensionale nu implică tabele, linii şi coloane, ci obiecte de următoarele tipuri: variabile,
dimensiuni, niveluri, ierarhii, atribute.
Data Warehouse, care cuprinde de obicei informaŃii despre o întreagă companie, poate fi
subîmpărŃită în baze de date departamentale, numite rafturi de date (Data Marts). De exemplu, poate
exista un Data Mart al departamentului financiar, un altul al departamentului vânzări şi un altul
pentru departamentul marketing.
ConstrucŃia unei astfel de baze de date poate fi abordată în două moduri.
• O primă abordare este de a construi mai întâi un schelet al bazei de date la care se
lipesc ulterior rafturile de date. Aceasta necesită o analiză prealabilă a întregului şi o
delimitare a blocurilor componente. Ea cere un timp mai lung de dezvoltare, dar
rezultatul este o bază de date unitară.
• A doua metodă este de a construi mai întâi rafturi specifice, efortul constând, în acest
caz, în asocierea acestora. Această soluŃie oferă mai rapid, aplicaŃii funcŃionale
utilizatorilor, dar au de suferit unitatea şi portabilitatea aplicaŃiilor finale.
Utilizatorii trebuie să-şi schimbe optica asupra bazelor de date pentru a fi capabili să
folosească puterea şi flexibilitatea instrumentelor analitice de care dispun. Instrumentele OLAP au
evoluat ca o modalitate de a rezolva interogările complicate necesare procesului de analiză a datelor.
CombinaŃia între bazele de date multidimensionale şi instrumentele analitice prietenoase face uşoară
analiza, sinteza şi consolidarea datelor.
În ultimii ani, marii producători de sisteme de gestiune a bazelor de date relaŃionale, precum
Oracle, au introdus în produsele lor construcŃii care să faciliteze accesul la datele din sistemele
fundamentale pentru luarea de decizii. Astfel, noile versiuni de SGBD-uri ale firmelor mari prevăd o
modalitate mai inteligentă de a realiza operaŃia de compunere între două sau mai multe tabele,
metode de indexare noi, potrivite pentru marile cantităŃi de date statice cu care operează sistemele
Data Warehouse, capacitatea de a detecta şi optimiza interogări de un tip special, posibilitatea de a
folosi mai multe procesoare pentru a rezolva o interogare.
Un sistem Data Warehouse are un efect fundamental asupra utilizatorilor. Ei pot manevra
mult mai flexibil sistemul, au posibilităŃi elevate pentru interogarea datelor, dar ei trebuie să ştie cum
să prelucreze şi să vizualizeze datele şi cum să le folosească în procesul de decizie.
Un efort ce trebuie făcut pentru construirea unui sistem de suport pentru decizii (DSS –
Decision Support System) constă în procesul de descoperire a informaŃiilor utile din baza de date.
Acest proces, numit Data Mining sau Knowledge Discovery in Databases (KDD), procesează mari
cantităŃi de date, a căror corelare nu este neapărat evidentă, în vederea descoperirii de tendinŃe şi
tipare.

1.5. Arhitecturi multi-user pentru sisteme de gestiune a


bazelor de date

Arhitecturile uzuale care sunt utilizate pentru implementarea sistemelor de gestiune a bazelor
de date multi-user sunt: teleprocesarea, arhitectura fişier-server arhitectura client-server.
Teleprocesarea este arhitectura tradiŃională, ce cuprinde un calculator cu o singură unitate
CPU şi un numar de terminale care sunt incapabile să funcŃioneze singure. Terminalele trimit mesaje
la programele aplicaŃie ale utilizatorilor, care la rândul lor, utilizează serviciile SGBD.
Această arhitectură a plasat o greutate teribilă asupra calculatorului central, care pe lângă
rularea programelor de aplicaŃii şi ale SGBD-ului, mai trebuie să preia şi din munca terminalelor (de
exemplu, formatarea datelor pentru afişarea pe ecran).
Arhitectura fişier-server, presupune deja că procesarea este distribuită în reŃea (de obicei o
reŃea locală LAN). Arhitectura cuprinde fişierele cerute de aplicaŃii şi SGBD-ul. AplicaŃiile şi
funcŃiile SGBD sunt executate pe fiecare staŃie de lucru, solicitând când este nevoie fişiere de pe
server-ul de fişiere. Dintre dezavantaje se remarcă:
• existenŃa unui trafic intens pe reŃea;
• necesitatea unei copii complete a SGBD-ului pe fiecare staŃie de lucru;
• acelaşi fişier poate fi accesat de mai multe SGBD-uri, ceea ce implică un control complex
al integrităŃii, simultaneităŃii, reconstituirii.
Arhitectura client-server se referă la modul în care interacŃionează componentele software
pentru a forma un sistem. Există un proces client, care necesită resurse şi un proces server, care oferă
resurse.
În arhitectura client-server, clientul (front end) emite, prin intermediul reŃelei locale, o cerere
SQL care este executată pe server (back-end); acesta trimite ca răspuns ansamblul înregistrărilor
rezultat. Într-o astfel de interacŃiune maşinile sunt eterogene, iar protocoalele de reŃea pot fi distincte.
În contextul bazelor de date, client-ul:
• administrează interfaŃa cu utilizatorul şi logica aplicaŃiei;
• acceptă şi verifică sintaxa intrărilor utilizatorilor;
• procesează aplicaŃiile;
• generează cerinŃele pentru baza de date şi le trimite server-ului;
• transmite răspunsul înapoi la utilizator.
În contextul bazelor de date, server-ul:
• primeşte şi procesează cerinŃele clienŃilor pentru baza de date;
• verifică autorizarea;
• garantează respectarea constrângerilor de integritate;
• efectuează procesarea interogare-reactualizare şi trimite clientului răspunsul;
• realizează optimizarea interogărilor;
• asigură controlul concurenŃei dintre mai multi clienŃi care se ignoră (mecanisme de
blocare);
• intreŃine dictionarul datelor;
• oferă acces simultan la baza de date;
• asigură robusteŃea în cazul defecŃiunilor;
• oferă controlul reconstituirii etc.
Arhitectura tradiŃională client-server pe „două etaje (straturi)“ presupune:
• client-ul – responsabil, în primul rand, de prezentarea datelor către client;
• server-ul – responsabil, în primul rand, de furnizarea serviciilor către client.
Arhitectura client-server pe „trei etaje“ presupune trei straturi, fiecare fiind rulat, potenŃial, pe
o platformă diferită.
• stratul (client) format din interfaŃa cu utilizatorul, care este rulat pe calculatorul
utilizatorului final;
• stratul (server de aplicaŃie), ce manevrează logica aplicaŃiilor şi prelucrării datelor, şi
care poate servi mai mulŃi clienŃi (conectare la celelalte două straturi se face prin reŃele
locale LAN sau de mare suprafaŃă WAN);
• stratul (server-ul de baze de date), care se ocupă cu validarea datelor şi accesarea bazei
de date (stochează date necesare stratului din mijloc).
Arhitectura se potriveşte natural mediului Web. Un browser Web acŃionând drept client şi un
server Web fiind server de aplicaŃie.
Middleware este un strat, evident software, între aplicaŃia postului client şi server-ul de baze
de date, constituit dintr-o interfaŃă de programare a aplicaŃiilor (API - Application Programming
Interface) şi un protocol de reŃea.
API descrie tipul de interacŃiune dintre o aplicaŃie client şi un server la distanŃă, via un
protocol de comunicaŃie şi de formatare a datelor. Scopul existenŃei interfeŃei de programare a
aplicaŃiilor este de a oferi o interfaŃă unică mai multor server-e de baze de date.
Este convenabil ca sistemele de baze de date să fie considerate ca fiind formate dintr-un
server (sistemul SGBD însăşi) şi un set de clienŃi (aplicaŃiile). Frecvent, clienŃii şi server-ul pot fi
rulate pe calculatoare diferite, realizându-se un tip simplu de procesare distribuită. În general, fiecare
server poate deservi mai multi clienŃi, iar fiecare client poate accesa mai multe server-e. Dacă
sistemul oferă transparenŃă totală (fiecare client se poate comporta ca şi cum ar comunica cu un
singur server, de pe un singur calculator) atunci este vorba despre un sistem de baze de date
distribuite.
SQL*PLUS

• SQL este un limbaj de comenzi pentru comunicare cu server-ul Oracle.


• SQL*Plus este un utilitar Oracle care recunoaşte comenzile SQL şi trimite aceste comenzi
server-ului Oracle pentru execuŃie.

SQL*Plus  instrument puternic care este utilizat în dezvoltarea aplicaŃiilor pentru baza de
date Oracle.
SQL*Plus  instrument flexibil care poate fi executat pe toate platformele pe care se instalează
produsul Oracle.

Ce operaŃii se pot realiza din consola SQL*Plus ?


• editarea, salvarea, încărcarea şi execuŃia de comenzi SQL sau blocuri PL/SQL;
• formatarea, salvarea, tipărirea şi realizarea anumitor calcule asupra rezultatelor unei interogări
sub formă de rapoarte;
• listarea definiŃiilor tabelelor;
• accesarea şi transferarea datelor între baze de date;
• realizarea unor funcŃii de administrare a BD: administrarea utilizatorilor, administrarea spaŃiilor
tabel, operaŃii de arhivare şi recuperare etc.

Deosebiri esenŃiale între comenzile SQL şi comenzile SQL*Plus.


Marcăm dintre aceste deosebiri câteva, care sunt semnificative. Comenzile SQL*Plus:
• nu cer caracter de terminare;
• cer un caracter de continuare dacă comanda este mai mare decât o linie;
• nu sunt depuse în buffer-ul SQL;
• nu permit prelucrarea datelor din baza de date;
• foloseste comenzi pentru formatarea datelor (SQL foloseste functii);
• cuvintele cheie pot fi prescurtate.

Conexiune la SQL*Plus
După ce utilizatorul se conectează la SQL*Plus, sistemul afişează un prompt (SQL>) şi
aşteaptă comenzile utilizatorului. Utilizatorul poate da:
• comenzi SQL pentru accesarea bazei de date;
• blocuri PL/SQL pentru accesarea bazei de date;
• comenzi SQL*Plus.

Activarea interfeŃei SQL*Plus


1. Din WINDOWS:
Se selecteaza: START > PROGRAMS > ORACLE > APPLICATION DEVELOPMENT >
SQL*Plus
Se da username, password si numele bazei.
2. Prin linia de comanda:
SQLPLUS [nume_utiliz/parola][@nume_baza_de_date] [@nume_fisier]
Închiderea sesiunii de lucru SQL*Plus şi preluarea controlului sistemului de operare al
calculatorului gazdă se realizează cu QUIT sau EXIT.
Conectarea la o altă bază de date, decât cea deschisă iniŃial, în timpul unei sesiuni de lucru
SQL*Plus:
CONNECT [nume_utilizator[/parola]][@nume_baza_de_date]
Conexiunea rămâne validă până când apare una din următoarele situaŃii:
• se părăseşte SQL*Plus;
• se dă comanda de deconectare DISCONNECT (comanda nu închide sesiunea de lucru
SQL*Plus);
• se face conectarea la o altă bază de date.

Crearea unei legături între BD locală şi o BD aflată la distanŃă:


CREATE [PUBLIC] DATABASE LINK nume_legatura
CONNECT TO nume_utilizator
IDENTIFIED BY parola
USING baza_de_date_distanta
După ce legătura a fost creată, pot fi făcute interogări asupra tabelelor corespunzătoare BD
distante prin specificarea numelui legăturii în clauza FROM din cerere. Dacă se specifică opŃiunea
PUBLIC, legătura este disponibilă tuturor utilizatorilor cu excepŃia celor care şi-au definit o legătură
privată cu acelaşi nume.

Suprimarea unei legături între două BD, una locală şi una la distanŃă:
DROP [PUBLIC] DATABASE LINK nume_legatura.
Câteva dintre cele mai importante comenzi disponibile în SQL*Plus :
ACCEPT – citeşte o variabilă de intrare de la utilizator;
DEFINE – declară o variabilă (DEF);
DESCRIBE – listează atributele tabelelor sau ale altor obiecte (DESC);
EDIT – invoca editorul, salveaza continutul buffer-ului in fisierul afiedt.buf;
EXIT sau QUIT – deconectează utilizatorul şi încheie sesiunea SQL*Plus;
GET – caută un fişier SQL şi îl depune în buffer-ul SQL;
HOST – execută o comandă a sistemului de operare (!);
LIST – afişează ultima comandă executată din buffer-ul SQL (L);
PROMPT – afişează un text pe ecran;
RUN – listează şi execută comanda salvată în buffer-ul SQL (/);
SAVE – salvează comanda din buffer-ul SQL într-un fişier script;
SET – modifică variabilele de mediu specifice SQL*Plus;
SHOW – afişează setările variabilelor de mediu SQL*Plus;
SPOOL – copiază ieşirea unei comenzi într-un fişier;
START – execută un script SQL (@).

Salvarea comenzilor
Comanda SQL, care este introdusă interactiv prin interfaŃa SQL*Plus, este memorată într-un
buffer SQL. Ea poate fi modificată sau executată de mai multe ori, atâta timp cât utilizatorul nu a
introdus o nouă comandă sau nu a şters explicit buffer-ul SQL (CLEAR BUFFER). Cererea nouă va
şterge vechea cerere din buffer.
Utilizatorul poate salva una sau mai multe comenzi într-un fişier, ce ulterior poate fi încărcat,
modificat sau executat. Extensia implicită a fişierului: .sql.
SAVE nume_fisier [CREATE|REPLACE|APPEND]

comenzi SQL BUFFER comenzi SQL

SQL*Plus SERVER

comenzi SQL*Plus rezultatul cererii

RAPORT
(formatat)

Display calculator

SAVE alfa
EDIT alfa
@alfa

• opŃiunea CREATE arată că se creează un nou fişier;


• opŃiunea REPLACE permite înlocuirea (overwrite) unui fişier existent;
• opŃiunea APPEND adaugă conŃinutul buffer-ului în continuarea unui fişier.
Pentru încărcarea şi executarea unui fişier de comenzi poate fi utilizată una din
următoarele variante:
• comanda START;
• comanda ∂;
• comenzile GET şi RUN;
• comenzile GET şi /.
Pentru introducerea de comentarii printre comenzile care se găsesc într-un fişier există mai
multe posibilităŃi:

• utilizarea caracterelor “--” urmate de textul comentariului;

• utilizarea delimitatorilor “/*” şi “*/” pentru a marca începutul şi sfârşitul unui


comentariu.

Pentru a obŃine informaŃii referitoare la structura tabelelor, vizualizărilor sau sinonimelor, a


procedurilor, funcŃiilor sau pachetelor fără a fi necesară consultarea cataloagelor de sistem, se
utilizează comanda:
DESCRIBE [nume_schema.]nume_obiect

Editarea comenzilor
Editorul integrat SQL *Plus (mini-editor mod linie) se încarcă prin:
EDIT [nume_fisier[.extensie]]
Dacă se doreşte lansarea în execuŃie a unui alt editor, se modifică variabila EDITOR cu
ajutorul comenzii DEFINE. De exemplu:
DEFINE _EDITOR = vi
SQL*Plus păstrează în memorie ultima comandă executată. Comenzile SQL*Plus nu sunt
depuse în buffer-ul SQL. Ele se dau secvenŃial, câte una la un moment dat. Dacă comanda este prea
lungă, ea va fi continuată pe linia următoare tastând caracterul „–” la sfârşitul liniei, înainte de a tasta
RETURN.
Pentru editarea comenzilor SQL şi a blocurilor PL/SQL se pot folosi:
• A[PPEND] text – adaugă textul specificat la sfârşitul liniei curente din buffer-ul SQL;
• C[HANGE] separator old [separator [new [separator]]] – schimbă textul old cu textul
new (ca separator se poate folosi orice caracter care nu este alfanumeric);
• DEL {n | n m | n * | n LAST | * | * n | * LAST | LAST} – şterge una sau mai multe linii
din buffer-ul SQL (caracterul “*” indică linia curentă); DEL fără nici o clauză are ca efect
ştergerea liniei curente;
• CL[EAR] BUFF[ER] – sterge toate liniile din buffer-ul SQL;
• I[NPUT] [text] – adaugă una sau mai multe linii de text după linia curentă din buffer;
• n text – inlocuieste linia n prin text;
• L[IST] {n | n m | n * | n LAST | * | * n | * LAST | LAST} – listează una sau mai multe
linii din buffer (caracterul “*” indică linia curentă); LIST fără nici o clauză listează toate
liniile din buffer.

Comenzi interactive
SQL*Plus dispune de comenzi ce permit comunicarea directă cu utilizatorul:
• comanda PAUSE permite afişarea unei linii vide sau unui text suspendând temporar
acŃiunea şi aşteptând un RETURN de la utilizator;
• comanda PROMPT trimite o linie goală sau un mesaj pe ecran;
• comanda ACCEPT permite citirea unei linii de pe ecran şi atribuirea valorii sale unei
variabile (utilizator) specificate (variabila poate să fie deja definită prin comanda
DEFINE).
ACCEPT variabila [NUMBER | CHAR | DATE]
[FORMAT format] [PROMPT text | NOPROMPT] [HIDE]
ObservaŃii:
• tipul implicit al variabilei este CHAR;
• textul de la opŃiunea PROMPT este tipărit înainte ca utilizatorul să dea valoarea efectivă;
• opŃiunea HIDE face ca valoarea dată de utilizator să fie mascată (de exemplu, o parolă);
• opŃiunea FORMAT indică modul de formatare;
• variabila de substituŃie, dacă este prezentă, nu trebuie prefixată de simbolul “&”.

Exemplu:
ACCEPT alfa PROMPT ’Numarul de exemplare:’
ACCEPT beta PROMPT ’Numele autorului:’
SELECT *
FROM carte
WHERE nrex = &alfa
AND autor = ’&beta’;

Variabilele de substituŃie (&nume)


Aceste variabile sunt utilizate pentru stocarea temporară a unor valori. Variabilele pot să
apară în comenzi SQL sau SQL*Plus. InterfaŃa cere utilizatorului să dea valori de fiecare dată când
întâlneşte o variabilă nedefinită. Dacă variabila este precedată de simbolurile “&&”, doar la prima
apelare se va solicita o valoare.
Exemplu:
SELECT nume, &&salariu
FROM salariat
ORDER BY &salariu;
Pentru variabilele de tip caracter sau de tip dată calendaristică este obligatorie folosirea
ghilimelelor. Variabilele de substituŃie pot să apară în condiŃia WHERE, în clauza ORDER BY, în
expresia unei coloane, în numele unui tabel, în locul unei întregi comenzi SELECT.
Exemplu:
SELECT &coloana
FROM &tabel
WHERE &conditie
ORDER BY &ordine;
Comanda SET VER[IFY] {ON | OFF} permite listarea (sau nu) textului unei comenzi SQL
sau PL/SQL, inainte si dupa ce SQL*Plus inlocuieste variabilele de substitutie cu valori efective.
SQL*Plus permite definirea variabilelor utilizator de tip CHAR prin:
DEFINE variabilă = valoare
Variabila rămâne definită până când fie se părăseşte SQL*Plus, fie se dă comanda
UNDEFINE pentru variabila respectivă.
Tipărirea tuturor variabilelor utilizator, a valorilor şi tipurilor acestora se obŃine prin forma
DEFINE.
Exemplu:
SQL> DEFINE autor1 = Zola
SQL> DEFINE autor2 = Blaga
SQL> SELECT titlu, nrex
2 FROM carte
3 WHERE autor = ’&autor1’
4 OR autor = ’&autor2’;

Setări în SQL*Plus
Pentru a preciza opŃiunile de lucru cu SQL*Plus se utilizează comanda SET. Setările SQL
standard se găsesc în fişierul login.sql, care poate fi modificat pentru a conŃine setări adiŃionale. Când
se termină sesiunea toate setările sunt pierdute.
Comanda SET are două forme sintactice:
• una din ele se foloseşte ca Help pentru utilizator;
• cealaltă se foloseşte pentru setarea variabilelor sistem.
O variabilă sistem este un câmp rezervat în care se reŃine o valoare de către sistemul Oracle,
valoare care indică o stare a sistemului. Pentru a afişa valorile tuturor variabilelor de mediu la un
moment dat se utilizeaza comanda SHOW ALL.
SET variabila_sistem valoare
Parametrul variabila_sistem poate lua oricare din valorile care apar la execuŃia comenzii
SHOW ALL.
În continuare sunt prezentate numai o parte a acestor setări (în special cele folosite la
formatarea rapoartelor) împreună cu valorile pe care le poate lua parametrul valoare.
• SET RECSEP {WR[APPED] | EA[CH] | OFF} – controlează tipărirea separatorilor de
înregistrări. Cele trei valori posibile au următoarele semnificaŃii:
- WRAPPED tipăreşte un separator după fiecare linie a unei înregistrări (chiar dacă
aceasta cuprinde mai multe linii);
- EACH face acelaşi lucru, dar numai la sfârşitul unei înregistrări;
- OFF anulează tipărirea unui separator.
• SET RECSEPCHAR {_ | c} – setează caracterul ce separă înregistrările;
• SET SPACE {1 | n} – setează numărul de spaŃii între coloane.
• SET WRA[P] {OFF | ON} – specifică modul de afişare a înregistrărilor (trunchiat sau
pe o linie).
• SET NULL text – specifică textul afişat în locul valorii NULL.
• SET HEADS[EP] {| | c | OFF | ON} – specifică caracterele ce separă numele
coloanelor de înregistrări.
• SET UND[ERLINE] {_ | c | OFF | ON} – specifică caracterul folosit pentru
sublinierea numelor coloanelor.
• SET NEWP[AGE] {1 | n | NONE} – setează numărul de linii vide lăsate la începutul
fiecărei pagini.
• SET TERM[OUT] {OFF | ON} – controlează afişarea output-ului generat de comenzi
executate dintr-un script.
• SET PAGES[IZE] {24 | n} – specifică numărul de linii afişate pe pagină (n implicit
este 24; se poate seta la valoarea 0 pentru a suprima afişarea numelor coloanelor, a titlului
unui raport).
• SET FEED[BACK] {6 | n | OFF | ON} – controlează afişarea numărului de
înregistrări furnizate ca rezultat de o comandă SELECT.
• SET ECHO {OFF | ON} – controlează afişarea comenzilor dintr-un script SQL lansat
cu comanda START, pe măsură ce acestea sunt executate.
Comanda SPOOL permite salvarea rezultatelor unei interogări într-un fişier indicat ca
parametru. Ea are următoarea sintaxă:

SPO[OL] [ file_name[. ext] | OFF | OUT]

SQL

Structured Query Language (SQL) este un limbaj universal care poate fi utilizat pentru a
defini, interoga, reactualiza şi gestiona baze de date relaŃionale. SQL este accesibil utilizatorilor
începători, dar în acelaşi timp poate oferi programatorilor experimentaŃi facilităŃi deosebite. SQL este
un limbaj non-procedural, adică se specifică ce informaŃie este solicitată, dar nu modul cum se obŃine
această informaŃie. SQL poate fi utilizat autonom sau prin inserarea comenzilor sale într-un limbaj de
programare. SQL a sistemului Oracle este o extensie a normei SQL89 şi o implementare a normei
SQL92.
În SQL se disting trei familii de comenzi:
• Comenzi pentru definirea datelor, care permit descrierea (definirea) structurii obiectelor
ce modelează sistemul studiat. Aceste comenzi definesc limbajul de definire a datelor
(LDD).
• Comenzi pentru prelucrarea datelor, ce permit consultarea, reactualizarea, suprimarea sau
inserarea datelor. Aceste comenzi definesc limbajul de prelucrare a datelor (LMD).
• Comenzi pentru controlul datelor, care permit asigurarea confidenŃialităŃii şi integrităŃii
datelor, salvarea informaŃiei, realizarea fizică a modificărilor în baza de date, rezolvarea
unor probleme de concurenŃă. Aceste comenzi definesc limbajul de control al datelor
(LCD).

Sistemul impune anumite restricŃii asupra identificatorilor.


• Numele unui obiect nu poate depăşi 30 de caractere, cu excepŃia numelui bazei de date
care este limitat la 8 caractere şi a numelui legăturii unei baze care poate ajunge la 128
caractere.
• Nu se face distincŃie între litere mici şi litere mari.
• Numele trebuie să înceapă printr-un caracter alfabetic şi nu poate fi un cuvânt cheie
rezervat; poate să conŃină literele mari şi mici ale alfabetului englez, cifrele 0 - 9 şi
caracterele $, _, #.
• Un utilizator nu trebuie să definească două obiecte cu acelaşi nume.
• În general este bine ca numele unui obiect să fie descriptiv şi fără prescurtări excesive.
Limbajul de definire a datelor- DDL

La nivel logic, o bază de date Oracle este alcătuită din scheme. O schemă este o mulŃime de
structuri logice de date, numite obiecte. Ea aparŃine unui utilizator al bazei de date şi poartă numele
său.
Specificarea bazelor de date şi a obiectelor care le compun se realizează prin intermediul
limbajului de definire a datelor (DDL). Definirea unui obiect presupune crearea, modificarea şi
suprimarea sa. Limbajul de definire a datelor cuprinde instrucŃiunile SQL care permit realizarea
acestor operaŃii (CREATE, ALTER, DROP). InstrucŃiunile DDL au efect imediat asupra bazei de date
şi înregistrează informaŃia în dicŃionarul datelor. De asemenea, LDD contine instructiunile RENAME,
TRUNCATE si COMMENT.
În cadrul unei scheme se pot defini obiecte de tip: tabel (table), vizualizare (view), vizualizare
materializată (materialized view), secvenŃă (sequence), index (index), sinonim (synonym), grupare
(cluster), procedură (procedure) şi funcŃie (function) stocată, declanşator (trigger), pachet stocat
(package), legătură a bazei de date (database link), dimensiune (dimension) etc.

Tipuri de date

Pentru memorarea datelor numerice, tipurile cele mai frecvent folosite sunt: NUMBER,
INTEGER, FLOAT, DECIMAL.
Pentru memorarea şirurilor de caractere, cele mai frecvent tipuri de date utilizate sunt:
CHAR, VARCHAR2 şi LONG.
Există restricŃii referitoare la folosirea tipului de date LONG.
• Într-un tabel poate să fie o singură coloană de tip LONG.
• Nu pot fi comparate două şiruri de caractere de tip LONG.
• O coloană de tip LONG nu poate fi parametru într-o procedură.
• O funcŃie nu poate întoarce ca rezultat o valoare de tip LONG.
• O coloană de tip LONG nu poate fi folosită în clauzele WHERE, ORDER BY, GROUP BY,
CONNECT.
• Operatorii sau funcŃiile Oracle nu pot fi folosiŃi în SQL pentru a modifica coloane de tip
LONG.
• O coloană de tip LONG nu poate fi indexată.
Alte tipuri de date scalare furnizate de SQL sunt NCHAR şi NVARCHAR2, folosite pentru
reprezentarea caracterelor limbilor naŃionale.
InformaŃii relative la timp sau dată calendaristică se obŃin utilizând tipul DATE. Pentru
fiecare dată de tip DATE sunt depuse: secolul, anul, luna, ziua, ora, minutul, secunda. Pentru o
coloană de tip DATE sistemul rezervă 7 bytes, indiferent dacă se memorează doar timpul, sau doar
data calendaristică.
Formatul implicit al datei se defineşte cu ajutorul parametrului de iniŃializare
NLS_DATE_FORMAT. În general, acest parametru este setat la forma DD-MON-YY. Dacă nu este
specificat timpul, timpul implicit este 12:00:00.

Valori valide pentru date


Câmp
calendaristice
De la -4712 la 9999 (cu excepŃia anului
YEAR
0).
MONTH De la 01 la 12.
De la 01 la 31 (limitat de valorile
câmpurilor MONTH şi YEAR,
DAY
corespunzător regulilor calendarului
curent).
HOUR De la 00 la 23.
MINUTE De la 00 la 59.
De la 00 la 59.9(n), unde „9(n)“ este
SECOND
precizia fracŃiunilor de secundă.

Modele de format
Un model de format este un literal caracter care descrie formatul valorilor de tip DATE sau
NUMBER stocate într-un şir de caractere. Atunci când se converteşte un şir de caractere într-o dată
calendaristică sau într-un număr, modelul de format indică sistemului cum să interpreteze şirul
respectiv. În instrucŃiunile SQL se poate folosi un model de format ca argument al funcŃiilor TO_CHAR
şi TO_DATE. În felul acesta se poate specifica formatul folosit de sistemul Oracle pentru a returna sau
a stoca o valoare în/din baza de date. Un model de format nu schimbă reprezentarea internă a valorii în
baza de date.
O parte dintre elementele cel mai frecvent întâlnite ale unui format de tip numeric sunt
sintetizate în tabelul următor.

Element Exemplu Descriere


Plasează o virgulă în poziŃia specificată. Într-un model de format
, (virgulă) 9,999 numeric pot fi precizate mai multe virgule, dar o virgulă nu poate
apărea în partea dreaptă a punctului zecimal.
Plasează un punct zecimal în poziŃia specificată. Într-un format
. (punct) 99.99
numeric, se poate specifica cel mult un punct zecimal.
$ $9999 Include semnul „$“ în faŃa unei valori.
0 0999; 9990 Plasează zerouri în faŃa sau la sfârşitul valorii.
Întoarce valoarea cu numărul specificat de cifre. Valoarea va avea
9 9999 un spaŃiu, respectiv un minus în faŃă dacă este pozitivă, respectiv
negativă.
Plasează în poziŃia specificată simbolul ISO pentru monede
C C999
(valoarea curentă a parametrului NLS_ISO_CURRENCY).
Plasează în poziŃia specificată caracterul zecimal, care este valoarea
curentă a parametrului NLS_NUMERIC_CHARACTER. Valoarea
D 99D99
implicită este punctul. Se poate specifica cel mult un caracter
zecimal într-un model de format numeric.
EEEE 9.9EEEE Returnează o valoare folosind notaŃia ştiinŃifică.
Întoarce în poziŃia specificată simbolul monedei locale (valoarea
L L999
curentă a parametrului NLS_CURRENCY).
Plasează semnul minus la sfârşitul valorilor negative şi un spaŃiu la
MI 9999MI sfârşitul celor pozitive. Acest element poate fi specificat numai pe
ultima poziŃie a modelului de format numeric.
S9999; Plasează semnele plus sau minus la începutul sau la sfârşitul valorii.
S
9999S Acest element poate apărea doar pe prima sau ultima poziŃie a
modelului de format numeric.
Modelele de format pentru date calendaristice pot fi utilizate în cadrul următoarelor funcŃii:
• TO_DATE, pentru a converti o valoare de tip caracter, care este într-un alt format decât
cel implicit, într-o valoare de tip DATE;
• TO_CHAR, pentru a converti o valoare de tip DATE, care este într-un alt format decât cel
implicit, într-un şir de caractere.
Un model de format pentru date calendaristice este alcătuit dintr-unul sau mai multe elemente
specifice. Scrierea cu litere mari sau mici a cuvintelor, abrevierilor sau a numeralelor romane este
respectată în elementul de format corespunzător. De exemplu, modelul de format „DAY“ produce
cuvinte cu majuscule, cum ar fi „FRIDAY“, iar „Day“ şi „day“ au ca rezultat „Friday“, respectiv
„friday“.
Într-un model de format pentru date calendaristice se pot preciza semne de punctuaŃie şi
literale caracter, incluse între ghilimele. Toate aceste caractere apar în valoarea returnată pe locul
specificat în modelul de format.
Element ExplicaŃie
AD sau A.D. Indicatorul AD (Anno Domini) cu sau fără puncte.
BC sau B.C. Indicatorul BC (Before Christ) cu sau fără puncte.
Numărul zilei din săptămână (1-7). Duminica este considerată prima zi a
D
săptămânii.
DAY Numele zilei completat cu spaŃii, până la lungimea de 9 caractere.
DD Numărul zilei din lună (1-31).
DDD Numărul zilei din an (1-366).
DY Numele zilei din săptămână, printr-o abreviere de 3 litere.
FF FracŃiunile de secundă.
HH sau HH12 Ora din zi (1-12).
HH24 Ora din zi (0-23).
MI Minutele din oră (0-59).
MM Luna din an (01-12).
MON Numele lunii, printr-o abreviere de 3 litere.
MONTH Numele lunii completat cu spaŃii, până la lungimea de 9 litere.
RM Luna în cifre romane (I-XII).
RR Anul cel mai apropiat de data curentă.
Acceptă intrarea atât cu 2, cât şi cu 4 cifre. Dacă anul de intrare se dă cu 2
RRRR
cifre, furnizează acelaşi lucru ca şi formatul RR.
SS Secundele din minut (0-59).
SSSSS Secundele trecute de la miezul noptii (0-86399).
TZH Ora regiunii.
TZM Minutul regiunii.
Y,YYY Anul scris cu virgulă după prima cifră.
YEAR sau SYEAR Anul în litere („S“ prefixează anii i.Hr. cu semnul minus).
YYYY sau SYYYY Anul cu 4 cifre.
YYY, YY sau Y Ultimele cifre ale anului.

Modificatorii FM şi FX pot fi utilizaŃi în modelele de format din cadrul funcŃiei TO_CHAR,


controlând completarea cu spaŃii şi verificarea exactă a formatelor. Un modificator poate să apară
într-un model de format de mai multe ori. În acest caz, efectele sale sunt active pentru porŃiunea din
model care începe la prima apariŃie şi apoi dezactivate pentru porŃiunea din model care urmează celei
de-a doua apariŃii ş.a.m.d.
Modificatorul FM (Fill Mode) suprimă completarea cu spaŃii în valoarea returnată de funcŃia
TO_CHAR, iar FX (Format eXact) impune corespondenŃa exactă dintre argumentul de tip caracter şi
modelul de format precizat pentru data calendaristică respectivă.
Valoarea null, reprezentând lipsa datelor, nu este egală sau diferită de nici o altă valoare,
inclusiv null.
Totuşi, există două situaŃii în care sistemul Oracle consideră două valori null ca fiind egale:
la evaluarea funcŃiei DECODE şi dacă valorile null apar în chei compuse. Două chei compuse care
conŃin valori null sunt considerate identice dacă toate componentele diferite de null sunt egale.

Pseudocoloane
O pseudocoloană se comportă ca şi o coloană a unui tabel, dar nu este stocată efectiv într-un
tabel. Se pot face interogări asupra pseudocoloanelor, dar nu se pot insera, actualiza sau şterge
valorile acestora.
• LEVEL returnează nivelul liniilor rezultat ale unei cereri ierarhice.
• CURRVAL şi NEXTVAL sunt pseudocoloane utile în lucrul cu secvenŃe şi sunt tratate în
secŃiunea corespunzătoare acestora.
• ROWID returnează adresa unei linii din baza de date, furnizând modul cel mai rapid de a
accesa linia respectivă. În sistemul Oracle, valorile acestei pseudocoloane conŃin
următoarele informaŃii necesare pentru a localiza o linie: numărul obiectului, blocul de
date, fişierul de date, linia în cadrul blocului de date. Valorile pseudocoloanei ROWID
sunt de tipul ROWID sau UROWID.
• ROWNUM returnează numărul de ordine al liniilor rezultate în urma execuŃiei unei cereri.
Pseudocoloana poate fi utilizată pentru a limita numărul de linii returnate. Dacă este
folosită clauza ORDER BY într-o subcerere, iar condiŃia în care apare ROWNUM este
plasată în cererea de nivel superior, atunci condiŃia va fi aplicată după ordonarea liniilor.
Exemplu:
Să se afişeze informaŃii despre operele de artă având cele mai mici 10 coduri.
SELECT *
FROM (SELECT * FROM opera ORDER BY cod_opera)
WHERE ROWNUM < 11;

Tabele

Crearea unui tabel


Crearea unui tabel constă din generarea structurii sale, adică atribuirea unui nume tabelului şi
definirea caracteristicelor sale (se definesc coloanele, se definesc constrângerile de integritate, se
specifică parametrii de stocare etc.).

În Oracle9i tabelele pot fi create în orice moment, chiar şi în timpul utilizării bazei. Structura
unui tabel poate fi modificată online. Nu este necesar să se specifice dimensiunea acestuia. Totuşi,
din considerente administrative, este important să se cunoască estimativ cât spaŃiu va utiliza tabelul.
Comanda CREATE TABLE permite crearea unui tabel relaŃional sau a unui tabel obiect.
Tabelul relaŃional reprezintă structura fundamentală pentru stocarea datelor utilizatorului. Un tabel
obiect utilizează un tip obiect pentru definiŃia unei singure coloane şi este folosit pentru a stoca
instanŃele unui obiect particular.
Pentru a crea un tabel, utilizatorul trebuie să aibă acest privilegiu şi să dispună de spaŃiul de
memorie în care să creeze obiectul. La nivelul schemei sale, un utilizator are toate privilegiile.
CREATE TABLE [<nume_schema>.] <nume_tabel> (
<nume_coloana_1> <tip_date> [DEFAULT <expresie>],

<nume_coloana_n> <tip_date> [DEFAULT <expresie>]);

Comanda poate conŃine opŃional clauza TABLESPACE, care specifică spaŃiul tabel în care va
fi stocat tabelul. De asemenea, poate conŃine opŃional clauza STORAGE care este folosită pentru
setarea parametrilor de stocare prin intermediul cărora se specifică mărimea şi modul de alocare a
extinderilor segmentului tabel. La crearea unui tabel nu este nevoie să se specifice dimensiunea
maximă a acestuia, ea fiind determinată până la urmă de marimea spaŃiului alocat spaŃiului tabel în
care este creat tabelul.
Structura unui tabel poate fi creată în următoarele patru moduri:
• fără a indica cheile;
• indicând cheile la nivel de coloană;
• indicând cheile la nivel de tabel;
• prin copiere din alt tabel.
1. Crearea structurii unui tabel fără a indica cheile:
CREATE TABLE carte
(codel CHAR(5),
titlu VARCHAR2(30),
autor VARCHAR2(30),
pret NUMBER(8,2),
nrex NUMBER(3),
coded CHAR(5));

2. Crearea structurii unui tabel indicând cheile la nivel coloană:


CREATE TABLE carte
(codel CHAR(5) PRIMARY KEY,
titlu VARCHAR2(30),
autor VARCHAR2(30),
pret NUMBER(8,2),
nrex NUMBER(3),
coded CHAR(5) NOT NULL
REFERENCES domeniu(coded));
Constrângerea de cheie primară sau externă ce presupune?
CREATE TABLE carte
(codel CHAR(5) PRIMARY KEY,
titlu VARCHAR2(30),
autor VARCHAR2(30),
pret NUMBER(8,2),
nrex NUMBER(3),
coded CHAR(5) NOT NULL
REFERENCES domeniu(coded)
ON DELETE CASCADE);
OpŃiunea ON DELETE CASCADE specifică că suprimarea oricărui domeniu de carte din
tabelul domeniu este autorizată şi implică suprimarea automată a tuturor cărŃilor din domeniul
respectiv care se găsesc în tabelul carte.

3. Crearea structurii unui tabel indicând cheile la nivel de tabel:


CREATE TABLE carte
(codel CHAR(5),
titlu VARCHAR2(30),
autor VARCHAR2(30),
pret NUMBER(8,2),
nrex NUMBER(3),
coded CHAR(5) NOT NULL,
PRIMARY KEY (codel),
FOREIGN KEY (coded)
REFERENCES domeniu (coded));
Dacă cheia primară are mai mult de o coloană atunci cheile trebuie indicate la nivel de tabel.
CREATE TABLE imprumuta
(codel CHAR(5),
codec CHAR(5),
dataim DATE DEFAULT SYSDATE,
datares DATE,
dataef DATE,
PRIMARY KEY (codel, codec, dataim),
FOREIGN KEY (codel)
REFERENCES carte(codel),
FOREIGN KEY (codec)
REFERENCES cititor(codec));

4. Crearea structurii unui tabel prin copiere din alt tabel:


CREATE TABLE carte_info
AS SELECT codel, titlu, autor
FROM carte
WHERE coded = ’I’;
Constrângerile din primul tabel nu se păstrează şi pentru al doilea tabel. Comanda creează un
tabel, dar şi inserează date în tabel.

Constrângeri
Constrângerea este un mecanism care asigură că valorile unei coloane sau a unei mulŃimi de
coloane satisfac o condiŃie declarată. Unei constrâgeri i se poate da un nume unic. Dacă nu se
specifică un nume explicit atunci sistemul automat îi atribuie un nume de forma SYS_Cn, unde n
reprezintă numărul constrângerii. Constrângerile pot fi şterse, pot fi adăugate, pot fi activate sau
dezactivate, dar nu pot fi modificate.
Exemplu:
Să se definească o constrângere la nivel de coloană prin care să se specifice cheia primară şi
cheia externă.
CREATE TABLE carte
(codel CHAR(5)
CONSTRAINT cp_carte PRIMARY KEY,
titlu VARCHAR2(30),…
coded CHAR(5)
CONSTRAINT nn_coded NOT NULL
CONSTRAINT ce_coded
REFERENCES domeniu(coded));
Exemplu:
Să se definească o constrângere la nivel de tabel prin care să se specifice cheia primară şi cheia
externă.
CREATE TABLE carte
(codel CHAR(5),
titlu VARCHAR2(30),…
coded CHAR(5) NOT NULL,
CONSTRAINT cp_carte PRIMARY KEY (codel),
CONSTRAINT ce_coded
FOREIGN KEY (coded)
REFERENCES domeniu(coded));
ObservaŃii
• Liniile ce nu respectă constângerea sunt depuse automat într-un tabel special.
• Constrângerile previn ştergerea unui tabel dacă există dependenŃe.
• Constrângerile pot fi create o dată cu tabelul sau după ce acesta a fost creat.
• Constrângerile pot fi activate sau dezactivate în funcŃie de necesităŃi.

Constrângeri declarative: constrângeri de domeniu, constrângerea de integritate a entităŃii,


constrângerea de integritate referenŃială.

Constrângerile de domeniu definesc valori luate de un atribut (DEFAULT, CHECK,


UNIQUE, NOT NULL).
• constrângerea (coloană) DEFAULT ;
• constrângerea (coloană sau tabel) CHECK ; constrângerea CHECK la nivel de tabel poate
compara coloane între ele, poate face referinŃă la una sau mai multe coloane, dar nu poate
conŃine subcereri. Constrângerea la nivel de coloană nu poate referi alte coloane ale aceluiaşi
tabel.
CREATE TABLE carte
(codel CHAR(5),…
pret NUMBER(8,2)
CONSTRAINT alfa
CHECK (pret < nrex),…);
La execuŃia acestei comenzi apare mesajul: ORA – 02438: Column check constraint cannot
reference other columns.
Dacă dupa NUMBER(8, 2) se adaugă o virgulă, atunci constrângerea va fi la nivel de tabel,
iar în aceste caz este permisă referirea altei coloane.
• constrângerea (coloană sau tabel) UNIQUE ;
• constrângerea declarativă NOT NULL poate fi doar la nivel coloană.
Constrângerea de integritate a entităŃii precizează cheia primară a unui tabel. Când se
creează cheia primară se generează automat un index unic. Valorile cheii primare sunt distincte şi
diferite de valoarea null.
Constrângerea de integritate referenŃială asigură coerenŃa între cheile primare şi cheile
externe corespunzătoare. Când este definită o cheie externă sistemul Oracle verifică:
• dacă a fost definită o cheie primară pentru tabelul referit de cheia externă;
• dacă numărul coloanelor ce compun cheia externă corespunde numărului de coloane a
cheii primare;
• dacă tipul şi lungimea fiecărei coloane a cheii externe corespunde cu tipul şi lungimea
fiecărei coloane a cheii primare.
Această constrângere poate fi definită la nivel de coloană sau tabel şi asigură coerenŃa între
cheile primare şi cheile externe corespunzătoare. Constrângerea FOREIGN KEY desemnează o coloană
sau o combinaŃie de coloane drept cheie externă şi stabileşte relaŃia cu o cheie primară sau o cheie
unică din acelaşi tabel sau din altul. O cheie externă compusă poate fi definită doar la nivel de tabel.
Cheia externă se defineşte în tabelul „copil“, iar tabelul care conŃine coloana referită reprezintă
tabelul „părinte“. Valoarea unei chei externe trebuie să fie egală cu o valoare existentă în tabelul
„părinte“ sau să fie null. Cheile externe se bazează pe valorile datelor şi sunt pointer-i logici.
Cheile externe se definesc folosind următoarele cuvinte cheie:
• FOREIGN KEY este utilizat într-o constrângere la nivel de tabel pentru a defini coloana din
tabelul „copil“;
• REFERENCES identifică tabelul „părinte“ şi coloana corespunzătoare din acest tabel;
• ON DELETE CASCADE determină ca, odată cu ştergerea unei linii din tabelul „părinte“, să
fie şterse şi liniile dependente din tabelul „copil“;
• ON DELETE SET NULL determină modificarea automată a valorilor cheii externe la
valoarea null, atunci când se şterge valoarea „părinte“.
DefiniŃiile şi numele constrângerilor definite se pot fi consulta prin interogarea vizualizărilor
USER_CONSTRAINTS şi ALL_CONSTRAINTS din dicŃionarul datelor.
În versiunea Oracle8 există posibilitatea ca o constrângere să fie amânată (DEFERRABLE).
În acest caz, mai multe comenzi SQL pot fi executate fără a se verifica restricŃia, aceasta fiind
verificată numai la sfârşitul tranzacŃiei, atunci când este executată comanda COMMIT. Dacă vreuna
din comenzile tranzacŃiei încalcă restricŃia, atunci întreaga tranzacŃie este derulată înapoi şi este
returnată o eroare. OpŃiunea implicită este NOT DEFERRABLE.

Modificarea structurii unui tabel


Comanda care realizează modificarea structurii tabelului (la nivel de coloană sau la nivel de
tabel), dar nu modificarea conŃinutului acestuia, este ALTER TABLE.
ALTER TABLE realizează modificarea structurii unui tabel nepartiŃionat sau partiŃionat, a unei
partiŃii sau subpartiŃii dintr-un tabel. Pentru tabele obiect sau tabele relaŃionale conŃinând coloane
obiect, instrucŃiunea poate fi utilizată pentru a converti tabelul la ultima definiŃie a tipului referit, după
ce acesta a fost modificat. Comanda nu schimbă conŃinutul tabelului.
Comanda ALTER TABLE permite:
• adăugarea (ADD) de coloane, chei (primare sau externe), constrângeri într-un tabel
existent;
• modificarea (MODIFY) coloanelor unui tabel;
• specificarea unei valori implicite pentru o coloană existentă;
• activarea şi dezactivarea (ENABLE, DISABLE) unor constrângeri;
• suprimarea unei coloane;
• suprimarea (DROP) cheii primare, a cheii externe sau a unor constrângeri.
Comanda ALTER TABLE are următoarea sintaxă simplificată:
ALTER TABLE [<nume_schema>.] <nume_tabel>
[ADD (<nume_coloana> <tip_date>, <constrângere>) |
MODIFY (<nume_coloana_1>,…, <nume_coloana_n>) |
DROP <clauza_drop>,]
[ENABLE | DISABLE <clause>];
1. Pentru a adăuga o coloană, o cheie primară, o cheie externă sau o constrângere unui tabel
este folosită următoarea formă:
ALTER TABLE nume_tabel
ADD (nume_coloana constrangere,…
nume_coloana constrangere);
2. Pentru a modifica una sau mai multe coloane existente:
ALTER TABLE nume_tabel
MODIFY (nume_coloana constrangere,…
nume_coloana constrangere);
3. Pentru a suprima cheia primară sau alte constrângeri sunt utilizate formele:
ALTER TABLE nume_tabel
DROP PRIMARY KEY;
ALTER TABLE nume_tabel
DROP CONSTRAINT nume_constrangere;
4. Pentru a activa (ENABLE) sau dezactiva (DISABLE) constrângeri:
ALTER TABLE nume_tabel
ENABLE nume_constrangere;
ObservaŃii
• Nu se poate specifica poziŃia unei coloane noi în structura tabelului. O coloană nouă devine
automat ultima în cadrul structurii tabelului.
• Modificarea unei coloane presupune schimbarea tipului de date, a dimensiunii sau a valorii
implicite a acesteia. O schimbare a valorii implicite afectează numai inserările care succed
modificării.
• Dimensiunea unei coloane numerice sau de tip caracter poate fi mărită, dar nu poate fi micşorată
decât dacă acea coloană conŃine numai valori null sau dacă tabelul nu conŃine nici o linie.
• Tipul de date al unei coloane poate fi modificat doar dacă valorile coloanei respective sunt null.
• Definirea cheii primare sau a cheii externe după crearea tabelului.
CREATE TABLE carte
(CODEL char(5),
…);
ALTER TABLE carte
ADD CONSTRAINT cheie_prim PRIMARY KEY (codel);
• Suprimarea cheii primare.
ALTER TABLE carte
DROP PRIMARY KEY;
• Dacă există o CE care referă o CP şi dacă se încearcă ştergerea cheii primare, această ştergere nu
se poate realiza (tabelele sunt legate prin declaraŃia de cheie externă). Ştergerea este totuşi
permisă dacă în comanda ALTER apare opŃiunea CASCADE, care determină şi ştergerea cheilor
externe ce referă cheia primară.
ALTER TABLE domeniu
DROP PRIMARY KEY CASCADE;
• Suprimarea cheii externe.
ALTER TABLE carte
ADD CONSTRAINT beta
FOREIGN KEY (coded) REFERENCES domeniu;
ALTER TABLE carte
DROP CONSTRAINT beta;
• Schimbarea cheii primare. Este destul de complicat procesul schimbării cheii primare fără a
afecta modul de proiectare a bazei de date. Schimbarea se face în două etape: se şterge cheia
primară şi apoi se recreează.
ALTER TABLE carte
ADD (PRIMARY KEY(codel));
ALTER TABLE carte
DROP PRIMARY KEY;
ALTER TABLE carte
ADD PRIMARY KEY(titlu, autor));
• Adăugarea unei coloane. Această coloană iniŃial va fi null (pentru toate liniile). Nu se poate
specifica unde să apară coloana, ea devenind ultima coloană a tabelului.
ALTER TABLE carte
ADD (rezumat LONG);
• Pentru suprimarea unei coloane a tabelului este utilizată următoarea formă:
ALTER TABLE nume_tabel
DROP (nume_coloană) [CASCADE CONSTRAINTS];
OpŃiunea DROP a comenzii ALTER TABLE a fost introdusă în versiunea Oracle8i. Coloana
care este suprimată poate să conŃină date. O comandă ALTER TABLE permite ştergerea unei singure
coloane. După o astfel de operaŃie, în tabel trebuie să rămână cel puŃin o coloană. Odată suprimată, o
coloană nu poate fi recuperată.
Clauza CASCADE CONSTRAINTS permite suprimarea tuturor constrângerilor de integritate
referenŃială care se referă la cheile primare sau unice definite asupra coloanelor şterse. De asemenea,
prin această clauză se suprimă şi constrângerile multicoloană definite pe baza coloanelor şterse.
• Constrângerile pot fi adăugate (ADD CONSTRAINT), şterse (DROP CONSTRAINT), activate
(ENABLE) sau dezactivate (DISABLE), dar nu pot fi modificate.
ALTER TABLE cititor
ADD CONSTRAINT cp_cititor
PRIMARY KEY (codec)
DISABLE;
ALTER TABLE cititor
ENABLE CONSTRAINT cp_cititor;
Prima comandă adaugă o constrângere, dar nu-i dă viaŃă. Constrângerea există, dar server-ul
nu o verifică. Când se activează o constrângere, sistemul controlează toate liniile tabelului şi
inserează într-un tabel special toate liniile care nu verifică constrângerea. Tabelul are următoarea
structură:
(ROW_ID ROWID
(OWNER VARCHAR2(30),
(TABLE_NAME VARCHAR2(30),
(CONSTRAINT VARCHAR2(30))
• Din punct de vedere fizic, comanda ALTER TABLE permite schimbarea parametrilor PCTFREE
şi PCTUSED şi a parametrilor din clauza STORAGE.
• Comanda permite alocarea (ALLOCATE EXTENT) şi dealocarea (DEALLOCATE UNUSED)
manuală a spaŃiului utilizat de către un tabel. Alocarea se face prin adăugarea de noi extinderi,
iar dealocarea reprezintă eliberarea spaŃiului nefolosit de tabel (care nu a fost folosit niciodată
sau a devenit liber datorită ştergerii unor linii).
• Alte opŃiuni ale comenzii ALTER TABLE, care au apărut începând cu versiunea Oracle8i, sunt SET
UNUSED şi DROP UNUSED COLUMNS:
ALTER TABLE nume_tabel
SET UNUSED [ ( ] nume_coloană [ ) ];
ALTER TABLE nume_tabel
DROP UNUSED COLUMNS;
OpŃiunea SET UNUSED permite marcarea uneia sau mai multor coloane ca fiind nefolosite, cu
scopul de a fi şterse atunci când necesităŃile sistemului impun acest lucru. Coloanele nefolosite sunt
tratate ca şi cum ar fi fost suprimate, deşi datele acestora rămân în liniile tabelului. După ce o coloană a
fost marcată UNUSED, utilizatorul nu mai are acces la aceasta prin intermediul cererilor. În plus,
numele şi tipurile de date ale coloanelor nefolosite nu vor fi afişate cu comanda DESCRIBE din
SQL*Plus. Utilizatorul poate să adauge tabelului o nouă coloană având acelaşi nume cu cel al unei
coloane nefolosite.
DROP UNUSED COLUMNS şterge din tabel toate coloanele marcate ca fiind nefolosite. Acest
lucru se poate utiliza pentru eliberarea spaŃiului de pe disc corespunzător coloanelor nefolosite din
tabel. Dacă tabelul nu conŃine nici o coloană nefolosită, instrucŃiunea nu întoarce o eroare şi nu are nici
un efect.
Atunci când se elimină o coloană dintr-un tabel folosind opŃiunea DROP a comenzii ALTER
TABLE, vor fi suprimate şi coloanele din tabel care sunt marcate cu opŃiunea SET UNUSED.

Suprimarea unui tabel


Pentru ştergerea unui tabel este utilizată comanda DROP TABLE:
DROP TABLE [nume_schema.]nume_tabel
[CASCADE CONSTRAINTS];
Clauza CASCADE CONSTRAINTS permite suprimarea tuturor constrângerilor de integritate
referenŃială corespunzătoare cheilor primare şi unice din tabelul supus ştergerii. Dacă se omite această
clauză şi există constrângeri de integritate referenŃială, sistemul returnează o eroare şi nu suprimă
tabelul.
Suprimarea unui tabel presupune:
0suprimarea definiŃiei sale în dicŃionarul datelor;
0suprimarea indecşilor asociaŃi;
0suprimarea privilegiilor conferite în legătură cu tabelul;
0recuperarea spaŃiului ocupat de tabel;
0permanentizarea tranzactiilor in asteptare;
0invalidarea (dar nu suprimarea) funcŃiilor, procedurilor, vizualizărilor, secventelor,
sinonimelor referitoare la tabel.
Odată executată, instrucŃiunea DROP TABLE este ireversibilă. Ca şi în cazul celorlalte
instrucŃiuni ale limbajului de definire a datelor, această comandă nu poate fi anulată (ROLLBACK).
Pentru ştergerea întregului conŃinut al unui tabel şi eliberarea spaŃiului de memorie ocupat de
acesta, sistemul Oracle oferă instrucŃiunea:
TRUNCATE TABLE nume_tabel;
Fiind o instrucŃiune LDD, aceasta nu poate fi anulată ulterior (printr-o operaŃie ROLLBACK).
Ea reprezintă o alternativă a comenzii DELETE din limbajul de prelucrare a datelor. De remarcat că
instrucŃiunea DELETE nu eliberează spaŃiul de memorie. Comanda TRUNCATE este mai rapidă
deoarece nu generează informaŃie ROLLBACK şi nu activează declanşatorii asociaŃi operaŃiei de
ştergere. Dacă tabelul este „părintele“ unei constrângeri de integritate referenŃială, el nu poate fi
trunchiat. Pentru a putea fi aplicată instrucŃiunea TRUNCATE, constrângerea trebuie să fie mai întâi
dezactivată.
In DD, informaŃiile despre tabele se găsesc în vizualizarea USER_TABLES. Dintre cele mai
importante coloane ale acesteia, se remarca:

TABLE_NAME Numele tabelului


TABLESPACE_NAME SpaŃiul tabel în care se află tabelul
CLUSTER_NAME Numele cluster-ului din care face parte tabelul
PCT_FREE Procentul de spaŃiu păstrat liber în interiorul fiecărui bloc
PCT_USED Procentul de spaŃiu ce poate fi utilizat în fiecare bloc
INI_TRANS Numărul iniŃial de tranzacŃii concurente în interiorul unui
bloc
NITIAL_EXTENT Dimensiunea spaŃiului alocat pentru prima extensie
NEXT_EXTENT Dimensiunea spaŃiului alocat pentru următoarea extensie
MIN_EXTENTS Numărul minim de extensii ce se alocă la crearea unui tabel
MAX_EXTENTS Numărul maxim de extensii ce se alocă la crearea unui tabel
PCT_INCREASE Procentul cu care creşte dimensiunea unei extensii
BACKED_UP Y sau N, după cum tabelului i-a fost făcută o copie de
siguranŃă de la ultima modificare
NUM_ROWS Numărul de înregistrări din tabel
BLOCKS Numărul de blocuri utilizate de tabel
EMPTY_BLOCKS Numărul de blocuri ce nu conŃin date
AVG_SPACE SpaŃiul mediu liber din tabel
AVG_ROW_LEN Lungimea medie, în octeŃi, a unei linii
TABLE_LOCK ENABLED (activat) sau DISABLED (dezactivat): este
activată sau nu blocarea tabelului
PARTITIONED YES sau NO, indică dacă tabelul este partiŃionat (sau nu)
TEMPORARY Y sau N, indică dacă tabelul este temporar (sau nu)
NESTED YES sau NO, indică dacă tabelul este imbricat (sau nu)
Exemplu:
DESCRIBE USER_TABLES
SELECT TABLE_NAME, NUM_ROWS, NESTED
FROM USER_TABLES;
Exemplu:
SELECT 'DROP TABLE' || OBJECT_NAME || ';'
FROM USER_OBJECTS
WHERE OBJECT_TYPE = 'TABLE';

Indecşi

Un index este un obiect al schemei unei baze de date care:


• creşte viteza de execuŃie a cererilor;
• garantează că o coloană conŃine valori unice.
Server-ul Oracle utilizează identificatorul ROWID pentru regăsirea liniilor în structura fizică
a bazei de date. Indexul, din punct de vedere logic, este compus dintr-o valoare cheie şi din
identificatorul adresă ROWID.
Cheia indexului poate fi coloana unui tabel sau concatenarea mai multor coloane (numărul
maxim de coloane care pot defini cheia indexului este 32). Coloanele care apar în cheia indexului
trebuie declarate NOT NULL în tabel.
Indecşii sunt utilizaŃi şi întreŃinuŃi automat de către server-ul Oracle. Odată creat indexul, el
nu necesită o acŃiune directă din partea utilizatorului.
Indecşii pot fi creaŃi în două moduri:
• automat, de server-ul Oracle (PRIMARY KEY, UNIQUE KEY);
• manual, de către utilizator (CREATE INDEX, CREATE TABLE).
Server-ul Oracle creează automat un index unic atunci când se defineşte o constrângere
PRIMARY KEY sau UNIQUE asupra unei coloane sau unui grup de coloane. Numele indexului va fi
acelaşi cu numele constrângerii.
Indecşii, fiind obiecte ale schemei bazei, beneficiază de procesul de definire a unui obiect.
Crearea unui index (care nu este obligatoriu unic) pe una sau mai multe coloane ale unui tabel
se face prin comanda:
CREATE [UNIQUE] INDEX <nume_index>
ON [<nume_schema>.] <nume_tabel>
(<nume_col> [ASC | DESC], <nume_col> [ASC | DESC], …)
];
Exemplu:
1) Să se creeze un index descrescător relativ la coloana adresa din tabelul cititor.
CREATE INDEX cititor_idx
ON cititor (adresa DESC);
2) Să se afişeze informaŃiile referitoare la indexul cititor_idx.
SELECT TABLE_NAME, UNIQUENESS, MIN_EXTENTS
FROM USER_INDEXES
WHERE INDEX_NAME='cititor_idx';
3) Să se creeze un index explicit, referitor la cheia primara a unui tabel.
CREATE TABLE exemplu
(cod_id NUMBER(6)
PRIMARY KEY USING INDEX
(CREATE INDEX cod_id_idx ON exemplu (cod_id)),
nume VARCHAR2(20));
Mai mulŃi indecşi asupra unui tabel nu implică întotdeuna interogări mai rapide. Fiecare
operaŃie LMD care este permanentizată asupra unui tabel cu indecşi asociaŃi presupune actualizarea
indecşilor respectivi.
Prin urmare, este recomandată crearea de indecşi numai în anumite situaŃii:
• coloana conŃine o varietate mare de valori;
• coloana conŃine un număr mare de valori null;
• una sau mai multe coloane sunt utilizate frecvent împreună într-o clauză WHERE sau într-o
condiŃie de join;
• tabelul este mare şi este de aşteptat ca majoritatea interogărilor asupra acestuia să
regăsească mai puŃin de 2-4% din linii.
Crearea unui index nu este recomandată în următoarele cazuri:
• tabelul este mic;
• coloanele nu sunt utilizate des în cadrul unei condiŃii dintr-o cerere;
• majoritatea interogărilor regăsesc mai mult de 2-4% din liniile tabelului;
• tabelul este actualizat frecvent;
• coloanele indexate sunt referite în expresii.

In concluzie, ce tabele sau ce coloane trebuie (sau nu) indexate?


• indexaŃi tabelele pentru care interogările selectează un număr redus de rânduri (sub 5%);
• indexaŃi tabelele care sunt interogate folosind clauze SQL simple;
• nu indexaŃi tabelele ce conŃin puŃine înregistrări (accesul secvenŃial este mai simplu);
• nu indexaŃi tabelele care sunt frecvent actualizate, deoarece ştergerile, inserările şi
modificările sunt îngreunate de indecşi;
• indexaŃi coloanele folosite frecvent în clauza WHERE sau în clauza ORDER BY;
• nu indexaŃi coloanele ce conŃin date asemănătoare (puŃine valori distincte);
Exemplu:
CREATE INDEX upper_nume_idx ON artist (UPPER(nume));
Indexul creat prin instrucŃiunea precedentă facilitează prelucrarea unor interogări precum:
SELECT * FROM artist
WHERE UPPER(nume) = 'GRIGORESCU';
Pentru a asigura că server-ul Oracle utilizează indexul şi nu efectuează o căutare asupra
întregului tabel, valoarea funcŃiei corespunzătoare expresiei indexate trebuie să nu fie null în
interogările ulterioare creării indexului. Următoarea instrucŃiune garantează utilizarea indexului dar, în
absenŃa clauzei WHERE, server-ul Oracle ar putea cerceta întreg tabelul.
SELECT * FROM artist
WHERE UPPER(nume) IS NOT NULL
ORDER BY UPPER(nume);
Exemplu:
Să se creeze tabelul artist, specificându-se indexul asociat cheii primare.
CREATE TABLE artist (
cod_artist NUMBER
PRIMARY KEY USING INDEX
(CREATE INDEX artist_cod_idx
ON artist(cod_artist)),
nume VARCHAR2(30) NOT NULL,
prenume VARCHAR2(30), …);
Ştergerea unui index se face prin comanda:
DROP INDEX nume_index [ON [nume_schema.] nume_tabel]
Pentru a suprima indexul trebuie ca acesta să se găsească în schema personală sau să ai
privilegiul de sistem DROP ANY INDEX.
Pentru a reconstrui un index se pot folosi două metode:
• se şterge indexul (DROP INDEX) şi se recreează (CREATE INDEX);
• se utilizează comanda ALTER INDEX cu opŃiunea REBUILD.
Validarea unui index, adică verificarea integrităŃii indexului specificat pentru un tabel, se face
prin comanda:
VALIDATE INDEX nume_index [ON nume_tabel] [WITH LIST]
InformaŃii referitoare la indecşi şi la coloanele care îi definesc pot fi regăsite în vizualizările
USER_INDEXES, respectiv USER_IND_COLUMNS din dicŃionarul datelor. Dintre coloanele tabelului
USER_INDEXES se remarcă:

INDEX_NAME Numele indexului


INDEX_TYPE Tipul indexului (NORMAL, LOB, CLUSTER etc.)
TABLE_OWNER Proprietarul tabelului indexat
TABLE_NAME Numele tabelului indexat
TABEL_TYPE Tipul tabelului indexat (TABLE, CLUSTER etc.)
UNIQUENESS Starea de unicitate (UNIQUE, NONUNIQUE)
TABLESPACE_NAME SpaŃiul tabel în care este stocat indexul
INITIAL_EXTENT SpaŃiul alocat pentru prima extensie
NEXT_EXTENT SpaŃiul alocat pentru următoarea extensie
MIN_EXTENTS Numărul minim de extensii alocate
MAX_EXTENTS Numărul maxim de extensii
PCT_INCREASE Procentul cu care cresc extensiile
BLEVEL Nivelul din B-arbore. Acesta arată adâncimea indexului de
la ramuri la frunze
LEAF_BLOCKS Numărul de blocuri frunză din index
DISTINCT_KEYS Numărul de chei distincte în index
STATUS Starea indexului (VALID, INVALID, DIRECT_LOAD)
NUM_ROWS Numărul de linii utilizate. Acesta nu trebuie să includă
valorile NULL din tabelul de bază
PARTITIONED Determină dacă indexul este partiŃionat (YES sau NO)
GENERATED Determină dacă sistemul a generat numele indexului (Y)
sau utilizatorul (N)

Exemplu:
Să se obŃină informaŃii referitoare la indecşii tabelului carte.
SELECT a.index_name, a.column_name,
a.column_position poz, b.uniqueness
FROM user_indexes b, user_ind_columns a
WHERE a.index_name = b.index_name
AND a.table_name = ’carte’;

SecvenŃe

O secvenŃă este un obiect în baza de date care serveşte pentru a genera întregi unici în
sistemele multi-utilizator, evitând apariŃia conflictelor şi a blocării.
SecvenŃele sunt memorate şi generate indiferent de tabele  aceeaşi secvenŃă poate fi
utilizată pentru mai multe tabele. O secvenŃă poate fi creată de un utilizator şi poate fi partajată de
mai mulŃi utilizatori.
Crearea unei secvenŃe se face cu ajutorul comenzii:
CREATE SEQUENCE [<nume_schema>.]<nume_secventa>
[INCREMENT BY n] [START WITH m]
[{MAXVALUE n | NOMAXVALUE}] [{MINVALUE n | NOMINVALUE}]
[{CACHE k | NOCACHE}]
CACHE k | NOCACHE specifică numărul de valori alocate de server-ul Oracle pe care le va
păstra în memoria cache pentru a oferi utilizatorilor un acces rapid (implicit sunt alocate 20 de
valori);
O secvenŃă este referită într-o comandă SQL cu ajutorul pseudo-coloanelor:
• NEXTVAL – referă valoarea următoare a secvenŃei;
• CURRVAL – referă valoarea curentă a secvenŃei.
NEXTVAL şi CURRVAL pot fi folosite în:
• clauza VALUES a unei comenzi INSERT;
• clauza SET a unei comenzi UPDATE;
• lista SELECT a unei subcereri dintr-o comanda INSERT;
• lista unei comenzi SELECT.
NEXTVAL şi CURRVAL nu pot fi folosite în:
• subinterogare in SELECT, DELETE sau UPDATE;
• interogarea unei vizualizări;
• comandă SELECT cu operatorul DISTINCT;
• comandă SELECT cu clauza GROUP BY, HAVING sau ORDER BY;
• clauza WHERE a unei comenzi SELECT;
• condiŃia unei constrângeri CHECK;
• valoarea DEFAULT a unei coloane într-o comandă CREATE TABLE sau ALTER TABLE;
• comandă SELECT care este combinată cu altă comandă SELECT printr-un operator mulŃime
(UNION, INTERSECT, MINUS).
Din dicŃionarul datelor pot fi obŃinute informaŃii despre secvenŃe folosind vizualizarea
USER_SEQUENCES.
1) Să se creeze o secvenŃă domeniuseq care să fie utilizată pentru a insera noi domenii în tabelul
domeniu şi să se insereze un nou domeniu.
2) Să se afişeze informaŃiile referitoare la secvenŃa domeniuseq.
CREATE SEQUENCE domeniuseq
START WITH 1
INCREMENT BY 1;
INSERT INTO domeniu
VALUES (domeniuseq.NEXTVAL,’Informatica’);
SELECT INCREMENT, START, MAXVALUE, MINVALUE,
FROM USER_SEQUENCES
WHERE SEQUENCE_NAME = 'domeniuseq';
Modificarea unei secvenŃe se face prin comanda ALTER SEQUENCE. Sintaxa comenzii este
similară instrucŃiunii CREATE SEQUENCE , dar:
• noua valoare maximă pentru MAXVALUE nu poate fi mai mică decât valoarea curentă;
• opŃiunea START WITH nu poate fi modificată de comandă.
Suprimarea unei secvenŃe se face cu ajutorul comenzii:
DROP SEQUENCE [<nume_schema>.]<nume_secventa>;
După ce a fost ştearsă, secvenŃa nu mai poate fi referită. Pentru a putea şterge sau modifica
secvenŃa trebuie fie să fi proprietarul acesteia, fie să ai privilegiul de sistem DROP ANY
SEQUENCE, respectiv privilegiul ALTER SEQUENCE.
Comentarii

Sistemul Oracle oferă posibilitatea de a comenta obiectele create, printr-un text care este
inserat în dicŃionarul datelor. Comentariul se poate referi la tabele, vizualizări, clişee sau coloane.
COMMENT ON {TABLE nume_obiect | COLUMN
nume_obiect.nume_coloana} IS ’text comentariu’

Sinonime

Oracle oferă posibilitatea de a atribui mai multe nume aceluiaşi obiect. Aceste nume
adiŃionale sunt numite sinonime (synonymes). Ele sunt utile deoarece permit simplificarea formulării
cererii şi referirea la obiecte, fără a fi nevoie să se specifice proprietarii obiectelor sau localizarea
acestora.
Spre deosebire de alias a cărui durată de viaŃă este limitată la cererea ce conŃine alias-ul,
sinonimele sunt salvate în dicŃionarul datelor şi pot fi reutilizate.
Sistemul Oracle permite crearea de sinonime pentru obiecte de tipul: tabel, vizualizare,
secvenŃă, funcŃie, procedură, pachet, clişeu, sinonim.
CREATE [PUBLIC] SYNONYM [schema.]nume_sinonim
FOR [schema.]obiect
Administratorul bazei poate produce şi poate suprima sinonime publice sau private, iar
utilizatorii pot genera sau suprima doar sinonime private. Pentru suprimarea unui sinonim din baza de
date se utilizează comanda:
DROP [PUBLIC] SYNONYM [schema.]nume_sinonim

Vizualizări

Vizualizarea (view) este un tabel logic (virtual) relativ la date din una sau mai multe tabele
sau vizualizări. Vizualizarea este definită plecând de la o cerere a limbajului de interogare a datelor,
moştenind caracteristicile obiectelor la care se referă. Vizualizarea, fiind virtuală, nu solicită o
alocare de memorie pentru date. Ea este definită în DD cu aceleaşi caracteristici ca şi un tabel.
Textul cererii care defineşte vizualizarea este salvat în DD. Nucleul Oracle determină
fuzionarea cererii relative la vizualizare cu comanda de definire a vizualizării, analizează rezultatul
fuziunii în zona partajată şi execută cererea.
 Oracle transformă cererea referitoare la o vizualizare într-o cerere relativă la tabelele de
bază. Vizualizarea este memorata in DD sub forma unui SELECT.
Dacă sunt utilizate clauzele UNION, GROUP BY şi CONNECT BY, atunci Oracle nu determină
fuzionarea, el va rezolva vizualizarea şi apoi va aplica cererea rezultatului obŃinut.
O vizualizare reflectă la orice moment conŃinutul exact al tabelelor de bază. Orice modificare
efectuată asupra tabelelor se repercutează instantaneu asupra vizualizării. Ştergerea unui tabel
implică invalidarea vizualizărilor asociate tabelului şi nu ştergerea acestora.
Vizualizările sunt definite pentru:
• furnizarea unui nivel mai înalt de securizare a bazei;
• simplificarea formulării unei cereri;
• mascarea complexităŃii datelor;
• afişarea datelor într-o altă reprezentare decât cea a tabelelor de bază;
• asigurarea independenŃei datelor;
• asigurarea confidenŃialităŃii anumitor informaŃii;
• definirea constrângerilor de integritate;
• restricŃionarea acesului la date.
Vizualizările pot fi simple şi complexe. O vizualizare simplă extrage date dintr-un singur tabel,
nu conŃine funcŃii sau grupări de date şi asupra ei pot fi efectuate operaŃii LMD.
O vizualizare este considerată complexă dacă extrage date din mai multe tabele, conŃine funcŃii
sau grupări de date şi nu permite întotdeauna (prin intermediul său) operaŃii LMD asupra tabelelor de
bază.
OperaŃiile LMD asupra vizualizărilor complexe sunt restricŃionate de următoarele reguli:
• nu se poate insera, actualiza sau şterge o linie dintr-o vizualizare dacă aceasta conŃine
funcŃii grup, clauza GROUP BY, cuvântul cheie DISTINCT sau pseudocoloana ROWNUM;
• nu se poate adăuga sau modifica o linie dintr-o vizualizare, dacă aceasta conŃine coloane
definite prin expresii;
• nu pot fi adăugate linii printr-o vizualizare, dacă tabelul de bază conŃine coloane care au
constrângerea NOT NULL şi nu apar în lista SELECT a vizualizării.
Pentru a obŃine informaŃii referitoare la vizualizările definite, se pot interoga vizualizările
USER_VIEWS şi ALL_VIEWS din dicŃionarul datelor. Textul instrucŃiunii SELECT care defineşte o
vizualizare este stocat într-o coloană de tip LONG, numită TEXT.
Atunci când datele sunt accesate prin intermediul unei vizualizări, server-ul Oracle efectuează
următoarele operaŃii:
• recuperează definiŃia acesteia din USER_VIEWS;
• verifică privilegiile de acces la tabelele ei de bază;
• converteşte cererea într-o operaŃie echivalentă asupra tabelelor de bază.
Crearea unei vizualizări se realizează cu ajutorul comenzii:
CREATE [OR REPLACE][FORCE | NOFORCE] VIEW
[<nume_schema>.]<nume_view> [(<alias>[,<alias>]…)]
AS <cerere_SELECT>
[WITH {CHECK OPTION [CONSTRAINT <nume_constrangere>] |
READ ONLY }];
– OR REPLACE recreează vizualizarea dacă aceasta deja există.
– FORCE creează vizualizarea chiar dacă tabelul de bază nu există sau chiar dacă vizualizarea face
referinŃă la obiecte care încă nu sunt create. Deşi vizualizarea va fi creată, utilizatorul nu poate să
o folosească.
– NO FORCE este implicită şi se referă la faptul că vizualizarea este creată numai dacă tabelele de
bază există.
– Cererea este o comandă SELECT care poate să conŃină alias pentru coloane.
– WITH CHECK OPTION specifică faptul că reactualizarea datelor din tabele (inserare sau
modificare) se poate face numai asupra datelor selectate de vizualizare (care apar în clauza
WHERE).
– WITH READ ONLY asigură că nici o operaŃie LMD nu poate fi executată asupra vizualizării.
Exemplu:
Să se genereze o vizualizare care conŃine informaŃii referitoare la împrumutul cărŃilor şi în
care să fie implementată constrîngerea că orice carte, care există într-un singur exemplar, poate fi
împrumutată maximum 15 zile.
CREATE VIEW imprumutare
AS SELECT *
FROM imprumuta
WHERE codel NOT IN
(SELECT codel
FROM carte
WHERE nrex = 1)
OR datares - dataim < 15
WITH CHECK OPTION;
Cererea care defineşte vizualizarea poate fi complexă, incluzând join-uri, grupări şi subcereri,
însă nu poate conŃine clauza ORDER BY. Dacă este necesar, această clauză poate fi specificată la
interogarea vizualizării. Interogarea unei vizualizări este similară celei unui tabel. Numărul coloanelor
specificate în definiŃia vizualizării trebuie să fie egal cu cel din lista asociată comenzii SELECT.
Asupra cererii care defineşte vizualizarea se impun următoarele restricŃii:
• nu pot fi selectate pseudocoloanele CURRVAL şi NEXTVAL ale unei secvenŃe;
• dacă sunt selectate pseudocoloanele ROWID, ROWNUM sau LEVEL, acestora trebuie să li
se specifice alias-uri;
• dacă cererea selectează toate coloanele unui tabel, utilizând simbolul „*“, iar ulterior se
adaugă coloane noi tabelului, vizualizarea nu va conŃine acele coloane până la recrearea sa
printr-o instrucŃiune CREATE OR REPLACE VIEW;
• pentru vizualizările obiect, numărul şi tipul elementelor selectate de cerere trebuie să
coincidă cu cel al atributelor de pe primul nivel al tipului obiect.
Aportul versiunii Oracle9i în ceea ce priveşte instrucŃiunea CREATE VIEW constă în
posibilitatea:
• creării de subvizualizări ale vizualizărilor obiect;
• definirii de constrângeri asupra vizualizărilor.
Exemplu:
a) Să se creeze o vizualizare care conŃine numele şi prenumele artistului, numărul operelor
sale şi valoarea medie a acestora.
CREATE VIEW artist_nr_val(nume, numar_opere, val_medie)
AS SELECT a.nume || ' ' || a .prenume "Nume si prenume",
COUNT(o. cod_opera) numar, AVG(o.valoare) medie
FROM opera o, artist a
WHERE o.cod_artist = a.cod_artist
GROUP BY o.cod_artist, a.nume, a.prenume;
b) Să se creeze vizualizarea sculptura ce va conŃine codul operei, data achiziŃiei, codul
artistului şi stilul operelor al căror tip este „sculptura“.
CREATE OR REPLACE VIEW sculptura
(cod_sculptura, informatii, cod_sculptor, stil)
AS SELECT cod_opera,
'Sculptura ' || titlu ||
' a fost achizitionata la data ' ||
data_achizitiei, cod_artist, stil
FROM opera
WHERE tip = 'sculptura';
Modificarea unei vizualizări presupune modificarea definiŃiei acesteia. Pentru a înlocui o
vizualizare trebuie avut privilegiul de sistem necesar pentru distrugerea şi crearea acesteia. Înlocuirea
se poate face în două moduri.

• Vizualizarea poate fi distrusă (DROP VIEW) şi apoi recreată (CREATE) cu noua definiŃie.
Atunci când este distrusă, toate privilegiile sunt retrase. Aceste privilegii trebuie să fie
create pentru noua vizualizare.
• Vizualizarea poate fi recreată prin redefinire cu instrucŃiunea CREATE VIEW, dar cu
clauza OR REPLACE. Această metodă conservă toate privilegiile curente.
In Oracle9i este posibila adaugarea de constrangeri unei vizualizari prin comanda ALTER VIEW.

Modificarea unui vizualizări are următoarele efecte:

• definiŃia vizualizării din DD este actualizată;

• nici unul din obiectele de bază nu este afectat de înlocuire;

• toate restricŃiile care existau în vizualizarea originală sunt distruse;

• toate vizualizările şi programele PL/SQL dependente de vizualizarea înlocuită devin


invalide.

Suprimarea unei vizualizări se realizează prin comanda DROP VIEW care şterge definiŃia
vizualizării din baza de date.
DROP VIEW <nume_view> [CASCADE CONSTRAINT];
Ştergerea vizualizării nu va afecta tabelele relativ la care a fost definită vizualizarea.
AplicaŃiile şi vizualizările care se bazează pe vizualizarea suprimată devin invalide. Pentru a suprima
o vizualizare, utilizatorul trebuie să aibă privilegiul DROP ANY VIEW sau să fie creatorul
vizualizării respective.
Similar opŃiunii corespunzătoare din comanda DROP TABLE, clauza CASCADE
CONSTRAINTS permite suprimarea tuturor constrângerilor de integritate referenŃială corespunzătoare
cheilor primare şi unice din vizualizarea supusă ştergerii. Dacă se omite această clauză şi există astfel
de constrângeri, instrucŃiunea DROP VIEW va eşua.
Recompilarea unei vizualizări permite detectarea eventualelor erori referitoare la
vizualizare, înaintea executării vizualizării. După fiecare modificare a tabelelor de bază este
recomandabil ca vizualizarea să se recompileze:
ALTER VIEW <nume_view> COMPILE;
Reactualizarea tabelelor implică reactualizarea corespunzătoare a vizualizărilor!!!
Reactualizarea vizualizărilor implică reactualizarea tabelelor de bază? NU! Există
restricŃii care trebuie respectate!!!
• Nu pot fi modificate date din vizualizare sau adaugate date prin vizualizare, daca aceasta
contine coloane definite prin expresii.
• Nu pot fi înserate, şterse sau actualizate date din vizualizări ce conŃin: operatorul DISTINCT;
clauzele GROUP BY, HAVING, START WITH, CONNECT BY; pseudo-coloana ROWNUM;
funcŃii grup; operatori de mulŃimi.
• Nu pot fi inserate sau actualizate date care ar încălca constrângerile din tabelele de bază.
• Nu pot fi inserate sau actualizate valorile coloanelor care rezultă prin calcul.
• Nu se pot face operaŃii LMD asupra coloanelor calculate cu DECODE.
Alături de restricŃiile prezentate anterior, aplicabile tuturor vizualizărilor, există restricŃii
specifice, aplicabile vizualizărilor bazate pe mai multe tabele.
Regula fundamentală este că orice operaŃie INSERT, UPDATE sau DELETE pe o
vizualizare bazată pe mai multe tabele poate modifica datele doar din unul din tabelele de bază. In
care???
Un tabel de bază al unei vizualizări este protejat prin cheie (key preserved table) dacă orice
cheie selectată a tabelului este de asemenea şi cheie a vizualizării. Deci, un tabel protejat prin cheie
este un tabel ale cărui chei se păstrează şi la nivel de vizualizare. Pentru ca un tabel să fie protejat
prin cheie nu este necesar ca tabelul să aibă toate cheile selectate în vizualizare. Este suficient ca,
atunci când cheia tabelului este selectată, aceasta să fie şi cheie a vizualizării.
Asupra unui join view pot fi aplicate instrucŃiunile INSERT, UPDATE sau DELETE, doar
dacă sunt îndeplinite următoarele condiŃii:
• instrucŃiunea LMD afectează numai unul dintre tabelele de bază;
• în cazul instrucŃiunii UPDATE, toate coloanele care pot fi reactualizate trebuie să corespundă
coloanelor dintr-un tabel protejat prin cheie (în caz contrar, Oracle nu va putea identifica unic
înregistrarea care trebuie reactualizată);
• în cazul instrucŃiunii DELETE, rândurile unei vizualizări pot fi şterse numai dacă există un
tabel în join protejat prin cheie şi numai unul (în caz contrar, Oracle nu ar şti din care tabel să
şteargă);
• în cazul instrucŃiunii INSERT, toate coloanele în care sunt inserate valori trebuie să provină
dintr-un tabel protejat prin cheie.
ALL_UPDATABLE_COLUMNS, DBA_UPDATABLE_COLUMNS şi
USER_UPDATABLE_COLUMNS sunt vizualizări din DD ce conŃin informaŃii referitoare la
coloanele vizualizărilor existente, care pot fi reactualizate.
Exmplu:
1. Să se creeze un view ce conŃine câmpurile nume, prenume, job din tabelul salariat.
2. Să se insereze, să se actualizeze şi să se şteargă o înregistrare în acest view. Ce efect vor avea
aceste acŃiuni asupra tabelului de bază?
CREATE VIEW vederea2
AS SELECT nume, prenume, job
FROM salariat;
Nu se pot face inserari deoarece view-ul nu conŃine cheia primară!
INSERT INTO vederea2
VALUES ('Popescu','Valentin','grafician');
va genera eroarea:
ORA-01400: cannot insert NULL into
("SCOTT"."SALARIAT"."COD_SALARIAT")
Actualizarea job-ului salariatului având numele "Popescu":
UPDATE vederea2
SET job = 'programator'
WHERE nume = 'Popescu';
SELECT nume, prenume, job FROM salariat;
Ştergerea înregistrării referitoare la salariatul având numele "Popescu":
DELETE vederea2
WHERE nume = 'Popescu';
OperaŃiile care se realizează asupra view-ului se realizează şi în tabelul salariat. Pentru un caz
mai general, când view-ul conŃine cheia externă a tabelului de bază, sunt permise modificări ale view-
ului, dacă acestea nu afectează cheia externă.
Exemplu:
Să se creeze un view care conŃine câmpurile nume, prenume, job din tabelul salariat. Să se
introducă în view doar persoanele care sunt graficieni.
CREATE VIEW vederea21
AS SELECT nume, prenume, job
FROM salariat
WHERE job = 'grafician'
WITH CHECK OPTION;
Să se creeze o vizualizare care să conŃină cod_salariat, nume, prenume din tabelul salariat şi
coloana tip din tabelul grafician. Apoi să se insereze, să se actualizeze şi să se şteargă o înregistrare
din acest view (vizualizarea conŃine cheia primară cod_salariat din tabelele salariat şi grafician).
CREATE VIEW vederea4
AS SELECT s.cod_salariat,nume,prenume,tip
FROM salariat s, grafician g
WHERE s.cod_salariat=g.cod_salariat;
În cazul inserării unei înregistrări pentru care se specifică toate câmpurile:
INSERT INTO vederea4
VALUES (30,'Popescu','Valentin','artist plastic');
va apare următoarea eroare:
ORA-01776: cannot modify more than one base TABLE through a join view
Pot fi inserate date doar într-un tabel de bază (în oricare, dar în unul singur) prin intermediul
view-ului, astfel:
INSERT INTO vederea4 (cod_salariat, nume)
VALUES (30, 'Popescu');
Comanda pentru ştergerea unei înregistrări:
DELETE vederea4
WHERE cod_salariat = 3;
va genera următoarea eroare:
ORA-01752: cannot delete from view without exactly one key-preserved TABLE.
Modificarea unei înregistrări se face prin secvenŃa care urmează. Toate actualizările care se
fac în view se fac şi în tabelele de bază.
UPDATE vederea4
SET tip = 'designer'
WHERE cod_salariat = 3;
Exemplu:
Care dintre coloanele unei vizualizări sunt actualizabile?
SELECT column_name, updatable
FROM user_updatable_columns
WHERE table_name = 'vederea4';
Exemplu:
1. Să se creeze un view (vederea3) care să conŃină, pentru fiecare categorie de salariat, salariile
medii şi numărul de angajaŃi din tabelul salariat.
2. Să se insereze, să se actualizeze şi să se şteargă o înregistrare în view.
CREATE VIEW vederea3 (nr, job, salmed)
AS SELECT COUNT(*), job, AVG(salariu)
FROM salariat
GROUP BY job;
Nu se pot face inserări, actualizări sau ştergeri într-un view ce conŃine funcŃii grup. După
oricare din aceste operaŃii apare acelaşi mesaj:
ORA-01732: data manipulation operation not legal on this view
Exemplu:
Să se creeze o vizualizare care să conŃină coloanele cod_contractant, adresa, telefon din
tabelul contractant şi coloanele nr_contract, tip_contract, data_incheiere din tabelul contract. Să se
insereze o înregistrare în vizualizare.
CREATE VIEW vederea44
AS SELECT c.cod_contractant, adresa, telefon,
co.nr_contract, tip_contract,
data_incheiere
FROM contractant c, contract co
WHERE c.cod_contractant=co.cod_contractant;
La inserarea unei înregistrări căreia i se specifică valorile tuturor câmpurilor din ambele
tabele:
INSERT INTO vederea44(cod_contractant, adresa,
nr_contract, data_incheiere)
VALUES (200, 'Str. Marmurei, 14', '6235',
TO_DATE('January 03,2002','Month dd,yyyy'));
se obŃine eroarea:
ORA-01779: cannot modify a column which maps to a non key-preserved TABLE
Cele două tabele de bază, contractant şi contract, se află într-o relaŃie “one-to-many”, iar
view-ul creat conŃine cheile primare din ambele tabele.
Doar tabelul contract este protejat prin cheie şi, prin urmare, doar el poate fi modificat prin
intermediul view-ului. Aceasta, deoarece ar putea exista mai multe înregistrări în view, cu aceeaşi
valoare corespunzătoare câmpului cod_contractant (CP în contractant).
Exact aceeaşi eroare se obŃine dacă încercăm inserarea unei înregistrări în vederea44,
specificând fie şi numai un câmp provenind din tabela contractant (indiferent dacă el conŃine sau nu
CP).
Singura operaŃie de inserare permisă este aceea efectuată prin specificarea cheilor provenind
doar din tabelul contract. Astfel, prin executarea comenzii:
INSERT INTO vederea44(nr_contract, tip_contract)
VALUES ('6234', 0);
este creată o înregistrare, dar este modificat şi tabelul contract. Dacă la inserŃie nu se specifică cheia
primară din contract:
INSERT INTO vederea44(tip_contract)
VALUES (1);
ORA-01400: mandatory (NOT NULL) column is missing or NULL during insert
Cererea din definiŃia vizualizării poate fi restricŃionată prin clauzele WITH READ ONLY şi
WITH CHECK OPTION. OpŃiunea WITH READ ONLY asigură că nu pot fi efectuate operaŃii LMD
asupra vizualizării. Constrângerea WITH CHECK OPTION garantează faptul că va fi permisă, prin
intermediul vizualizării, numai inserarea sau actualizarea de linii accesibile acesteia (care sunt
selectate de cerere). Prin urmare, această opŃiune asigură constrângeri de integritate şi verificări
asupra validităŃii datelor inserate sau actualizate.
OpŃiunea WITH CHECK OPTION nu poate funcŃiona dacă:
• există o cerere imbricată în cadrul subcererii vizualizării sau în vreuna dintre vizualizările
de bază;
• operaŃiile de inserare, ştergere şi modificare se fac prin intermediul declanşatorilor
INSTEAD OF.
Cuvântul cheie CONSTRAINT permite numirea constrângerii WITH CHECK OPTION. În
absenŃa acestei clauze, constrângerea va avea un nume implicit de forma SYS_Cn, unde n este un
număr întreg unic.
Exemplu:
Să se creeze o vizualizare ce conŃine artiştii de naŃionalitate română, care au opere expuse în
muzeu. DefiniŃia vizualizării nu va permite modificarea naŃionalităŃii unui artist sau inserarea unui
artist având altă naŃionalitate decât cea română.
CREATE VIEW artist_roman
AS SELECT * FROM artist
WHERE nationalitate = 'romana'
WITH CHECK OPTION CONSTRAINT artist_roman_ck;
UPDATE artist_roman
SET nationalitate = 'engleza'
WHERE cod_artist = 25;
Încercarea de actualizare a unei linii prin instrucŃiunea anterioară va genera eroarea „ORA-
01402: view WITH CHECK OPTION where-clause violation“.
Exemplu:
Să se creeze o vizualizare asupra tabelului galerie care să nu permită efectuarea nici unei
operaŃii LMD.
CREATE VIEW viz_galerie
AS SELECT cod_galerie, nume_galerie
FROM galerie
WITH READ ONLY;
DELETE FROM viz_galerie
WHERE cod_galerie = 10;
Încercarea de ştergere a unei linii din vizualizarea viz_galerie determină apariŃia erorii „ORA-
01752: cannot delete from view without exactly one key-preserved table“. Dacă se încearcă modificarea
sau inserarea unei linii prin intermediul unei vizualizări asupra căreia a fost definită o constrângere
WITH READ ONLY, server-ul Oracle generează eroarea „ORA-01733: virtual column not allowed
here“.
Exemplu:
Să se creeze o vizualizare care conŃine codul şi titlul operelor de artă, codul şi numele artiştilor
care le-au creat, precum şi codul galeriilor unde sunt expuse. Să se afle dacă este posibilă adăugarea
unei noi înregistrări prin intermediul acestei vizualizări.
CREATE VIEW opera_artist
AS SELECT o.cod_opera, o.titlu, o.cod_galerie,
a.cod_artist, a.nume
FROM opera o, artist a
WHERE o.cod_artist = a.cod_artist;
InstrucŃiunea următoare afişează numele coloanelor şi valorile YES/NO, după cum aceste
coloane sunt, sau nu, modificabile.
SELECT COLUMN_NAME, UPDATABLE
FROM USER_UPDATABLE_COLUMNS
WHERE TABLE_NAME = 'OPERA_ARTIST';
Se va obŃine că doar primele trei coloane ale vizualizării sunt modificabile.
Indexul primar al coloanei cod_artist din tabelul artist nu este unic în vizualizarea opera_artist.
Prin urmare, tabelul artist nu este key-preserved, iar coloanele sale nu sunt modificabile.
InstrucŃiunea următoare va genera eroarea „ORA-01776: cannot modify more than one base
table through a join view“.
INSERT INTO opera_artist
VALUES (200, 'Poeme de l''ame', 20, 147, 'Janmot');
În schimb, instrucŃiunea următoare va fi executată cu succes, întrucât adaugă o înregistrare în
tabelul de bază opera, ale cărui coloane sunt modificabile.
INSERT INTO opera_artist (cod_opera, titlu, cod_galerie)
VALUES (200, 'Poeme de l''ame', 20);

InformaŃii despre obiectele bazei de date

Pot fi obŃinute consultând DD. Dintre ele se remarcă:


• definiŃiile tuturor obiectelor din baza de date;
• spaŃiul alocat şi spaŃiul utilizat în prezent de obiectele schemei;
• constrângerile de integritate;
• numele utilizatorilor bazei;
• privilegiile şi rolurile acordate fiecărui rol;
• alte informaŃii generale despre baza de date.
Tabelul USER_CATALOG conŃine informaŃii despre tabelele şi vizualizările definite de un
utilizator particular. Acest tabel poate fi referit şi prin sinonimul său public CAT.
Tabelul USER_OBJECTS conŃine informaŃii despre toate obiectele definite de utilizatorul
curent. Tabelul are următoarea schemă relaŃională:
USER_OBJECTS (object_name, object_id, object_type, created, last_ddl_time,
timestamp, status)
Vizualizările cele mai importante ale dicŃionarului datelor conŃin:
• descrierea tabelelor definite de utilizatori (USER_ALL_TABLES),
• informaŃii despre constrângerile definite de utilizator(USER_CONSTRAINTS),
• informaŃii despre legăturile bazei de date (USER_DB_LINKS),
• erorile curente ale obiectelor depozitate (USER_ERRORS),
• informaŃii despre indecşii creaŃi de utilizator (USER_INDEXES),
• informaŃii despre tabelele utilizatorului (USER_TABLES) etc.
Vizualizările din dicŃionarul datelor referitoare la tabele conŃin:
• USER_TAB_COLUMNS|COLS – informaŃii despre coloanele tabelelor,
• USER_CONS_COLUMNS – informaŃii despre constrângeri la nivel coloană,
• USER_TAB_COMMENTS – informaŃii despre comentarii la nivel tabel,
• USER_COL_COMMENTS – informaŃii despre comentarii la nivel coloană,
• USER_TAB_PARTITIONS – informaŃii despre partiŃiile tabelelor.

DQL- Comanda SELECT

Una dintre cele mai importante comenzi ale limbajului de prelucrare a datelor este SELECT.
Cu ajutorul ei pot fi extrase submulŃimi de valori atât pe verticală (coloane), cât şi pe orizontală
(linii) din unul sau mai multe tabele. Sintaxa comenzii este simplă, apropiată de limbajul natural.
SELECT [ALL | DISTINCT]
{* | listă de atribute selectate | expr AS alias}
FROM { [schema.]{tabel [PARTITION (partition_name)] |
[THE] (subquery)} [alias_tabel] }
[WHERE condiŃie]
[GROUP BY listă de expresii
[HAVING condiŃie]]
[ORDER BY {expresie | poziŃie | c_alias} [ASC | DESC]]

PrezenŃa clauzelor SELECT şi FROM este obligatorie deoarece acestea specifică coloanele
selectate, respectiv tabelele din care se vor extrage datele. Tabelele specificate în clauza FROM pot fi
urmate de un alias, care va reprezenta numele folosit pentru referirea tabelului respectiv în cadrul
instrucŃiunii.
Eliminarea duplicatelor se poate realiza folosind clauza DISTINCT. Dacă nu se specifică
parametrul DISTINCT, parametrul ALL este implicit şi are ca efect afişarea dublurilor.
Simbolul “*” permite selectarea tuturor atributelor din tabelele asupra cărora se execută
cererea. Atributele sau expresiile din lista clauzei SELECT pot conŃine alias-uri, care vor reprezenta
numele câmpurilor respective în cadrul tabelului furnizat ca rezultat de instrucŃiunea SELECT.
Clauza WHERE poate fi folosită pentru a impune anumite condiŃii liniilor din care se vor
extrage atributele specificate în clauza SELECT.
Clauza GROUP BY grupează înregistrările după anumite câmpuri; în cazul prezenŃei acestei
clauze, clauza HAVING poate impune restricŃii suplimentare asupra rezultatului final.
Ordonarea înregistrărilor se poate face cu ajutorul clauzei ORDER BY. Cu ajutorul
parametrilor ASC şi DESC se poate specifica ordonarea crescătoare, respectiv descrescătoare a
înregistrărilor. Pentru o secvenŃă crescătoare valorile null sunt afişate ultimele. Dacă nu se face nici o
specificaŃie, atunci ordinea de returnare este la latitudinea server-ului.

Operatorii utilizaŃi (în ordinea priorităŃii de execuŃie) sunt:


• operatori aritmetici (unari sau binari),
• operatorul de concatenare ( || ),
• operatorii de comparare (=, !=, ^=, < >, >, >=, <, <=, IN (echivalent cu =ANY, adică egal
cu cel puŃin una din valorile listei), NOT IN (echivalent cu !=ALL, adică diferit de toate
elementele listei), ALL, [NOT] BETWEEN x AND y, [NOT] EXISTS, [NOT] LIKE, IS [NOT]
NULL,
• operatori logici (NOT, AND, OR).
Limbajul permite prezenŃa unor instrucŃiuni SELECT imbricate în oricare din clauzele
SELECT, WHERE, HAVING sau FROM (instrucŃiunile SELECT care apar în clauzele respective se
numesc subcereri).
În cazul folosirii subcererilor, pot fi utilizaŃi operatorii ALL, ANY, IN (=ANY), EXIST, NOT
IN (!=ANY), care sunt specifici cererilor ce returnează mai multe linii (multiple-row subquery) sau
operatorii de comparaŃie =, <, >, >=, <=, <>, specifici cererilor care returnează o singură linie
(single-row subquery).
Executarea subcererilor se poate face:
• fie cu sincronizare (corelat  evaluarea subcererii face referinŃă la o coloană a cererii
principale şi cererea interioară se execută pentru fiecare linie a cererii principale care o
conŃine);
• fie fără sincronizare (încuibărit  se execută mai întâi cererea interioară, iar rezultatul
ei este transmis cererii de nivel imediat superior).

Cereri mono – relaŃie


Exemplu:
Dacă în interiorul alias-ului apare un spaŃiu liber sau caractere speciale, atunci alias-ul trebuie scris
între ghilimele.
SELECT dateres–dataim ”numar zile”
FROM imprumuta;

Exemplu:
Valorile de tip caracter şi de tip dată calendaristică trebuie să fie incluse între apostrofuri.
SELECT codel
FROM imprumuta
WHERE datares >= ’01–JAN–03’;
Exemplu:
Să se obŃină titlurile şi numărul de exemplare ale cărŃilor scrise de autorii al căror nume
începe cu litera S.
SELECT titlu, nrex
FROM carte
WHERE autor LIKE ’S%’;
Exemplu:
Să se afişeze data şi ora curentă.
SELECT TO_CHAR(SYSDATE,’DD/MM/YY HH24:MI:SS’)
FROM DUAL;
Exemplu:
Utilizând ideea că directorul este salariatul care nu are şef, să se tipărească numele
directorului.
SELECT ename,NVL(TO_CHAR(mgr),’Nu are sef’)
FROM emp
WHERE mgr IS NULL;

Intrebari
NVL(x, y) x si y trebuie sa fie de acelasi tip!
 NVL(comm, 'nu are') este corect?

SELECT ename, job


FROM emp
WHERE mgr IS NULL;
Daca utilizati mgr = NULL este corect?

Se pot folosi alias-uri in clauza WHERE?


SELECT titlu, pret*nrex pret_total
FROM carte
WHERE pret_total>1000;

SELECT titlu.pret_total
FROM (SELECT titlu, pret*nrex pret_total
FROM carte)
WHERE pret_total>1000;

Exemplele anterioare sunt corecte? Comentati!

<nume angajat> castiga <salariu> lunar, dar doreste <salariu de 3 ori mai mare>
SELECT ename||'castiga'||sal||'lunar, dar doreste'
||sal*3 "salariul ideal"
FROM emp;

De ce este incorect?
SELECT titlu, MIN(pret)
FROM carte;

Se pot folosi functii grup in clauza WHERE? NU!


SELECT titlu
FROM carte
WHERE pret = MAX(pret);
SELECT titlu
FROM carte
WHERE pret= (SELECT MAX(pret)
FROM carte);
Exemplu:
Să se afişeze codurile cititorilor care nu au împrumutat cărŃi într-un interval precizat.
SELECT DISTINCT codec
FROM imprumuta
WHERE dataim NOT BETWEEN ’&d1’ AND ’&d2’;
SURSA REZULTAT
'''x''' 'x'
'''' '
''',''' ','
''');' ');
''''||nume_dep||'''' 'informatica'
Se poate folosi alias in clauza WHERE? Pentru coloane NU! Pentru tabele DA!

Clauza GROUP BY
Exemplele care urmează arată modul general de constituire a subansamblelor virtuale folosind
clauza GROUP BY. Fiecare expresie care apare în SELECT trebuie să aibă aceeaşi valoare pentru
toate liniile care aparŃin aceleiaşi partiŃii. Numele coloanelor din GROUP BY nu trebuie să
figureze obligatoriu în lista de la SELECT.
Clauza WHERE are prioritate fata de GROUP BY. Nu se poate utiliza alias de coloana in clauza
GROUP BY.
Pentru a returna informatie corespunxatoare fiecarui grup, pot fi utilizate functiile agregat. Acestea
pot aparea in clauzele SELECT, ORDER BY si HAVING. Se poate utiliza functie grup in clauza
WHERE? Este corect …WHERE AVG(sal) > 200? NU!
Cand se utilizeaza GROUP BY, server-ul sorteaza implicit multimea rezultata in ordinea crescatoare
a valorilor coloanelor dupa care se realizeaza gruparea.
Grupurile sunt formate si functiile grup sunt calculate, inainte ca clauza HAVING sa fie aplicata
grupurilor.
Exemplu:
Să se obŃină numărul de câte ori a fost împrumutată fiecare carte.
SELECT codel, COUNT(*)
FROM imprumuta
GROUP BY codel;
Exemplu:
Pentru fiecare domeniu de carte să se obŃină numărul cărŃilor din domeniu, media preŃurilor şi
numărul total de exemplare.
SELECT coded,COUNT(*),AVG(pret),SUM(nrex)
FROM carte
GROUP BY coded;
Dacă în comanda SELECT apar atribute coloană (nu funcŃii grup) şi se utilizează clauza
GROUP BY atunci aceste coloane trebuie obligatoriu să apară în clauza GROUP BY.
Exemplu:
Să se obŃină pentru fiecare autor, media preŃurilor cărŃilor din bibliotecă.
SELECT autor, AVG(pret)
FROM carte
GROUP BY autor;

Exemplu:
Pentru departamentele în care salariul maxim depăşeşte 5000$ să se obŃină codul acestor
departamente şi salariul maxim pe departament.
SELECT deptno, MAX(sal)
FROM emp
GROUP BY deptno
HAVING MAX(sal)>5000;

Exemplu:
SELECT MAX(AVG(pret))
FROM carte
GROUP BY autor;

Exemplu:
Să se afişeze numele şi salariul celor mai prost plătiŃi angajaŃi din fiecare departament.
SELECT ename, sal
FROM emp
WHERE (deptno, sal) IN
(SELECT deptno, MIN(sal)
FROM emp
GROUP BY deptno);
Exemplu:
Să se obŃină pentru fiecare carte, codul său şi numărul de exemplare care nu au fost încă
restituite.
SELECT codel, COUNT(*)
FROM imprumuta
WHERE dataef IS NULL
GROUP BY codel;

Exemplu:
Să se obŃină numărul cărŃilor împrumutate cel puŃin o dată.
SELECT COUNT(DISTINCT codel)
FROM imprumuta;

Exemplu:
Să se afişeze numărul cărŃilor împrumutate cel puŃin de două ori (pentru fiecare carte
împrumutată mai mult decât o dată să se obŃină numărul de câte ori a fost împrumutată).
SELECT COUNT(COUNT(codel))
FROM imprumuta
GROUP BY codel
HAVING COUNT(*)>1;
În cererea anterioară COUNT(codel), reprezintă numărul care arată de câte ori a fost
împrumutată fiecare carte, iar COUNT(COUNT(codel)), reprezintă numărul total al cărŃilor
împrumutate.
Exemplu:
Sa se afiseze numărul de cărŃi imprumutate din fiecare domeniu.
SELECT d.intdom, COUNT(*)
FROM domeniu d, carte c, imprumuta I
WHERE c.codel = i. codel
AND c.coded = d.coded
GROUP BY intdom;
Exemplu:
Lista codurilor cititorilor care au mai mult de 3 cărŃi nerestituite la termen.
SELECT codec
FROM imprumuta
WHERE dataef IS NULL AND datares < SYSDATE
GROUP BY codec
HAVING COUNT(*) > 2;
Exemplu:
Pentru fiecare domeniu de carte care conŃine cel puŃin o carte şi unde preŃul oricărei cărŃi nu
depăşeşte o valoare dată, să se obŃină: codul domeniului, numărul cărŃilor din domeniu şi numărul
mediu de exemplare.
SELECT coded, COUNT(*), AVG(nrex)
FROM carte
GROUP BY coded
HAVING COUNT(*) >= 1
AND MAX(pret) < &pret_dat;
Exemplu:
Codurile domeniilor care nu contin carti.
SELECT coded
FROM carte
GROUP BY coded
HAVING COUNT(*) = 0;
Nu este corect, deoarece se iau in considerare NUMAI codurile domeniilor care apar in
tabelul CARTE.
SELECT intdom
FROM domeniu d
WHERE 0 = (SELECT COUNT(*)
FROM carte
WHERE coded = d.coded);
Urmatoarea cerere este corecta?
SELECT intdom
FROM domeniu d,(SELECT coded, COUNT(*) a
FROM carte
GROUP BY coded) b
WHERE b.coded = d.coded)
AND b.a = o;
Exemplu:
În ce interogări este necesară utilizarea cuvântului cheie HAVING?
A. când este necesar să eliminăm linii duble din rezultat;
B. când este necesar să ordonăm mulŃimea rezultat;
C. când este necesar să efectuăm un calcul pe grup;
D. când este necesar să restricŃionăm grupurile de linii returnate.
Cereri multi – relaŃie

Comanda SELECT oferă posibilitatea de a consulta informaŃii care provin din mai multe tabele.
Operatorii care intervin în astfel de cereri pot fi:
• operatori pe mulŃimi (UNION, UNION ALL, INTERSECT, MINUS);
• operatori compunere care implementează diferite tipuri de join.
Există două moduri de realizare a cererilor multi-relaŃie:
• forma procedurală, în care trebuie indicat drumul de acces la informaŃie prin imbricarea
de comenzi SELECT;
• forma relaŃională, în care drumul de acces la informaŃie este în sarcina sistemului.
Exemplu:
Să se obŃină, utilizând aceste două forme, codurile şi titlurile cărŃilor împrumutate.
a) Forma procedurală (imbricare de comenzi SELECT):
SELECT codel, titlu
FROM carte
WHERE codel IN (SELECT DISTINCT codel
FROM imprumuta);
b) Forma relaŃională:
SELECT carte.codel, titlu
FROM carte, imprumuta
WHERE carte.codel = imprumuta.codel;

Operatori pe mulŃimi (UNION, UNION ALL, INTERSECT, MINUS)


Comenzile SELECT, care intervin în cereri ce conŃin operatori pe mulŃimi, trebuie să
satisfacă anumite condiŃii:
• toate comenzile SELECT trebuie să aibă acelaşi număr de coloane;
• opŃiunea DISTINCT este implicită (excepŃie UNION ALL);
• numele coloanelor sunt cele din prima comandă SELECT;
• dimensiunea coloanei implicit este cea mai mare dintre cele două coloane;
• sunt admise combinaŃii de forma:
1. SELECT1 UNION SELECT2 INTERSECT SELECT3 şi ordinea de execuŃie este de la
stânga la dreapta;

2. SELECT1 UNION (SELECT2 INTERSECT SELECT3) şi ordinea este dată de paranteze.


Exemplu:
Să se obŃină, utilizând operatorul INTERSECT, codurile cărŃilor din care sunt mai puŃin de 15
exemplare şi care au fost împrumutate de cel puŃin trei ori.
SELECT codel
FROM carte
WHERE nrex < 15
INTERSECT
SELECT codel
FROM imprumuta
GROUP BY codel
HAVING COUNT(*) > 3;
Exemplu:
Să se afişeze codurile cititorilor care nu au împrumutat cărŃi.
SELECT codec
FROM cititor
MINUS
SELECT DISTINCT codec
FROM imprumuta;
Exemplu:
Să se listeze codul operelor, codul artiştilor şi numele acestora, utilizând operatorul UNION
SELECT cod_opera, cod_artist, TO_CHAR(null) nume
FROM opera
UNION
SELECT TO_NUMBER(null), cod_artist, nume
FROM artist

OperaŃii de compunere

Un join simplu (natural join) este o instrucŃiune SELECT care returnează linii din două sau mai
multe tabele. Este preferabil ca tabelul care are linii mai puŃine să fie al doilea în operaŃia de
compunere. Comanda durează mai puŃin, dacă tabela este indexată după coloana, relativ la care se
face compunerea. Compunerea a n tabele cere minim (n-1) condiŃii de join.

Exemplu:
Să se obŃină codurile şi titlurile cărŃilor împrumutate.

SELECT carte.codel, titlu


FROM carte, imprumuta
WHERE carte.codel = imprumuta.codel;

S-ar putea ca tabelele legate prin operaŃia de compunere să nu aibă coloane comune (non-
equijoin). În acest caz în clauza WHERE nu apare operatorul egalitate şi sunt folosiŃi operatorii: <=,
>=, BETWEEN.
Pentru a simplifica scrierea şi pentru a elimina ambiguităŃile care pot să apară este necesară
folosirea alias-ului pentru tabele. Alias-ul este valid doar pentru instrucŃiunea SELECT curentă.

Exemplu:
Să se obŃină pentru fiecare salariat numele, salariul şi grila de salarizare (Θ join).

SELECT e.ename, e.sal, s.grade


FROM emp e, salgrade s
WHERE e.sal BETWEEN s.lasal AND s.hisal;

Exemplu:
Să se obŃină titlurile şi preŃurile cărŃilor mai scumpe decât cartea având titlul “Baze de date”, al
cărui autor este Oszu (self join).

SELECT x.titlu, x.pret


FROM carte x, carte y
WHERE x.pret > y.pret
AND y.titlu = ’Baze de date’
AND y.autor = ’Oszu’;

O altă variantă de rezolvare a problemei, ca o cerere cu sincronizare:

SELECT titlu, pret


FROM carte x
WHERE EXISTS
(SELECT *
FROM carte
WHERE carte.titlu=’Baze de date’
AND carte.autor=’Oszu’
AND x.pret > pret);

Exemplu:
Să se obŃină informaŃii despre cititorii al căror cod este mai mare decât codul unui cititor având
un nume dat.

a) Forma procedurală de rezolvare a cererii este următoarea:


SELECT *
FROM cititor
WHERE codec > (SELECT codec
FROM cititor
WHERE nume=’&nume1’);

b) Forma relaŃională pentru a rezolva cererea este următoarea:


SELECT c2.*
FROM cititor c1, cititor c2
WHERE c1.nume = ’&nume1’
AND c2.codec > c1.codec;

Dacă o linie nu satisface condiŃia de join, atunci linia respectivă nu va apare în rezultatul cererii.
Pentru a evita această pierdere, în algebra relaŃională a fost introdus operatorul outer-join.

Un outer-join (join extern) este reprezentat prin operatorul (+) care este plasat în clauza WHERE
după numele tabelului ale cărui linii trebuie să nu se piardă din rezultatul cererii. Semnul (+) poate fi
plasat în oricare parte a condiŃiei din clauza WHERE, însă nu în ambele părŃi. Efectul operatorului
(+) este că se generează valori null pentru coloanele tabelului lângă care apare scris, ori de câte ori
tabelul nu are nici o linie care să poată fi reunită cu o linie din celălalt tabel.

Exemplu:
Să se obŃină titlurile cărŃilor şi numele domeniului căruia îi aparŃin, remarcând si situaŃiile în care
domeniul nu ar avea cărŃi (dacă domeniul este fără cărŃi atunci apare null la titlul cărŃii).

SELECT titlu, intdom


FROM carte, domeniu
WHERE carte.coded(+) = domeniu.coded;

Exemplu:
Considerăm că tabelele dept şi emp au următorul conŃinut:

dept emp

deptno dname empno deptno


1 algebra 101 null
2 analiza 102 null
103 null
105 1
106 1

Interogarea următoare furnizează lista tuturor salariaŃilor si informatii despre departamentele


in care lucreaza, inclusiv a celor care nu sunt asignaŃi nici unui departament (right outher join).

SELECT a.deptno, a.dname, b.empno, b.deptno


FROM dept a, emp b
WHERE a.deptno(+) = b.deptno;

Rezultatul cererii anterioare va fi:

a.deptno a.dname b.empno b.deptno


101
102
103
1 algebra105 1
1 algebra106 1

Interogarea următoare afişează lista departamentelor, inclusiv a celor care nu au salariaŃi (left
outer join).

SELECT a deptno, a.dname, b.empno, b.deptno


FROM dept a, emp b
WHERE a.deptno = b.deptno(+);

Rezultatul cererii anterioare va fi:

a.deptno a.dname b.empno b.deptno


1 algebra105 1
1 algebra106 1
2 analiza null null
Interogarea următoare produce ca rezultat departamentele, chiar şi cele fără funcŃionari, şi
funcŃionarii, chiar şi cei care nu sunt asignaŃi nici unui departament (full outer join).
SELECT NVL(TO_CHAR(b.empno),’***’) id,
NVL(a.dname,’***’) nume_dep
FROM dept a, emp b
WHERE a.deptno = b.deptno(+)
UNION
SELECT NVL(TO_CHAR(b.empno),’***’) id,
NVL(a.dname,’***’) nume_dep
FROM dept a, emp b
WHERE a.deptno(+) = b.deptno;

Rezultatul cererii va fi:

id nume_dep
*** analiza
101 ***
102 ***
103 ***
105 algebra
106 algebra

Subcereri
De cele mai multe ori, pentru a implementa anumite interogări, nu este suficientă o singură
cerere SELECT ci sunt necesare subcereri. Subcererile sunt comenzi SELECT încapsulate în oricare
din clauzele SELECT, WHERE, HAVING, FROM.
Dacă subcererea urmează clauzei WHERE sau HAVING, ea poate conŃine unul dintre operatorii
ALL, ANY, IN (=ANY), EXIST, NOT IN (!=ALL) care sunt specifici cererilor care întorc mai multe linii
(multiple-row subquery) sau unul dintre operatorii de comparare (=, <, >, >=, <=, <>) care sunt
specifici cererilor care întorc o singură linie (single-row subquery).
Subcererile trebuie incluse între paranteze şi trebuie plasate în partea dreaptă a operatorului de
comparare. Subcererea nu poate conŃine clauza ORDER BY.
Exemplu:
Să se obŃină numele şi salariul angajaŃilor, având salariul minim.

SELECT ename, sal


FROM emp
WHERE sal=(SELECT MIN(sal)
FROM emp);
Exemplu:
Să se obŃină job-ul pentru care salariul mediu este minim. Sa se afiseze si salariul mediu.

SELECT job, AVG(sal)


FROM emp
GROUP BY job
HAVING AVG(sal)=(SELECT MIN(AVG(sal))
FROM emp
GROUP BY job);

Operatorul ANY presupune că este adevărată condiŃia dacă comparaŃia este adevărată pentru cel
puŃin una din valorile returnate. Sunt evidente relaŃiile:
< ANY  mai mic ca maximul;
> ANY  mai mare ca minimul;
= ANY  IN.

Pentru operatorul ALL se presupune că este adevărată condiŃia, dacă comparaŃia este adevărată
pentru toate elementele listei returnate. Pentru operatorul ALL sunt evidente relaŃiile:
< ALL  mai mic ca minimul;
> ALL  mai mare ca maximul;
! = ALL  NOT IN.

Exemplu:
WHERE codec > ALL (‘C1’, ‘C2’)  este superior tuturor elementelor din listă;

WHERE codec > ANY (‘C1’, ‘C2’)  este superior cel puŃin unui element din listă.

Exemplu:
Să se obŃină salariaŃii al căror salariu este mai mare ca salariile medii din toate departamentele.

SELECT ename, job


FROM emp
WHERE sal > ALL(SELECT AVG(sal)
FROM emp
GROUP BY deptno);

Există subcereri care au ca rezultat mai multe coloane (multiple-column subquery). Aceste
interogări au următoarea sintaxă generală:

SELECT col,col,…
FROM tabel
WHERE (col,col,…) IN (SELECT col,col,…
FROM tabel
WHERE condiŃie);
Exemplu:
Să se obŃină numele, numărul departamentului, salariul şi comisionul tuturor funcŃionarilor ale
căror salarii şi comisioane coincid cu salariile şi comisioanele unor salariaŃi din departamentul 7.

SELECT ename, deptno, sal, com


FROM emp
WHERE (sal,NVL(com,-1)) IN
(SELECT sal,NVL(com,-1)
FROM emp
WHERE deptno = 7);

Rezultatul acestei interogări este diferit de rezultatul următoarei interogări:

SELECT ename, deptno, sal, com


FROM emp
WHERE sal IN (SELECT sal
FROM emp
WHERE deptno=7)
AND NVL(com,-1) IN (SELECT NVL(com,-1)
FROM emp
WHERE deptno=7);

Dacă una din valorile returnate de subcerere este valoarea null atunci cererea nu întoarce nici o
linie. Prin urmare, dacă valoarea null poate să facă parte din rezultatul subcererii nu trebuie utilizat
operatorul NOT IN. Problema nu mai apare dacă se utilizează operatorul IN.

Exemplu:
Să se obŃină salariaŃii care nu au subordonaŃi.

SELECT e.ename
FROM emp e
WHERE e.empno NOT IN (SELECT m.mgr
FROM emp m);
În acest caz, instrucŃiunea SQL nu întoarce nici o linie deoarece una din valorile furnizate de
subcerere este valoarea null.
Exemplu:
Să se obŃină numele salariaŃilor, salariile, codul departamentului în care lucrează şi salariul mediu
pe departament pentru toŃi angajaŃii care au salariul mai mare ca media salariilor din departamentul
în care lucrează (folosirea subcererii în clauza FROM).
SELECT a.ename,a.sal,a.deptno,b.salavg
FROM emp a,(SELECT deptno,avg(sal) salavg
FROM emp
GROUP BY deptno) b
WHERE a.deptno=b.deptno
AND a.sal>b.salavg
Exemplu:
Să se obŃină lista celor mai scumpe cărŃi.
SELECT titlu
FROM carte
WHERE pret = (SELECT MAX(pret)
FROM carte);
Exemplu:
Să se obŃină lista scriitorilor care au în bibliotecă un număr de exemplare mai mare decât
numărul mediu al cărŃilor din bibliotecă.
SELECT DISTINCT autor
FROM carte
WHERE nrex > (SELECT AVG(nrex)
FROM carte);
Exemplu:
Să se obŃină informaŃii despre cărŃile al căror preŃ depăşeşte media preŃurilor cărŃilor ce
aparŃin aceluiaşi domeniu
SELECT *
FROM carte c
WHERE pret > (SELECT AVG(pret)
FROM carte
WHERE coded = c.coded);
Exemplu:
Să se obŃină lista cititorilor care au împrumutat cel puŃin o carte.
SELECT nume
FROM cititor
WHERE codec IN (SELECT DISTINCT codec
FROM imprumuta);
Exemplu:
Să se obŃină codurile cititorilor care nu au împrumutat niciodată cărŃi.
SELECT codec
FROM cititor
WHERE codec NOT IN
(SELECT DISTINCT codec
FROM imprumuta);
Exemplu:
Să se obŃină lista cititorilor care sunt în întârziere cu predarea cărŃilor.
SELECT nume
FROM cititor
WHERE codec IN (SELECT DISTINCT codec
FROM imprumuta
WHERE dataef IS NULL
AND dares<SYSDATE);
Exemplu:
Să se obŃină numele cititorilor care au împrumutat cel puŃin o carte scrisă de ZOLA.
SELECT nume
FROM cititor
WHERE codec IN
(SELECT DISTINCT codec
FROM imprumuta
WHERE codel IN
(SELECT codel
FROM carte
WHERE autor=’ZOLA’));
Exemplu:
Să se obŃină numele cititorilor care nu au împrumutat nici o carte scrisă de ZOLA.
SELECT nume
FROM cititor
WHERE codec NOT IN
(SELECT DISTINCT codec
FROM imprumuta
WHERE codel IN
(SELECT codel
FROM carte
WHERE autor=’ZOLA’));
Operatorul IN poate fi înlocuit cu = ANY (un element este în listă dacă şi numai dacă este egal cu
un element al listei), iar operatorul NOT IN poate fi înlocuit prin !=ALL.
Exemplu:
Să se obŃină codurile cititorilor care au împrumutat o carte de algebră.
SELECT DISTINCT codec
FROM imprumuta
WHERE codel IN
(SELECT codel
FROM carte
WHERE coded=
(SELECT coded
FROM domeniu
WHERE intdom=’ALGEBRA’));
Exemplu:
Să se obŃină cititorii care au împrumutat numai cărŃi scrise de ‘ZOLA’.
SELECT nume
FROM cititor
WHERE codec NOT IN
(SELECT DISTINCT codec
FROM imprumuta
WHERE codel NOT IN
(SELECT codel
FROM carte
WHERE autor=’ZOLA’));
Exemplu:
Să se obŃină numele cititorilor care au împrumutat cel puŃin o carte de informatică
(procedural).

SELECT nume
FROM cititor
WHERE codec IN
(SELECT DISTINCT codec
FROM imprumuta
WHERE codel IN
(SELECT codel
FROM carte
WHERE coded=
(SELECT coded
FROM domeniu
WHERE intdom= ’INFORMATICA’)));
Exemplu:
Să se obŃină numele cititorilor şi titlurile cărŃilor de informatică împrumutate de aceşti cititori
(relational).
SELECT nume, titlu
FROM cititor, carte, imprumuta, domeniu
WHERE imprumuta.codel = carte.codel
AND carte.coded = domeniu.coded
AND imprumuta.codec = cititor.codec
AND intdom = ’INFORMATICA’;

Subcererile pot fi executate corelat (cu sincronizare) sau încuibărit (fără sincronizare).
Subcererile fără sincronizare sunt caracterizate de faptul că se execută cererea cea mai interioară
care întoarce un rezultat ce este transmis cererii de nivel superior, care întoarce un rezultat s.a.m.d.
Subcererile cu sincronizare sunt caracterizate de faptul că evaluarea subcererii face referinŃă la o
coloană a cererii principale, iar evaluarea cererii interioare se face pentru fiecare linie a cererii
(principale) care o conŃine.
Exemplu:
Să se obŃină, utilizând sincronizarea subcererii cu cererea principală, titlurile cărŃilor care au
toate exemplarele împrumutate (se selectează un titlu din carte şi pentru acest titlu se numără câte
exemplare sunt împrumutate).
SELECT titlu
FROM carte
WHERE nrex=(SELECT COUNT(*)
FROM imprumuta
WHERE codel = carte.codel
AND dataef IS NULL);

Exemplu:
Să se obŃină codurile cititorilor şi codul ultimei cărŃi împrumutate.
SELECT codec, codel
FROM imprumuta i
WHERE dataim>=ALL (SELECT dataim
FROM imprumuta
WHERE codec=i.codec);

Pentru această interogare, clauza WHERE putea fi scrisă şi sub forma:

WHERE dataim=(SELECT MAX(dataim)


FROM imprumuta
WHERE codec=i.codec);

Exemplu:
Să se obŃină lista codurilor cărŃilor împrumutate şi codul primului cititor care a împrumutat
aceste cărti.

SELECT codel,codec
FROM imprumuta i
WHERE dataim<=ALL (SELECT dataim
FROM imprumuta
WHERE i.codel=codel);

Exemplu:
Să se obŃină codurile cărŃilor din care cel puŃin un exemplar este împrumutat.

SELECT codel
FROM carte
WHERE EXISTS
(SELECT codel
FROM imprumuta
WHERE codel = carte.codel
AND dataef IS NULL);

Operatorul WHERE EXISTS (subcerere) presupune că predicatul este adevărat dacă subcererea
întoarce cel puŃin un tuplu, iar WHERE NOT EXISTS (subcerere) presupune că predicatul este
adevărat dacă subcererea nu întoarce nici un tuplu.  EXISTS şi NOT EXISTS cer sincronizarea
subcererii.

Exemplu:
Să se obŃină titlurile cărŃilor care sunt momentan împrumutate.
SoluŃia 1 (cu sincronizare):
SELECT titlu
FROM carte
WHERE EXISTS
(SELECT *
FROM imprumuta
WHERE codel = carte.codel
AND dataef IS NULL);
SoluŃia 2 (fără sincronizare):
SELECT titlu
FROM carte
WHERE codel IN
(SELECT DISTINCT codel
FROM imprumuta
WHERE dataef IS NULL);

Exemplu:
Să se obŃină codurile cărŃilor care nu au fost împrumutate niciodată.

SoluŃia 1 (cu sincronizare)


SELECT codel
FROM carte
WHERE NOT EXISTS
(SELECT codel
FROM imprumuta
WHERE codel = carte.codel);
SoluŃia 2 (fără sincronizare)
SELECT codel
FROM carte
WHERE codel NOT IN
(SELECT DISTINCT codel
FROM imprumuta);

Exemplu:
Să se obŃină lista salariaŃilor având salariul minim în departamentul în care lucrează.

SELECT ename,sal
FROM emp e
WHERE sal=(SELECT MIN(sal)
FROM emp
WHERE deptno=e.deptno);

Exemplu:
Să se obŃină numele primilor trei salariaŃi având retribuŃia maximă (ideea rezolvării este de a
verifica dacă numărul salariaŃilor care au leafa mai mare decât leafa salariatului considerat, este mai
mic decât 3).

SELECT ename
FROM emp a
WHERE 3>(SELECT COUNT(*)
FROM emp
WHERE sal > a.sal);

Exemplu:
Să se obŃină numele cititorilor care au împrumutat cel puŃin aceleaşi cărŃi ca şi cititorul având
codul C19 (ideea problemei este de a selecta cititorii pentru care este vidă lista cărŃilor
împrumutatede C19 mai puŃin lista cărŃilor împrumutate de acei cititori).

SELECT nume
FROM cititor
WHERE NOT EXISTS
(SELECT codel
FROM imprumuta
WHERE codec=’C19’
MINUS
SELECT codel
FROM imprumuta
WHERE codec= cititor.codec);

Dacă problema era modificată în sensul că „cel puŃin”este înlocuit prin „cel mult” atunci trebuiau
inversate interogările legate prin MINUS.

Exemplu:
Să se obŃină codurile cititorilor care au împrumutat aceleaşi cărŃi ca şi cititorul având un cod
specificat.
Rezolvarea problemei se bazează pe ideea: A = B  A ⊂ B şi B ⊂ A  (A-B) = ∅ şi (B-A) = ∅
 A-B şi B-A nu furnizează nici un tuplu rezultat.
SELECT codec
FROM imprumuta i
WHERE NOT EXISTS
(SELECT codel
FROM imprumuta
WHERE codec=i.codec
MINUS
SELECT codel
FROM imprumuta
WHERE codec=’&ccc’)
AND NOT EXISTS
(SELECT codel
FROM imprumuta
WHERE codec=’&ccc’
MINUS
SELECT codel
FROM imprumuta
WHERE codec=i.codec)
AND codec!=’&ccc’);
Ultimul operator (AND), asigură să nu apară în rezultat cititorul specificat.
În cazul formei relaŃionale de rezolvare a cererii, drumul de acces la informaŃie este în sarcina
SGBD-lui şi prin urmare nu mai apar cereri imbricate.
Exemplu:
Să se obŃină numele cititorilor care au împrumutat cel puŃin o carte.
SoluŃia 1 (forma relaŃională):
SELECT DISTINCT nume
FROM cititor,imprumuta
WHERE cititor.codec=imprumuta.codec;
SoluŃia 2 (forma procedurală):
SELECT nume
FROM cititor
WHERE codec IN
(SELECT DISTINCT codec
FROM imprumuta);
Exemplu:
Să se obŃină numele cititorilor care au împrumutat cel puŃin două cărŃi.
SoluŃia 1 (forma relaŃională):
SELECT nume
FROM cititor, imprumuta
WHERE cititor.codec=imprumuta.codec
GROUP BY nume
HAVING COUNT(*)>1;
SoluŃia 2 (forma procedurală):
SELECT nume
FROM cititor
WHERE codec IN
(SELECT codec
FROM imprumuta
GROUP BY codec
HAVING COUNT(*)>1);

Exemplu:
Să se afişeze numele, prenumele, salariul lucrătorilor, codurile publicaŃiilor la care lucrează şi
salariul mediu pe publicaŃie pentru toŃi angajaŃii care au salariul mai mare decât media salariului pe
publicaŃia respectivă.
SELECT s.nume, s.prenume, s.salariu,
p.nr_publicatie, a.salariu_mediu
FROM salariat s, publicatie p,
(SELECT p1.nr_publicatie,AVG(salariu) salariu_mediu
FROM publicatie p1, salariat s1
WHERE p1.cod_salariat = s1.cod_salariat
GROUP BY p1.nr_publicatie) a
WHERE p.nr_publicatie = a.nr_publicatie
AND s.cod_salariat = p.cod_salariat
AND s.salariu > a.salariu_mediu;
Exemplu:
Să se obŃină numele salariaŃilor care nu cunosc nici o limbă străină.
SELECT nume, prenume
FROM salariat
WHERE NOT EXISTS
(SELECT *
FROM limba
WHERE limba.cod_salariat = salariat.cod_salariat
AND limba_cun IS NOT NULL);
Exemplu:
Să se afişeze graficienii care au întârziat să predea frame-urile.
a) cu sincronizare:
SELECT nume, prenume
FROM salariat
WHERE EXISTS
(SELECT *
FROM realizeaza r
WHERE salariat.cod_salariat=r.cod_salariat
AND data_lim < SYSDATE);
b) fără sincronizare:
SELECT nume, prenume
FROM salariat
WHERE cod_salariat IN
(SELECT DISTINCT cod_salariat
FROM realizeaza
WHERE data_lim < SYSDATE);
Exemplu:
Să se determine revistele coordonate de redactori şefi care nu cunosc limba în care sunt
scrise. Se ştie că în urma inspectării vizuale a rezultatului interogării se poate decide schimbarea
redactorilor şefi ai revistelor respective, de aceea se doreşte blocarea înregistrărilor găsite.
SELECT p.nr_publicatie
FROM salariat s, publicatie p
WHERE s.cod_salariat = p.cod_salariat
AND p.limba NOT IN
(SELECT limba_cun
FROM limba
WHERE limba.cod_salariat = s.cod_salariat)
FOR UPDATE OF p.cod_salariat;

Operatorul ROLLUP
Operatorul ROLLUP produce o mulŃime care conŃine liniile obŃinute în urma grupării
obişnuite şi linii pentru subtotaluri. Acest operator furnizează valori agregat şi superagregat
corespunzătoare expresiilor din clauza GROUP BY.
Operatorul ROLLUP creează grupări prin deplasarea într-o singură direcŃie, de la dreapta la
stânga, de-a lungul listei de coloane specificate în clauza GROUP BY. Apoi, se aplică funcŃia agregat
acestor grupări. Dacă sunt specificate n expresii în operatorul ROLLUP, numărul de grupări generate
va fi n + 1. Liniile care se bazează pe valoarea primelor n expresii se numesc linii obişnuite, iar
celelalte se numesc linii superagregat.
Daca in clauza GROUP BY sunt specificate n coloane, atunci pentru a produce subtotaluri in
n dimensiuni ar fi necesare n+1 operatii SELECT legate prin UNION ALL. Aceasta ar fi total
ineficient, deoarece fiecare SELECT ar implica o parcurgere a tabelului. Operatorul ROLLUP are
nevoie de o singura parcurgere a tabelului.
Exemplu:
Să se afişeze codurile de galerii mai mici decât 50, iar pentru fiecare dintre acestea şi pentru
fiecare autor care are opere expuse în galerie, să se listeze valoarea totală a lucrărilor sale. De
asemenea, se cere valoarea totală a operelor expuse în fiecare galerie. Rezultatul va conŃine şi
valoarea totală a operelor din galeriile având codul mai mic decât 50, indiferent de codul autorului.
SELECT cod_galerie, cod_artist, SUM(valoare)
FROM opera
WHERE cod_galerie < 50
GROUP BY ROLLUP(cod_galerie, cod_artist);
InstrucŃiunea precedentă va avea un rezultat de forma:
COD_GALERIE COD_ARTIST SUM(VALOARE)
10 50 14000
10 60 10000
10 24000
40 50 8080
40 8080
32080

Operatorul CUBE
Operatorul CUBE grupează liniile selectate pe baza valorilor tuturor combinaŃiilor posibile
ale expresiilor specificate şi returnează câte o linie totalizatoare pentru fiecare grup. El produce
subtotaluri pentru toate combinaŃiile posibile de grupări specificate în GROUP BY, precum şi un total
general.
Daca exista n coloane sau expresii in clauza GROUP BY, vor exista 2n combinatii posibile
superagregat. Matematic, aceste combinatii formeaza un cub n-dimensional.
Pentru producerea de subtotaluri fara ajutorul operatorului CUBE ar fi necesare 2n
instructiuni SELECT legate prin UNION ALL.
Exemplu:
Să se afişeze valoarea totală a operelor de artă ale unui autor, expuse în cadrul fiecărei galerii
având codul mai mic decât 50. De asemenea, să se afişeze valoarea totală a operelor din fiecare
galerie având codul mai mic decât 50, valoarea totală a operelor fiecărui autor indiferent de galerie şi
valoarea totală a operelor din galeriile având codul mai mic decât 50.
SELECT cod_galerie, cod_artist, SUM(valoare)
FROM opera
WHERE cod_galerie < 50
GROUP BY CUBE(cod_galerie, cod_artist);

COD_GALERIE COD_ARTIST SUM(VALOARE)


10 50 14000
10 60 10000
10 24000
40 50 8080
40 8080
50 22080
60 10000
32080

FuncŃia GROUPING

Aceasta funcŃie este utilă pentru:

• determinarea nivelului de agregare al unui subtotal dat, adică a grupului sau grupurilor
pe care se bazează subtotalul respectiv;

• identificarea provenienŃei unei valori null a unei expresii calculate, dintr-una din liniile
mulŃimii rezultat.
Functia returnează valoarea 0 sau 1. Valoarea 0 poate indica fie că expresia a fost utilizată
pentru calculul valorii agregat, fie că valoarea null a expresiei este o valoare null stocată.

Valoarea 1 poate indica fie că expresia nu a fost utilizată pentru calculul valorii agregat, fie
că valoarea null a expresiei este o valoare creată de ROLLUP sau CUBE ca rezultat al grupării.
Exemplu:
SELECT cod_galerie, cod_artist, SUM(valoare),
GROUPING(cod_galerie), GROUPING(cod_artist)
FROM opera
WHERE cod_galerie < 50
GROUP BY ROLLUP(cod_galerie, cod_artist);

SUM GROUPING GROUPING


COD_GALERIE COD_ARTIST
(VALOARE) (COD_GALERIE) (COD_ARTIST)
10 50 14000 0 0
10 60 10000 0 0
10 24000 0 1
40 50 8080 0 0
40 8080 0 1
32080 1 1
Pe prima linie din acest rezultat, valoarea totalizatoare reprezintă suma valorilor operelor
artistului având codul 50, în cadrul galeriei 10. Pentru a calcula această valoare au fost luate în
considerare coloanele cod_galerie şi cod_artist. Prin urmare, expresiile GROUPING(cod_galerie) şi
GROUPING(cod_artist) au valoarea 0 pentru prima linie din rezultat.
Pe linia a treia se află valoarea totală a operelor din galeria având codul 10. Această valoare a
fost calculată luând în considerare doar coloana cod_galerie, astfel încât GROUPING (cod_galerie)
şi GROUPING(cod_artist) au valorile 0, respectiv 1.
Pe ultima linie din rezultat se află valoarea totală a operelor din galeriile având codul mai mic
decât 50. Nici una dintre coloanele cod_galerie şi cod_artist nu au intervenit în calculul acestui total,
prin urmare valorile corespunzătoare expresiilor GROUPING(cod_galerie) şi
GROUPING(cod_artist) sunt 0.

Clauza GROUPING SETS

GROUPING SETS reprezintă o extensie a clauzei GROUP BY care permite specificarea unor
grupări multiple de date.
Această extensie, apărută în sistemul Oracle9i, permite scrierea unei singure instrucŃiuni
SELECT pentru a specifica grupări diferite (care pot conŃine operatorii ROLLUP şi CUBE), în loc de
mai multe instrucŃiuni SELECT combinate prin operatorul UNION ALL. De altfel, reuniunea
rezultatelor mai multor cereri este ineficientă întrucât necesită mai multe parcurgeri ale aceloraşi
date.
Operatorii ROLLUP şi CUBE pot fi consideraŃi cazuri particulare de mulŃimi de grupări. Au
loc următoarele echivalenŃe:

CUBE(a, b, c)
GROUPING SETS
((a, b, c), (a, b), (a, c), (b, c), (a), (b), (c), ())
ROLLUP(a, b, c)
GROUPING SETS
((a, b, c), (a, b), (a), ())

Exemplu:
Considerând galeriile al căror cod este mai mic decât 50, să se calculeze media valorilor
operelor:
• pentru fiecare galerie şi, în cadrul acesteia, pentru fiecare artist;
• pentru fiecare artist şi, în cadrul acestuia, pentru anii de achiziŃie corespunzători.
SELECT cod_galerie, cod_artist,
TO_CHAR(data_achizitiei, 'yyyy') "an achizitie",
AVG(valoare) "Valoare medie"
FROM opera WHERE cod_galerie < 50
GROUP BY GROUPING SETS
((cod_galerie, cod_artist),
(cod_artist, TO_CHAR(data_achizitiei, 'yyyy')));
MulŃimea rezultat este constituită din valorile medii pentru fiecare dintre cele două grupuri
((cod_galerie, cod_artist) si (cod_artist, an_achizitie)) şi are forma următoare:
COD_GALERIE COD_ARTIST An achizitie Valoare medie
10 50 3500
10 60 2500
40 50 2020
50 2000 2380
50 2002 2300
60 2001 2000
60 2003 3000

Exemplul precedent poate fi rezolvat şi prin următoarea instrucŃiune compusă:


SELECT cod_galerie, cod_artist, NULL "An achizitie",
AVG(valoare) "Valoare medie"
FROM opera
GROUP BY cod_galerie, cod_artist
UNION ALL
SELECT NULL, cod_artist,
TO_CHAR(data_achizitiei, 'yyyy'), AVG(valoare)
FROM opera
GROUP BY cod_artist, TO_CHAR(data_achizitiei, 'yyyy');
În absenŃa unui optimizor care analizează blocurile de cerere şi generează planul de execuŃie,
cererea precedentă va parcurge de două ori tabelul de bază (opera), ceea ce poate fi ineficient. Din
acest motiv, este recomandată utilizarea extensiei GROUPING SETS.

FuncŃii în SQL

Exista doua tipuri de functii:


• care opereaza pe o linie si returneaza un rezultat pe linie (single row functions);
• care opereaza pe un grup de linii si returneaza un rezultat pe grup de linii (functii grup sau
multiple row functions).
Single row functions pot sa fie:
• funcŃii pentru prelucrarea caracterelor,
• funcŃii aritmetice,
• funcŃii pentru prelucrarea datelor calendaristice,
• funcŃii de conversie,
• funcŃii generale (NVL, NVL2, NULLIF, CASE, DECODE etc.).

FuncŃii de conversie
Conversiile pot fi făcute:
• implicit de către server-ul Oracle ;
• explicit de către utilizator.
Conversii implicite
În cazul atribuirilor, sistemul poate converti automat:
• VARCHAR2 sau CHAR în NUMBER ;
• VARCHAR2 sau CHAR în DATE;
• VARCHAR2 sau CHAR în ROWID;
• NUMBER, ROWID, sau DATE în VARCHAR2.
Pentru evaluarea expresiilor, sistemul poate converti automat:
• VARCHAR2 sau CHAR în NUMBER, dacă şirul de caractere reprezintă un număr;
• VARCHAR2 sau CHAR în DATE, dacă şirul de caractere are formatul implicit DD-MON-
YY;
• VARCHAR2 sau CHAR în ROWID.
Conversii explicite
• funcŃia TO_CHAR converteşte data calendaristică sau informaŃia numerică în şir de
caractere conform unui format;
• funcŃia TO_NUMBER converteşte un şir de caractere în număr;
• funcŃia TO_DATE converteşte un şir de caractere în dată calendaristică conform unui
format.
Dacă formatul este omis, convertirea se face conform unui format implicit. FuncŃia
TO_DATE are forma TO_DATE(şir_de_caractere [,’fmt’]). FuncŃia este utilizată dacă se doreşte
conversia unui şir de caractere care nu are formatul implicit al datei calendaristice (DD-MON-YY).
Alte funcŃii de conversie sunt: CHARTOROWID, CONVERT, HEXTORAW, RAWTOHEX,
ROWIDTOCHAR etc., iar denumirea semnificativă arată rolul fiecăreia.
Exemplu:
SELECT TO_DATE(’Feb 22,1981’,’Mon dd,YYYY’)
FROM DUAL;

FuncŃii pentru prelucrarea caracterelor


• LENGTH(string) – returnează lungimea şirului de caractere string;
• LENGTHB(string) – îndeplineşte aceaşi funcŃie ca şi LENGTH, cu deosebirea că
returnează numărul de octeŃi ocupaŃi;
• SUBSTR(string, start [,n]) – returnează subşirul lui string care începe pe poziŃia start şi
are lungimea n; dacă n nu este specificat, subşirul se termină la sfârşitul lui string;
• LTRIM(string [,’chars’]) – şterge din stânga şirului string orice caracter care apare în
chars până la găsirea primului caracter care nu este în chars; dacă chars nu este
specificat, se şterg spaŃiile libere din stânga lui string;
• RTRIM(string [,’chars’]) – este similar funcŃiei LTRIM, cu excepŃia faptului că ştergerea
se face la dreapta şirului de caractere;
• LPAD(string, length [,’chars’]) – adaugă chars la stânga şirului de caractere string până
când lungimea noului şir devine length; în cazul în care chars nu este specificat, atunci se
adaugă spaŃii libere la stânga lui string;
• RPAD(string, length [,’chars’]) – este similar funcŃiei LPAD, dar adăugarea de caractere
se face la dreapta şirului;
• REPLACE(string1, string2 [,string3]) – returnează string1 cu toate apariŃiile lui string2
înlocuite prin string3; dacă string3 nu este specificat, atunci toate apariŃiile lui string2
sunt şterse;
• INITCAP(string) – transformă primul caracter al şirului în majusculă;
• INSTR(string, ‘chars’ [,start [,n]]) – caută în string, începând de de la poziŃia start, a n-a
apariŃie a secvenŃei chars şi întoarce poziŃia respectivă; dacă start nu este specificat,
căutarea se face de la începutul şirului; dacă n nu este specificat, se caută prima apariŃie a
secvenŃei chars;
• UPPER(string), LOWER(string) – transformă toate literele şirului de caractere string în
majuscule, respectiv minuscule;
• ASCII(char) – returnează codul ASCII al unui caracter;
• CHR(num) – returnează caracterul corespunzător codului ASCII specificat;
• CONCAT(string1, string2) – realizează concatenarea a două şiruri de caractere;
• SOUNDEX(string) – returnează reprezentarea fonetică a şirului de caractere specificat;
• TRANSLATE(string, from, to) – fiecare caracter care apare în şirurile de caractere string
şi from este transformat în caracterul corespunzător (aflat pe aceeaşi poziŃie ca şi în from)
din şirul de caractere to;

FuncŃii aritmetice
Cele mai importante funcŃii aritmetice sunt: ABS (valoarea absolută), ROUND (rotunjire cu
un număr specificat de zecimale), TRUNC (trunchiere cu un număr specificat de zecimale), EXP
(ridicarea la putere a lui e), LN (logaritm natural), LOG (logaritm într-o bază specificată), MOD
(restul împărŃirii a două numere specificate), POWER (ridicarea la putere), SIGN (semnul unui
număr), COS (cosinus), COSH (cosinus hiperbolic), SIN(sinus), SQRT(rădăcina pătrată),
TAN(tangent), funcŃiile LEAST şi GREATEST, care returnează cea mai mică, respectiv cea mai mare
valoare a unei liste de expresii etc.

FuncŃii pentru prelucrarea datelor calendaristice


• SYSDATE – returnează data şi timpul curent;
• ADD_MONTHS(d, count) – returnează data care este după count luni de la data d;
• NEXT_DAY(d, day) – returnează următoarea dată după data d, a cărei zi a săptămânii este
cea specificată prin şirul de caractere day;
• LAST_DAY(d) – returnează data corespunzătoare ultimei zile a lunii din care data d face
parte;
• MONTHS_BETWEEN(d2, d1) – returnează numărul de luni dintre cele două date
calendaristice specificate;
• NEW_TIME(data, zona_intrare, zona_iesire) – returnează ora din zona_intrare
corespunzătoare orei din zona_iesire;
• ROUND(d) – dacă data d este înainte de miezul zilei, întoarce data d cu timpul setat la
ora 12:00 AM; altfel, este returnată data corespunzătoare zilei următoare, cu timpul setat
la ora 12:00 AM;
• TRUNC(d) – întoarce data d, dar cu timpul setat la ora 12:00 AM (miezul nopŃii);
• LEAST(d1, d2, …, dn), GREATEST(d1, d2, …, dn) – returnează, dintr-o listă de date
calendaristice, prima, respectiv ultima dată în ordine cronologică.
Exemplu:
ROUND(’25-jul-95’, ’MONTH’) este 01-AUG-95,
ROUND(’25-jul-95’, ’YEAR’) este 01-JAN-96,
TRUNC(’25-jul-95’, ’MONTH’) este 01-JUL-95,
TRUNC(’25-jul-95’, ’YEAR’) este 01-JAN-95.
Utilizarea literelor mari sau mici în formatul unei date calendaristice precizează forma
rezultatului. De exemplu, ’MONTH’ va da rezultatul MAY, iar ’Month’ va da rezultatul May.
DD "of" MONTH va avea ca efect 12 of OCTOBER
OperaŃii cu date calendaristice
OperaŃie Rezultat Descriere
Data + număr Data Adaugă un număr de zile la o dată
Data - număr Data Scade un număr de zile dintr-o dată
Data - data Număr zile Scade două date calendaristice
Data + numar/24 Data Adună un număr de ore la o dată

Pentru afişarea câmpurilor de tip dată calendaristică sau pentru calcule în care sunt implicate
aceste câmpuri, există funcŃii specifice. Câteva din elementele care apar în formatul unei date
calendaristice sunt prezentate în tabelul următor.
Format Descriere Domeniu
SS Secunda relativ la minut 0-59
SSSSS Secunda relativ la zi 0-86399
MI Minut 0-59
HH Ora 0-12
HH24 0-24
Ora
DAY Ziua săptămânii SUNDAY-SATURDAY
D Ziua săptămânii 1-7
DD Ziua lunii 1-31 (depinde de lună)
DDD Ziua anului 1-366 (depinde de an)
MM Numărul lunii 1-12
MON Numele prescurtat al lunii JAN-DEC
MONTH Luna JANUARY-DECEMBER
YY Ultimele două cifre ale anului de exemplu, 99
YYYY Anul de exemplu, 1999
YEAR Anul în litere
CC Secolul de exemplu, 17
Q Numărul trimestrului 1-4
W Săptămâna lunii 1-5
WW Săptămâna anului 1-52
Formatul RR este comentat pe urmatorul exemplu:

Anul curent Data specificata Format RR Format YY

1995 27-OCT-95 1995 1995

1995 27-OCT-17 2017 1917

2001 27-OCT-17 2017 2017

2001 27-OCT-95 1995 2095


Exemplu:
Pentru operele achiziŃionate în ultimii 2 ani, să se afişeze codul galeriei în care sunt expuse,
data achiziŃiei, numărul de luni de la cumpărare, data primei verificări, prima zi în care au fost
expuse într-o galerie şi ultima zi a lunii în care au fost achiziŃionate. Se va considera că data primei
verificări este după 10 luni de la achiziŃionare, iar prima expunere într-o galerie a avut loc în prima zi
de duminică după achiziŃionare.
SELECT cod_galerie, data_achizitiei,
MONTHS_BETWEEN(SYSDATE, data_achizitiei) "Numar luni",
ADD_MONTHS(data_achizitiei, 10) "Data verificare",
NEXT_DAY(data_achizitiei, 'SUNDAY') Expunere,
LAST_DAY(data_achizitiei)
FROM opera
WHERE MONTHS_BETWEEN(SYSDATE, data_achizitiei) <= 24;

FuncŃii generale
• DECODE(value, if1, then1, if2, then2, … , ifN, thenN, else) – returnează then1 dacă value
este egală cu if1, then2 dacă value este egală cu if2 etc.; dacă value nu este egală cu nici
una din valorile if, atunci funcŃia întoarce valoarea else (selecŃie multiplă);
• NVL(e1, e2) – dacă e1 este NULL, returnează e2; altfel, returnează e1;
• NVL2(e1, e2, e3) – dacă e1 este NOT NULL, atunci returnează e2, altfel, returnează e3;
• NULLIF(e1, e2) – returneaza null daca e1=e2 si returneaza e1 daca e1 nu este egal cu e2;
• COALESCE(e1, e2, en) – returneaza prima expresie care nu este null din lista de
expresii (expresiile trebuie sa fie de acelasi tip).
Exemplu:
NVL(comision, 0) este 0 dacă comisionul este null. Prin urmare, expresia salariu*12 +
comision nu este corectă, deoarece rezultatul său este null dacă comisionul este null. Forma corectă
este salariu*12 + NVL(comision, 0).

Exemplu:
Să se afişeze preŃul modificat al unor cărŃi în funcŃie de editură. Pentru cărŃile din editura ALL
să se dubleze preŃurile, pentru cele din editura UNIVERS să se tripleze preŃurile, iar pentru cele din
editura XXX să se reducă la jumătate acest preŃ.
SELECT pret,editura,
DECODE(editura, ’ALL’,pret*2,
’UNIVERS’,pret*3,
’XXX’,pret/2,
pret) pret_revizuit
FROM carte;
Expresia CASE returneaza null daca nu exista clauza ELSE si daca nici o conditie nu este
indeplinita.
SELECT nume, sal,
(CASE WHEN sal <5000 THEN 'LOW'
WHEN sal <10000 THEN 'MEDIUM'
WHEN sal <20000 THEN 'GOOD'
ELSE 'EXCELLENT'
END) calificare
FROM salariat;
Exemplu:
Pentru înregistrările tabelului opera, să se afişeze titlul, data achiziŃiei, valoarea şi o coloană
reprezentând valoarea operei după ce se aplică o mărire, astfel: pentru operele achiziŃionate în 1998
creşterea este de 20%, pentru cele cumpărate în 1999 creşterea este de 15%, iar valoarea celor
achiziŃionate în anul 2000 creşte cu 10%. Pentru operele cumpărate în alŃi ani valoarea nu se
modifică.
SELECT titlu, data_achizitiei, valoare,
CASE TO_CHAR(data_achizitiei, 'yyyy')
WHEN '1998' THEN valoare * 1.20
WHEN '1999' THEN valoare * 1.15
WHEN '2000' THEN valoare * 1.10
ELSE valoare
END "Valoare marita"
FROM opera;
InstrucŃiunea din acest exemplu poate fi rescrisă utilizând funcŃia DECODE:
SELECT titlu, data_achizitiei, valoare,
DECODE (TO_CHAR(data_achizitiei, 'yyyy'),
'1998', valoare * 1.20,
'1999', valoare * 1.15,
'2000', valoare * 1.10,
valoare) "Valoare marita"
FROM opera;

FuncŃii grup
• AVG (media aritmetică),
• COUNT(*) (numărul de linii returnate de o cerere),
• COUNT ([DISTINCT] numărul valorilor unui expresii),
• SUM (suma valorilor unei expresii),
• MIN (valoarea minimă a unei expresii),
• MAX (valoarea maximă a unei expresii),
ObservaŃii:
• FuncŃiile grup operează pe un grup de linii şi nu cer folosirea clauzei GROUP BY.
• FuncŃiile grup ignoră valorile null.
• Orice funcŃie grup întoarce o singură valoare.
• Ele întorc valoarea null când sunt aplicate unei mulŃimi vide, cu excepŃia operatorului
COUNT care întoarce valoarea zero.
• Spre deosebire de funcŃiile COUNT, MIN şi MAX care pot fi aplicate unor câmpuri
numerice sau nenumerice, restul funcŃiilor grup se aplică doar câmpurilor numerice.
• FuncŃiile grup pot să apară în lista de la SELECT sau în clauza HAVING.
Exemplu:
Să se afişeze numărul cărŃilor distincte împrumutate.
SELECT COUNT(DISTINCT codel)
FROM imprumuta;
Exemplu:
Comanda care urmează este greşită! De ce?
SELECT titlu, COUNT(*)
FROM carte;
Exemplu:
Să se calculeze media preŃurilor cărŃilor din bibliotecă.
SELECT AVG(pret)
FROM carte;

Exemplu:
SELECT MAX(pret) - MIN(pret) diferenta
FROM carte;
Exemplu:
Să se obŃină suma, media valorilor, valoarea minimă şi cea maximă pentru operele de artă
expuse în galeria având codul 30. De asemenea, se va afişa numărul de opere şi numărul de artişti
care au creaŃii expuse în această galerie.
SELECT SUM(valoare) Suma, AVG(valoare) Media,
MIN(valoare) Minim, MAX(valoare) Maxim,
COUNT(*) Numar,
COUNT(DISTINCT cod_artist) "Numar artisti"
FROM opera
WHERE cod_galerie = 30;
Întrucât funcŃiile grup ignoră valorile null, această instrucŃiune va returna media valorilor pe
baza liniilor din tabel pentru care există o valoare validă stocată în coloana valoare. Aceasta
înseamnă că suma valorilor se împarte la numărul de valori diferite de null. Pentru a calcula media pe
baza tuturor liniilor din tabel, se utilizează:
SELECT AVG(NVL(valoare, 0))
FROM opera;
Exemplu:
Să se afişeze media valorilor operelor de artă pentru fiecare galerie şi, în cadrul acesteia,
pentru fiecare artist.
SELECT cod_galerie, cod_artist, AVG(valoare)
FROM opera
GROUP BY cod_galerie, cod_artist;

DML - Comanda INSERT

INSERT INTO nume_tabel / nume_view [(col1[, col2[,…]])]


VALUES (expresia1[, expresia2[,…]]) / subcerere;
• expresia1, expresia2, reprezintă expresii a căror evaluare este atribuită coloanelor precizate (se
inserează o linie);
• subcerere, reprezintă o interogare (se inserează una sau mai multe linii).
ObservaŃii:
• Dacă lipseşte specificaŃia coloanelor se consideră că sunt completate toate câmpurile
tabelului sau vizualizării.
• Dacă nu a fost specificată lista coloanelor şi dacă există câmpuri care nu au valori
efective, atunci valoarea null va fi atribuită acestor câmpuri.
• Dacă se introduc date doar în anumite coloane, atunci aceste coloane trebuie specificate.
În restul coloanelor se introduce automat null (daca nu exista DEFAULT).
• Specificarea cererii din comanda INSERT determină copierea unor date dintr-un tabel în
altul pe atâtea linii câte au rezultat din cerere.
• Dacă se introduc numai anumite câmpuri într-o înregistrare, atunci printre acestea trebuie
să se găsească câmpurile cheii primare.
• Pentru a putea executa comanda INSERT este necesar ca utilizatorul care execută această
instrucŃiune să aibă privilegiul de a insera înregistrări în tabel sau în vizualizare.
Exemplu:
Să se insereze în tabelul carte toate cărŃile din tabelul carte_info, presupunând că tabelul
carte_info a fost deja creat. De asemenea, să se introducă o nouă carte căreia i se cunoaşte codul
(c34), titlul (algebra) şi preŃul (500).
INSERT INTO carte
SELECT *
FROM carte_info;
INSERT INTO carte(codel,titlu,autor,nrex,pret,coded)
VALUES (’c34’,’algebra’,null,null,500,null);

Exemplu:
INSERT INTO carte(codel, nrex)
VALUES ('c25', 25);
INSERT INTO domeniu
VALUES ('&cod','&intdom');inserare prin parametrizare
** Exemplu:
INSERT INTO
(SELECT cod_opera, titlu, data
FROM opera
WHERE cod_galerie = 40)
VALUES (…);
** Exemplu:
INSERT INTO opera(cod_opera,…)
VALUES (123,…)
RETURNING valoare*10, cod_opera INTO :x, :y;
Exemplu:
Presupunând că tabelul salariat a fost completat cu datele tuturor salariaŃilor editurii, să se
completeze tabelele grafician, tehnoredactor şi redactor_sef, în concordanŃă cu datele conŃinute în
tabelul salariat (nu pot exista graficieni, tehnoredactori sau redactori şefi care să nu fie salariaŃi!).
INSERT INTO grafician (cod_salariat)
SELECT cod_salariat
FROM salariat
WHERE job = ’grafician’;
INSERT INTO tehnoredactor (cod_salariat)
SELECT cod_salariat
FROM salariat
WHERE job = ’tehnoredactor’;
INSERT INTO redactor_sef (cod_salariat)
SELECT cod_salariat
FROM salariat
WHERE job = ’redactor_sef’;

Exemplu:
Se doreşte ca toŃi graficienii având salariile mai mari decât media salariilor să colaboreze la
realizarea tuturor frame-urilor din publicaŃii coordonate de redactori şefi având vechimea maximă.
Să se completeze tabelul realizeaza cu înregistrările corespunzătoare.
INSERT INTO realizeaza (cod_salariat, nr_publicatie,
nr_capitol, nr_frame)
SELECT s.cod_salariat,f.nr_publicatie, f.nr_capitol,
f.nr_frame
FROM salariat s, frame f
WHERE s.salariu > (SELECT AVG(s1.salariu)
FROM salariat s1)
AND job = 'grafician'
AND f.nr_publicatie IN
(SELECT p.nr_publicatie
FROM salariat s2, publicatie p
WHERE s2.cod_salariat = p.cod_salariat
AND s2.vechime = (SELECT MAX(s3.vechime)
FROM salariat s3));

** Inserare în multiple tabele


Începând cu Oracle9i, comanda INSERT permite inserarea de date in multiple tabele. Ea este
utila in mediul warehouse. Inserarea se poate realiza neconditionat sau conditionat (utilizand clauza
WHEN). O comanda INSERT multitabel poate contine maximum 127 clauze WHEN.
Inserările multiple sunt permise numai pentru tabele (nu pentru vizualizari sau vizualizari
materializate). Subcererea nu poate utiliza o secventa.
1. Inserare necondiŃionată utilizând clauza ALL
Exemplu:
INSERT ALL
INTO sal_history VALUES(empid, hiredate, sal)
INTO mgr_history VALUES(empid, mgr, sal)
SELECT employee_id empid, hire_date hiredate,
salary sal, manager_id mgr
FROM employees
WHERE employee_id > 177;
2. Inserare condiŃionată utilizând clauzele WHEN şi ALL
Exemplu:
INSERT ALL
WHEN sal > 1000 THEN
INTO sal_history VALUES(empid, hiredate, sal)
WHEN mgr >177 THEN
INTO mgr_history VALUES(empid, mgr, sal)
SELECT employee_id empid, hire_date hiredate,
salary sal, manager_id mgr
FROM employees
WHERE employee_id > 177;
3. Inserare condiŃionată utilizând clauza FIRST
În acest caz, server-ul Oracle evalueaza fiecare clauză WHEN în ordinea apariŃiei în comanda
INSERT. OpŃiunea FIRST determină inserarea corespunzătoare primei clauze WHEN a cărei condiŃie
este evaluată true. Toate celelalte clauze WHEN sunt ignorate pentru linia respectivă. Pentru liniile
care nu satisfac prima conditie WHEN, restul conditiilor sunt evaluate in aceeasi maniera ca pentru
INSERT conditional. Dacă nici o condiŃie din clauzele WHEN nu este adevărată, atunci sistemul
execută clauza INTO corespunzătoare opŃiunii ELSE, iar dacă aceasta nu există, nu efectuează nici o
acŃiune.
Exemplu:
INSERT FIRST
WHEN sal > 20000 THEN
INTO special_sal VALUES(deptid, sal)
WHEN hiredate LIKE('%00%') THEN
INTO hiredate_history_oo VALUES(deptid, hiredate)
WHEN hiredate LIKE('%99%') THEN
INTO hiredate_history_99 VALUES(deptid, hiredate)
ELSE
INTO hiredate_history VALUES(deptid, hiredate)
SELECT department_id deptid, SUM(salary) sal,
MAX(hire_date) hiredate
FROM employees
GROUP BY department_id;
4. Inserare din tabele nerelaŃionale (pivotare nerelaŃional  relaŃional)

Exemplu:
Tabelul alfa (emp_id, week_id, sale_lu, sale_ma, sale_mi, sale_jo, sale_vi) provine dintr-o
bază nerelaŃională. Să se depună aceste date, în format relaŃional, în tabelul sales_info (emp_id,
week, sales).
Practic, in tabelul sales_info se vor insera 5 inregistrari.
INSERT ALL
INTO sales_info VALUES (emp_id, week_id, sale_lu)
INTO sales_info VALUES (emp_id, week_id, sale_ma)
INTO sales_info VALUES (emp_id, week_id, sale_mi)
INTO sales_info VALUES (emp_id, week_id, sale_jo)
INTO sales_info VALUES (emp_id, week_id, sale_vi)
SELECT emp_id, week_id, sale_lu, sale_ma,
sale_mi, sale_jo, sale_vi
FROM alfa;
Comanda DELETE

Ştergerea unei linii dintr-un tabel (simplu, partiŃionat sau tabel de bază a unei vizualizări) se
realizează prin comanda DELETE.
DELETE
[FROM] tablename / viewname [AS alias]
[WHERE condiŃie] [clauza_returning]
ObservaŃii:
• Comanda DELETE nu şterge structura tabelului.
• Pentru a se putea executa instrucŃiunea DELETE, utilizatorul care o lansează în execuŃie
trebuie să aibă acest privilegiu.
• În clauza WHERE pot fi folosite şi subcereri.
• Comanda nu poate fi folosită pentru ştergerea valorilor unui câmp individual. Acest lucru
se poate realiza cu ajutorul comenzii UPDATE.
• AtenŃie la ştergere, pentru a nu afecta integritatea referenŃială!

Exemplu:
Să se elimine cititorii care au numele ‘Popa’şi cei care au restituit astăzi cel puŃin o carte.

DELETE FROM cititor


WHERE nume=’Popa’
OR codec IN (SELECT codec
FROM imprumuta
WHERE data_ef=SYSDATE);
Exemplu:
Să se şteargă tehnoredactorii care colaborează la mai puŃin de trei publicaŃii.
DELETE FROM salariat
WHERE job = ’tehnoredactor’
AND COUNT(SELECT DISTINCT c.nr_publicatie
FROM capitol c
WHERE c.cod_salariat = cod_salariat)< 3;
** Exemplu:
Să se elimine redactorii şefi care nu au coordonat nici o publicaŃie.
DELETE FROM redactor_sef
WHERE cod_salariat NOT IN
(SELECT DISTINCT cod_salariat
FROM publicatie);
** Exemplu:
Să se şteargă salariul angajatului având codul 1279.
UPDATE salariat
SET salariu=null
WHERE cod_salariat = 1279;
** Exemplu:
Urmatoarele doua comenzi sunt echivalente.
DELETE FROM opera
WHERE cod_opera = 777;
DELETE FROM (SELECT * FROM opera)
WHERE cod_opera = 777;
** Exemplu:
Să se şteargă cartea cea mai scumpă şi să se reŃină valoarea acesteia într-o variabilă de legătură.
DELETE FROM carte
WHERE pret = (SELECT MAX(pret)
FROM carte
RETURNING pret INTO :aaa;
** Exemplu:
Pentru fiecare autor care are mai mult de 10 creaŃii expuse în muzeu, să se şteargă ultima operă
creată de acesta.
DELETE FROM opera o1
WHERE cod_artist =
(SELECT cod_artist
FROM opera o2
WHERE cod_artist = o1.cod_artist
AND data_crearii =
(SELECT MAX(data_crearii)
FROM opera
WHERE cod_artist = o2.cod_artist)
AND 10 <
(SELECT COUNT(*)
FROM opera
WHERE cod_artist = o2.cod_artist));

Comanda UPDATE

Pentru modificarea valorilor existente intr-un tabel sau intr-un tabel de baza a unei vizualizari
se utilizeaza comanda UPDATE. Valorile câmpurilor care trebuie modificate pot fi furnizate explicit
sau pot fi obŃinute în urma unei cereri SQL.
UPDATE tablename / viewname
SET (column1[,column2[,…]]) = (subquery) / column = expr / (query)
[WHERE condition]
ObservaŃii:
• Pentru a se putea executa instrucŃiunea UPDATE, utilizatorul care o lansează în execuŃie
trebuie să aibă acest privilegiu.
• Dacă nu este specificată clauza WHERE se vor modifica toate liniile.
• Cererea trebuie să furnizeze un număr de valori corespunzător numărului de coloane din
paranteza care precede caracterul de egalitate.

Exemplu:
PreŃul cărŃilor scrise de Lucian Blaga să fie modificat, astfel încât să fie egal cu preŃul celei
mai scumpe cărŃi de informatică din bibliotecă.
UPDATE carte
SET pret = (SELECT MAX(pret)
FROM carte
WHERE coded = ’I’)
WHERE autor = ’Lucian Blaga’;

Exemplu:
Să se modifice preŃul cărŃilor din bibliotecă, care se găsesc într-un număr de exemplare mai
mic decât media numărului de exemplare pe bibliotecă. Noua valoare a preŃului să fie egală cu suma
preŃurilor cărŃilor scrise de Zola.
UPDATE carte
SET pret = (SELECT SUM(pret)
FROM carte
WHERE autor = ’Zola’)
WHERE nrex < (SELECT AVG(nrex)
FROM carte);
Exemplu:
Să se reducă cu 10% salariile redactorilor şefi care nu sunt asociaŃi nici unei publicaŃii.
UPDATE salariat
SET salariu = 0,9*salariu
WHERE cod_salariat IN
(SELECT cod_salariat
FROM redactor_sef
WHERE cod_salariat NOT IN
(SELECT cod_salariat
FROM publicatie));
Exemplu:
Să se mărească cu 5% salariile redactorilor şefi ce coordoneaza publicaŃiile care au cel mai
mare număr de frame-uri.
UPDATE salariat
SET salariu = 1,05*salariu
WHERE cod_salariat IN
(SELECT cod_salariat
FROM publicatie
WHERE nr_publicatie IN
(SELECT nr_publicatie
FROM frame
GROUP BY nr_publicatie
HAVING COUNT(*) > ALL
(SELECT COUNT(*)
FROM frame
GROUP BY nr_publicatie)));
** Oracle9i permite utilizarea valorii implicite DEFAULT in comenzile INSERT si UPDATE.
Unei coloane i se atribuie valoarea implicită definită la crearea sau modificarea structurii tabelului
dacă nu se precizează nici o valoare sau dacă se precizează cuvântul cheie DEFAULT în comenzile
INSERT sau UPDATE. Dacă nu este definită nici o valoare implicită pentru coloana respectivă,
sistemul îi atribuie valoarea null.
Exemplu:
UPDATE carte
SET pret = DEFAULT
WHERE codel = 77;

LIMBAJUL PENTRU CONTROLUL DATELOR- DCL

Controlul unei baze de date cu ajutorul SQL-ului se refera la:


• asigurarea confidentialitatii si securitatii datelor;
• organizarea fizica a datelor;
• realizarea unor performante;
• reluarea unor actiuni in cazul unei defectiuni;
• garantarea coerentei datelor in cazul prelucrarii concurente.
Sistemul de gestiune trebuie:
• să pună la dispoziŃia unui număr mare de utilizatori o mulŃime coerentă de date;
• să garanteze coerenŃa datelor în cazul manipulării simultane de către diferiŃi utilizatori.
CoerenŃa este asigurată cu ajutorul conceptului de tranzacŃie. TranzacŃia este unitatea logică
de lucru constând din una sau mai multe instrucŃiuni SQL, care trebuie să fie executate atomic (ori se
execută toate, ori nu se execută nici una!), asigurând astfel trecerea BD dintr-o stare coerentă în altă
stare coerentă.
Dacă toate operaŃiile ce constituie tranzacŃia sunt executate şi devin efective, spunem că
tranzacŃia este validată, iar modificările aduse de tranzacŃie devin definitive.
Dacă dintr-un motiv sau altul (neverificarea condiŃiilor, accesul imposibil) o operaŃie a
tranzacŃiei nu a fost executată spunem că tranzacŃia a fost anulată. Modificările aduse de toate
operaŃiile tranzacŃiei anulate sunt şi ele anulate şi se revine la starea bazei de date de dinaintea
tranzacŃiei anulate.
Este posibil ca o tranzacŃie să fie descompusă în subtranzacŃii, astfel încât dacă este necesar
să se anuleze doar parŃial unele operaŃii.
 Fiecare tranzacŃie se poate termina:
• “normal” (commit);
• “anormal” (rollback).
Controlul tranzacŃiilor constă în:
• definirea începutului şi sfârşitului unei tranzacŃii,
• validarea sau anularea acesteia,
• eventuală descompunere în subtranzacŃii.
Limbajul pentru controlul datelor (LCD) permite salvarea informaŃiei, realizarea fizică a
modificărilor în baza de date, rezolvarea unor probleme de concurenŃă.
Limbajul conŃine următoarele instrucŃiuni:
• COMMIT - folosită pentru permanentizarea modificărilor executate asupra BD (modificările
sunt înregistrate şi sunt vizibile tuturor utilizatorilor);
• ROLLBACK - folosită pentru refacerea stării anterioare a BD (sunt anulate toate
reactualizările efectuate de la începutul tranzacŃiei);
• SAVEPOINT - folosită în conjuncŃie cu instrucŃiunea ROLLBACK, pentru definirea unor
puncte de salvare în fluxul programului.
O tranzacŃie constă:
• dintr-o singură instrucŃiune LDD;
• dintr-o singură instrucŃiune LCD;
• din instrucŃiuni LMD care fac schimbări consistente în date.
TranzacŃia începe:
• după o comandă COMMIT,
• după o comandă ROLLBACK,
• după conectarea iniŃială la Oracle,
• când este executată prima instrucŃiune SQL.
TranzacŃia se termină:
• dacă sistemul cade;
• dacă utilizatorul se deconectează;
• dacă se dau comenzile COMMIT sau ROLLBACK ;
• dacă se execută o comandă LDD.
După ce se termină o tranzacŃie, prima instrucŃiune SQL executabilă va genera automat
începutul unei noi tranzacŃii.
 Un commit apare automat:
• când este executată o comandă LDD;
• când este executată o comandă LCD;
• după o ieşire normală din SQL*Plus fără specificarea explicită a comenzilor COMMIT
sau ROLLBACK.
Un rollback apare automat după o ieşire “anormală“ din SQL*Plus sau o cădere sistem.
Din momentul în care s-a executat instrucŃiunea COMMIT, BD s-a modificat (permanent) în
conformitate cu instrucŃiunile SQL executate în cadrul tranzacŃiei care tocmai s-a terminat. Din acest
punct începe o nouă tranzacŃie.
Dacă se foloseşte utilitarul SQL*Plus, există posibilitatea ca după fiecare comandă LMD să
aibă loc o permanentizare automată a datelor (un COMMIT implicit). Acest lucru se poate realiza
folosind comanda:
SET AUTO[COMMIT] {ON | OFF}
Comanda ROLLBACK permite restaurarea unei stări anterioare a BD.
ROLLBACK [TO [SAVEPOINT] savepoint];
Dacă nu se specifică nici un savepoint, toate modificările făcute în tranzacŃia curentă sunt
anulate, iar dacă se specifică un anumit savepoint, atunci doar modificările de la acel savepoint până
în momentul respectiv sunt anulate. Executarea unei instrucŃiuni ROLLBACK presupune terminarea
tranzacŃiei curente şi începerea unei noi tranzacŃii.
Punctele de salvare pot fi considerate ca nişte etichete care referă o submulŃime a
schimbărilor dintr-o tranzacŃie, marcând efectiv un punct de salvare pentru tranzacŃia curentă.
Punctele de salvare NU sunt obiecte ale schemei. Prin urmare, nu sunt referite in DD.
Server-ul Oracle implementează un punct de salvare implicit pe care îl mută automat după
ultima comandă LMD executată. Dacă este creat un punct de salvare având acelaşi nume cu unul
creat anterior, cel definit anterior este şters automat.
SAVEPOINT savepoint;
Exemplu:
Comanda ROLLBACK nu va genera terminarea tranzacŃiei.
COMMIT
INSERT …
SAVEPOINT a
UPDATE …
INSERT …
SAVEPOINT b
DELETE …
ROLLBACK TO a
Starea datelor înainte de COMMIT sau ROLLBACK este următoarea:
• starea anterioară a datelor poate fi recuperată;
• utilizatorul curent poate vizualiza rezultatele operaŃiilor LMD prin interogări asupra
tabelelor;
• alŃi utilizatori nu pot vizualiza rezultatele comenzilor LMD făcute de utilizatorul curent
(read consistency);
• înregistrările (liniile) afectate sunt blocate şi, prin urmare, alŃi utilizatori nu pot face
schimbări în datele acestor înregistrări.
ExecuŃia unei comenzi COMMIT implică anumite modificări.
• Toate schimbările (INSERT, DELETE, UPDATE) din baza de date făcute după anterioara
comandă COMMIT sau ROLLBACK sunt definitive. Comanda se referă numai la
schimbările făcute de utilizatorul care dă comanda COMMIT.
• Toate punctele de salvare vor fi şterse.
• Starea anterioară a datelor este pierdută definitiv.
• ToŃi utilizatorii pot vizualiza rezultatele.
• Blocările asupra liniilor afectate sunt eliberate; liniile pot fi folosite de alŃi utilizatori
pentru a face schimbări în date.
ExecuŃia unei comenzi ROLLBACK implică anumite modificări.
• Anulează tranzacŃia în curs şi toate modificările de date făcute după ultima comandă
COMMIT.
• Sunt eliberate blocările liniilor implicate.
• Nu şterge un tabel creat prin CREATE TABLE. Eliminarea tabelului se poate realiza doar
prin comanda DROP TABLE.
Exemplu:
Ce efect are următoarea secvenŃă de instrucŃiuni?
(a) SELECT *
FROM salariat;

(b) SAVEPOINT a;
(c) DELETE FROM salariat;
INSERT INTO salariat
VALUES (18,’Breaban’,’Marin’,4,5000, ’tehnored’);
INSERT INTO salariat
VALUES (23,’Popescu’,’Emil’,7,40000,’grafician’);
SAVEPOINT b;

(d) INSERT INTO salariat


VALUES (29,’’,’’,5,3000000,’tehnoredactor’);
SELECT AVG(salariu)
FROM salariat;

(e) ROLLBACK TO b;
SELECT AVG(salariu)
FROM salariat;

(f) ROLLBACK TO a;
INSERT INTO salariat
VALUES (18,’Ion’,’Mihai’,5,580,’redr_sef’);
COMMIT;

ConsistenŃa la citire
Într-un sistem multi-user, sistemul Oracle furnizează read consistency la nivel de
instrucŃiune SQL, adică o singură comandă SQL nu poate da rezultate care sunt contradictorii sau
inconsistente. Read consistency asigură că fiecare utilizator “vede” datele aşa cum existau la ultimul
commit, înainte să înceapă o operaŃie LMD. Prin urmare, modificările efectuate asupra unei baze de
date nu sunt vizibile decât după ce operaŃia de actualizare a fost validată. Numai utilizatorul care a
executat tranzacŃia poate vedea modificările făcute de el în cursul acestei tranzacŃii.
Modelul multiversiune, furnizat de Oracle, asigură consistenŃa la citire:
• garantează că setul de date văzut de orice instrucŃiune SQL este consistent şi nu se schimbă în
timpul execuŃiei unei instrucŃiuni (Oracle asigură o consistenŃă la citire la nivel de
instrucŃiune);
• operaŃiile de citire (SELECT) nu trebuie să vadă datele care sunt în proces de schimbare;
• operaŃiile de scriere (INSERT, DELETE, UPDATE) nu trebuie să afecteze consistenŃa datelor
şi să întrerupă sau să intre în conflict cu alte operaŃii de scriere concurente.
Cum se implementează modelul multiversiune? Dacă asupra bazei este executată o comandă
LMD, server-ul Oracle face o copie a datelor dinainte de modificare şi o depune în segmentul
rollback (undo).
ToŃi utilizatorii (cu excepŃia celor care modifică datele) vor vedea datele cum sunt înainte de
modificare (văd conŃinutul segmentului undo). Dacă comanda LMD este commit, atunci schimbările
din baza de date devin vizibile oricărui utilizator care foloseşte instrucŃiunea SELECT. Când se
termină tranzacŃia, spaŃiul ocupat în segmentul undo de “vechea” dată este liber pentru reutilizare.
Server-ul Oracle asigură astfel o vizualizare consistentă a datelor în orice moment.
Blocări
Blocările sunt folosite în ORACLE pentru a asigura integritatea datelor, permiŃând în acelaşi
timp accesul concurent la date de către un număr “infinit” de utilizatori.
Din punct de vedere a resursei blocate, blocările pot fi:
• la nivel de linie (blocarea afectează un rând);
• nivel de tabel (blocarea afectează întreg tabelul).
La nivel de rând, blocările se pot face numai în modul exclusiv (X), adică un utilizator nu
poate modifica un rând până ce tranzacŃia care l-a blocat nu s-a terminat (prin permanentizare sau
prin derulare înapoi).

Blocările la nivel de tabel pot fi făcute în mai multe feluri, în funcŃie de caracterul mai mult
sau mai puŃin restrictiv al blocării (RS – row share; RX – row exclusive; S – share; SRX – share row
exclusive; X – exclusive).
• Modul X de blocare la nivel de tabel este cel mai restrictiv. Blocarea în mod X este
obŃinută la executarea comenzii LOCK TABLE cu opŃiunea EXCLUSIVE. O astfel de
blocare permite altor tranzacŃii doar interogarea tabelului. Tabelul nu mai poate fi blocat
în acelaşi timp de nici o altă tranzacŃie în nici un mod.
• Modul de blocare RX arată că tranzacŃia care deŃine blocarea a făcut modificări asupra
tabelului. O blocare RX permite acces (SELECT, INSERT, UPDATE, DELETE)
concurent la tabel şi blocarea concurentă a tabelului de către altă tranzacŃie în modurile
RS şi RX.
• Modul de blocare S (se obŃine prin comanda LOCK TABLE cu opŃiunea SHARE) permite
altor tranzacŃii doar interogarea tabelului şi blocarea sa în modurile S şi RS.
• Modul de blocare SRX (se obŃine prin comanda LOCK TABLE cu opŃiunea SHARE ROW
EXCLUSIVE) permite altor tranzacŃii doar interogarea tabelului şi blocarea sa în modul
RS.
• Modul de blocare RS permite acces (SELECT, INSERT, UPDATE, DELETE) concurent
la tabel şi blocarea concurentă a tabelului de către altă tranzacŃie în orice mod, în afară de
X. Modul de blocare RS, care este cel mai puŃin restrictiv, arată că tranzacŃia care a blocat
tabelul, a blocat rânduri din tabel şi are intenŃia să le modifice.
Din punct de vedere a modului de declanşare a blocării, blocările pot fi:
• implicite (blocarea este făcută automat de sistem în urma unei operaŃii INSERT, DELETE
sau UPDATE şi nu necesită o acŃiune din partea utilizatorului);
• explicite (blocarea este declanşată ca urmare a comenzilor LOCK TABLE sau SELECT cu
clauza FOR UPDATE).
Folosirea clauzei FOR UPDATE într-o comandă SELECT determină blocarea rândurilor
selectate în modul X şi blocarea întregului tabel (sau tabelelor) pe care se face interogarea în modul
RS. La actualizarea rândurilor (UPDATE) blocarea la nivel de linie se menŃine în timp ce blocarea la
nivel de tabel devine RX.
Exemplu:
SELECT salariu
FROM salariat
WHERE cod_salariat = 1234
FOR UPDATE OF salariu;
UPDATE salariat
SET salariu = 23456
WHERE cod_salariat = 1234;
COMMIT;
La executarea primei comenzi, rândul cu cod_salariat = 1234 este blocat în mod X în timp ce
tabelul salariat este blocat în modul RS. La executarea celei de a doua comenzi, blocarea la nivel de
linie se menŃine în timp ce blocarea la nivel de tabel devine RX. La executarea comenzii COMMIT,
tranzacŃia este permanentizată şi toate blocările sunt eliberate.
Unul sau mai multe tabele, vizualizari, partitii sau subpartitii ale unor tabele pot fi blocate în
oricare din modurile prezentate mai sus folosind comanda LOCK TABLE, care are sintaxa
simplificata:
LOCK TABLE nume_tabel [, nume tabel] …
IN mod_blocare MODE [NOWAIT]
Clauza NOWAIT determină sistemul să returneze imediat controlul către utilizatorul care
încearcă să realizeze o blocare asupra unui tabel. Dacă acesta este deja blocat, atunci sistemul va
returna un mesaj corespunzător. Altfel, sistemul va aştepta până când tabelul devine disponibil, îl va
bloca şi apoi va returna controlul utilizatorului.
Blocarile obtinute in urma acestei comenzi sunt prioritare celor impuse automat de catre
sistem. Un tabel ramane blocat pana la operatia COMMIT sau ROLLBACK asupra tranzactiei sau
pana la revenirea intr-un punct intermediar (SAVEPOINT) definit inainte de blocarea tabelului.
O blocare impusa asupra unui tabel nu impiedica ceilalti utilizatori sa îl consulte. Blocarea
unei vizualizari implica blocarea tabelelor sale de bază.
Campul mod_blocare poate avea valorile ROW SHARE, ROW EXCLUSIVE, SHARE, SHARE
ROW EXCLUSIVE, EXCLUSIVE. Dacă se specifică NOWAIT şi rândurile selectate sunt deja blocate
de altă tranzacŃie, atunci utilizatorul este înştiinŃat de acest lucru, returnându-i-se controlul.
Datorită accesului concurent la date este posibil ca mai mulŃi utilizatori să se blocheze
reciproc. Această situaŃie este numită interblocare (deadlock), pentru că fiecare dintre utilizatori
aşteaptă ca celălalt să elibereze resursa blocată. În cazul acesta problema nu se poate rezolva prin
simpla aşteptare, una din tranzacŃii trebuind să fie derulată înapoi. Oracle detectează automat
interblocările. În acest caz, Oracle semnalează o eroare uneia dintre tranzacŃiile implicate şi
derulează înapoi ultima instrucŃiune din această tranzacŃie. Acest lucru rezolvă interblocarea, deşi
cealaltă tranzacŃie poate încă să aştepte până la deblocarea resursei pentru care aşteaptă.
Care din următoarele comenzi încheie o tranzacŃie?
SELECT
ROLLBACK
UPDATE
DELETE
CREATE TABLE

III. BIBLIOGRAFIE MINIMALĂ OBLIGATORIE

1. Ileana Popescu, LetiŃia Velcescu, Neprocedural ORACLE 10G, SQL, Editura UniversităŃii din
Bucureşti, 2008
2. Mariana Popa, Baze de date (Fundamente, exemple, teste de verificare), Editura FRM, 2006
3. Marin Fotache, Catalin Strambei, Liviu Cretu, ORACLE 9i2, Editura Polirom, 2003
4. http://www.oracle.com/index.html/ → situl oficial ORACLE

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

  • Probleme Curent Electric
    Probleme Curent Electric
    Document6 pagini
    Probleme Curent Electric
    Oana Roxana Stratulat Potirniche
    Încă nu există evaluări
  • Respiratie Teste
    Respiratie Teste
    Document4 pagini
    Respiratie Teste
    Oana Roxana Stratulat Potirniche
    100% (1)
  • CURSUL 4 Semiologie Cutanata
    CURSUL 4 Semiologie Cutanata
    Document9 pagini
    CURSUL 4 Semiologie Cutanata
    Oana Roxana Stratulat Potirniche
    Încă nu există evaluări
  • Cursul 5 - Respirator
    Cursul 5 - Respirator
    Document10 pagini
    Cursul 5 - Respirator
    Oana Roxana Stratulat Potirniche
    Încă nu există evaluări
  • Cursul 2 - Neurologie
    Cursul 2 - Neurologie
    Document9 pagini
    Cursul 2 - Neurologie
    Oana Roxana Stratulat Potirniche
    Încă nu există evaluări
  • Teste Anatomie
    Teste Anatomie
    Document2 pagini
    Teste Anatomie
    Oana Roxana Stratulat Potirniche
    Încă nu există evaluări
  • MP2
    MP2
    Document6 pagini
    MP2
    Oana Roxana Stratulat Potirniche
    Încă nu există evaluări
  • CURSUL 1 - Anatomia SN
    CURSUL 1 - Anatomia SN
    Document4 pagini
    CURSUL 1 - Anatomia SN
    Oana Roxana Stratulat Potirniche
    Încă nu există evaluări
  • Tensin HDC S
    Tensin HDC S
    Document7 pagini
    Tensin HDC S
    Oana Roxana Stratulat Potirniche
    Încă nu există evaluări
  • CDD in HDC S
    CDD in HDC S
    Document10 pagini
    CDD in HDC S
    Oana Roxana Stratulat Potirniche
    Încă nu există evaluări
  • Biomecanica-Curs 1
    Biomecanica-Curs 1
    Document2 pagini
    Biomecanica-Curs 1
    Oana Roxana Stratulat Potirniche
    Încă nu există evaluări
  • Nevoia de A Comunica
    Nevoia de A Comunica
    Document11 pagini
    Nevoia de A Comunica
    Oana Roxana Stratulat Potirniche
    Încă nu există evaluări
  • Fisa Lucru Potirniche Oana Roxana
    Fisa Lucru Potirniche Oana Roxana
    Document2 pagini
    Fisa Lucru Potirniche Oana Roxana
    Oana Roxana Stratulat Potirniche
    Încă nu există evaluări