Sunteți pe pagina 1din 76

UNIVERSITATEA SPIRU HARET

FACULTATEA DE INGINERIE, INFORMATICĂ ȘI GEOGRAFIE

Baze de date
Conf. univ. dr. Nicoleta IACOB

Cuprins

Baze de date ............................................................................................................................................ 1

1. Noţiuni introductive în teoria bazelor de date ..................................................................................... 5

1.1. Noțiunile de bază de date, sistem de gestiune a bazei de date................................................. 5

1.2. Noțiunile de entitate, relație, atribut ........................................................................................ 5

1.3. Construirea de diagrame entitate-relaţie.................................................................................. 7

1.4. Tipuri de relații între entităţi.................................................................................................... 8

2. Baze de date relaţionale....................................................................................................................... 8

2.1. Noțiunile de bază de date relaţională, sistem de gestiune a bazelor de date relaţionale............... 8

2.2. Regulile lui Codd.......................................................................................................................... 9

2.3. Componentele bazelor de date relaționale:................................................................................. 10

1) Structura relaţională a datelor................................................................................................ 11

2) Operatorii modelului relaţional ............................................................................................. 11

3) Restricţii de integritate ale modelului relaţional ................................................................... 13

2.4. Tipuri de constrângeri de integritate........................................................................................... 14

3. Proiectarea bazelor de date relaţionale .............................................................................................. 14

3.1. Formele normale: FN1; FN2; FN3 ............................................................................................. 15

4. Limbajul SQL (Structured Query Language) .................................................................................... 21

4.1. Structura lexicală a limbajului SQL ...................................................................................... 21

4.2. Operatori SQL ....................................................................................................................... 21

4.3. Funcţii definite în SQL .......................................................................................................... 22

4.4. Tipuri de date......................................................................................................................... 23

1
4.5. Categorii de instrucţiuni SQL................................................................................................ 24

5. Limbajul de definire a datelor (LDD) ............................................................................................... 24

5.1. Comenzi (CREATE, ALTER, DROP) ....................................................................................... 25

6. Limbajul de manipulare a datelor (LMD) ......................................................................................... 29

6.1. Interogarea datelor (Comanda SELECT) ................................................................................... 30

6.2. Adăugarea de noi tupluri (Comanda INSERT) .......................................................................... 39

6.3. Modificarea tuplurilor din tabele (Comanda UPDATE) ............................................................ 42

6.4. Ştergerea tuplurilor din tabele (Comanda DELETE) ................................................................. 44

7. Limbajul de control al datelor (LCD)................................................................................................ 45

7.1. Asigurarea confidențialității și securității datelor....................................................................... 46

7.2. Reluarea unor acțiuni în cazul unei defecțiuni ........................................................................... 46

7.3. Garantarea coerenței datelor în cazul prelucrării concurente ..................................................... 47

8. Exerciţii de fixare a noţiunilor........................................................................................................... 49

Procedura de instalare Oracle XE (Oracle Database 11g Express Edition) și Apex (Oracle
Application Express) pe Windows .................................................................................................... 49

Crearea unui user............................................................................................................................... 51

APLICAȚII REZOLVATE ............................................................................................................... 52

DDL (Data Definition Language) ..................................................................................................... 52

Crearea tabelelor ............................................................................................................................... 52

Schema curenta ................................................................................................................................. 54

Adaugarea constrangerilor ................................................................................................................ 54

DML (Data Manipulation Language): INSERT, UPDATE, DELETE ............................................. 55

Introducerea valorilor in tabele ......................................................................................................... 55

Inserare de valori folosind variabile de substitutie - ampersand unic (&)........................................ 55

Crearea unui script pentru manipularea datelor................................................................................. 56

Copierea inregistrarilor dintr-un alt tabel .......................................................................................... 56

Modificarea tabelelor ........................................................................................................................ 57

Tipuri de constrangeri ....................................................................................................................... 57

Instructiunnea SELECT .................................................................................................................... 57

2
Tipuri de operatori:............................................................................................................................ 58

Definirea alias-urilor pentru coloane ................................................................................................. 58

Functia generala nvl .......................................................................................................................... 58

Operatorul de concatenare (||)............................................................................................................ 58

Randuri duplicate .............................................................................................................................. 58

Eliminarea randurilor duplicate ......................................................................................................... 58

Ordonarea inregsitrarilor ................................................................................................................... 58

Sortarea dupa aliasul numelui coloanei ............................................................................................. 59

Sortarea dupa pozitia coloanei .......................................................................................................... 59

Clauza WHERE................................................................................................................................. 59

Negarea comparatiei .......................................................................................................................... 60

Conditii multiple ............................................................................................................................... 60

Functii de tip caracter ........................................................................................................................ 61

Functii de tip numeric: ...................................................................................................................... 62

Functii de tip data calendaristica ....................................................................................................... 62

Functii de conversie........................................................................................................................... 63

Functii care accepta orice tip de tip de date ...................................................................................... 63

Functii de grup .................................................................................................................................. 64

Instructiunea CASE ........................................................................................................................... 64

Gruparea datelor ................................................................................................................................ 65

Interogari din mai multe tabele ......................................................................................................... 65

Selectii din mai multe tabele folosind alias-uri la tabele ................................................................... 65

Subinterogari ..................................................................................................................................... 66

Interogarea datelor din mai multe relatii folosind tipuri de asocieri ................................................. 68

Modificarea tuplurilor din tabele (comanda UPDATE) .................................................................... 69

Comanda DELETE............................................................................................................................ 70

Stergerea inregistrarilor folosind valori dintr-un alt tabel ................................................................. 70

Procesarea tranzactiilor ..................................................................................................................... 71

Folosirea atributului %type ............................................................................................................... 72


3
Variabile de legatura ......................................................................................................................... 72

Crearea si stergerea vederilor/vizualizarilor...................................................................................... 73

Definirea generatorului de numere de secventa ................................................................................ 74

Index .................................................................................................................................................. 74

Sinonim ............................................................................................................................................. 75

Operatii pe tabele structurate arborescent ......................................................................................... 75

APLICATII PROPUSE ..................................................................................................................... 75

Bibliografie............................................................................................................................................ 76

4
1. Noţiuni introductive în teoria bazelor de date
1.1. Noțiunile de bază de date, sistem de gestiune a bazei de date

O bază de date (BD):


• reprezintă un ansamblu structurat de fişiere care grupează datele prelucrate în aplicaţii
informatice ale unei persoane, grup de persoane, instituţii etc.;
• este definită ca o colecţie de date aflate în interdependenţă, împreună cu descrierea datelor şi a
relaţiilor dintre ele.

Sistemul de gestiune a bazei de date (SGBD) este:


• un sistem complex de programe care asigură interfaţa între o bază de date şi utilizatorii
acesteia;
• software-ul bazei de date care asigură:
o definirea structurii bazei de date;
o încărcarea datelor în baza de date;
o accesul la baza de date (interogare, actualizare);
o întreţinerea bazei de date (refolosirea spaţiilor goale, refacerea bazei de date în cazul
unor incidente);
o reorganizarea bazei de date (restructurarea şi modificarea strategiei de acces);
o securitatea datelor.

1.2. Noțiunile de entitate, relație, atribut

Cele trei concepte de bază utilizate în organizarea bazei de date sunt:


• entitatea;
• atributul;
• valoarea.

Prin entitate se înţelege un obiect concret sau abstract reprezentat prin proprietăţile sale. O proprietate
a unui obiect poate fi exprimată prin perechea (ATRIBUT, VALOARE).

Entitatea poate fi persoană, loc, concept, activitate etc. Prin urmare, ea poate fi un obiect cu existenţă
fizică, reală sau poate fi un obiect cu existenţă conceptuală, abstractă.

Exemplu: În exemplul “Produsul X are culoarea Y”, atributul este „culoarea”, iar valoarea este
reprezentată litera„Y”.

O entitate poate fi:


• dependentă (slabă), existenţa sa depinzând de altă entitate;
• independentă (tare), caz în care ea nu depinde de existenţa altei entităţi.

Observaţii privind entitățile:


• entităţile devin tabele în modelele relaţionale;
• în general, entităţile se scriu cu litere mari;
• entităţile sunt substantive, dar nu orice substantiv este o entitate. Trebuie ignorate
substantivele nerelevante;
• cheia primară identifică unic o entitate şi face distincţie între valori diferite ale entităţii.
Aceasta trebuie să fie unică şi cunoscută la orice moment. Cheia primară trebuie să fie
controlată de administratorul bazei, să nu conţină informaţii descriptive, să fie simplă, fără

5
ambiguităţi, să fie stabilă, să fie familiară utilizatorului astfel încât acesta să o poată folosi
cu uşurinţă;
• pentru fiecare entitate este obligatoriu să se dea o descriere detaliată;
• nu pot exista, în aceeaşi diagramă, două entităţi cu acelaşi nume, sau o aceeaşi entitate cu
nume diferite.

Relaţia este o comunicare între două sau mai multe entităţi. Gradul unei relaţii este dat de numărul de
entităţi participante într-o relaţie (de exemplu, relaţie binară, ternară, cvadruplă, n-ară).
Existenţa unei relaţii este subordonată existenţei entităţilor pe care le leagă.

O relaţie în care aceeaşi entitate participă mai mult decât o dată în diferite roluri defineşte o relaţie
recursivă. Uneori, aceste relaţii sunt numite unare.

Observaţii privind relațiile:


• în modelul relaţional, relaţiile devin tabele speciale sau coloane speciale care referă chei
primare;
• relaţiile sunt verbe, dar nu orice verb este o relaţie;
• pentru fiecare relaţie este important să se dea o descriere detaliată;
• într-o relaţie, tuplurile trebuie să fie distincte;
• în aceeaşi diagramă pot exista relaţii diferite cu acelaşi nume. În acest caz, ele sunt diferenţiate
de către entităţile care sunt asociate prin relaţia respectivă;
• cardinalul relaţiei este numărul tuplurilor dintr-o relaţie. Pentru fiecare relaţie trebuie stabilită
cardinalitatea (maximă şi minimă) relaţiei.

Asupra entităţilor participante într-o relaţie pot fi impuse constrângeri care trebuie să reflecte
restricţiile care există în lumea reală asupra relaţiilor. O clasă de constrângeri, numite constrângeri de
cardinalitate, este definită de numărul de înregistrări posibile pentru fiecare entitate participantă (raport
de cardinalitate). Cel mai întâlnit tip de relaţii este cel binar, iar în acest caz rapoartele de cardinalitate
sunt, în general, one-to-one (1:1), one-to-many (1:M) sau many-to-many (N:M).
• 1:1 - legătura de tip “una-la-una” (one-to-one) - este asocierea prin care unui element
(entitate) din mulţimea E1 îi corespunde un singur element din mulţimea E2 şi reciproc;
• 1:M – legătura de tip “una-la-multe” (one-to-many) - este asocierea prin care unui element
din mulţimea E1 îi corespund unul sau mai multe elemente din mulţimea E2, dar unui
element din E2 îi corespunde un singur element în mulţimea E1;
• N:M - legătura de tip “multe-la-multe” (many-to-many) - este asocierea prin care unui
element din mulţimea E1 îi corespund unul sau mai multe elemente din mulţimea E2 şi
reciproc.

O relaţie se poate memora printr-un tabel de forma:

R A1 ... Aj .. Am
r1 a11 ... a1j ... a1m
... ... ... ... ... ...
ri ai1 ... aij ... aim
... ... ... ... ... ...
rn an1 ... anj ... anm

6
unde liniile din acest tabel formează elementele relaţiei, sau tupluri, înregistrări, care în general sunt
distincte, coloanele A1, A2, ..., Am formează o mulţime de atribute, iar a11, …, anm sunt valoari pentru
fiecare din atributele A1, Am.

Atributul este o proprietate descriptivă a unei entităţi sau a unei relaţii (de exemplu, denumire,
unitate_de_masura a unui produs, sunt atribute ale entităţii PRODUS).

Atributele pot fi:


• simple (de exemplu, prețul unitar al unui produs);
• compuse (de exemplu, denumirea produsului);
• cu valori multiple (de exemplu, limbile în care este tradus un produs);
• derivate (de exemplu, numărul de zile rămase pănă la expirare se obţine din data expirării).

Atributele sunt utile atunci când într-o relaţie un domeniu apare de mai multe ori. Prin numele dat
fiecărei coloane (atribut), se diferenţiază coloanele care conţin valori ale aceluiaşi domeniu, eliminând
dependenţa faţă de ordine.

Observaţii privind atributele:


• atributul reprezintă coloana unei tabele de date, caracterizată printr-un nume;
• trebuie făcută distincţie între atribut, care uzual devine coloană în modelele relaţionale şi
valoarea acestuia, care devine valoare în coloane;
• atributele sunt substantive, dar nu orice substantiv este atribut;
• fiecărui atribut trebuie să i se dea o descriere completă în specificaţiile modelului (exemple,
contraexemple, caracteristici);
• pentru fiecare atribut trebuie specificat numele, tipul fizic (integer, float, char etc.), valori
posibile, valori implicite, reguli de validare, constrângeri, tipuri compuse;
• atributele pot caracteriza o clasă de entităţi, nu doar o entitate.

1.3. Construirea de diagrame entitate-relaţie

Prin tehnica entiate-relaţie (denumită şi entitate-asociere) se construieşte o diagramă entiate-relaţie


(notată E-R) prin parcurgerea următorilor paşi:
a) identificarea entităţilor (componentelor) din sistemul proiectului;
b) identificarea asocierilor (relaţiilor) dintre entităţi şi calificarea lor;
c) identificarea atributelor corespunzătoare entităţilor;
d) stabilirea atributelor de identificare a entităţilor.

a) Identificarea entităţilor. Prin convenţie, entităţile sunt substantive, se scriu cu litere mari şi se
reprezintă prin dreptunghiuri. Într-o diagramă nu pot exista două entităţi cu acelaşi nume, sau o
aceeaşi entitate cu nume diferite.

b) Identificarea asocierilor dintre entităţi şi calificarea lor. Între majoritatea componentelor (adică a
entităţilor) unui sistem economic se stabilesc legături (asocieri).

Observaţii privind diagramele entitate-relaţie:


• legăturile se reprezintă prin arce neorientate între entităţi;
• fiecărei legături i se acordă un nume plasat la mijlocul arcului şi simbolizat printr-un romb
(semnificaţia legăturii);
• numerele simbolizate deasupra arcelor se numesc cardinalităţi şi reprezintă tipul legăturii;
• cardinalitatea asocierilor exprimă numărul minim şi maxim de realizări ale unei entităţi cu
cealaltă entitate asociată. Maximele unei cardinalităţi sunt cunoscute şi sub denumirea de
7
grad de asociere, iar minimele unei cardinalităţi reprezintă obligativitatea participării
entităţilor la asociere.

1.4. Tipuri de relații între entităţi

Asocierea dintre entităţi se face în funcţie de:


• cardinalitatea asocierii. În funcţie de maxima cardinalităţii (gradul de asociere), se cunosc trei
tipuri de asocieri:
o una-la-una (1-1 sau one to one);
o una-la-multe (1-M sau one to many);
o multe-la-multe (N-M sau many to many).
• numărul de entităţi distincte care participă la asociere. Se cunosc trei tipuri de asocieri:
o binare (între două entităţi distincte);
o recursive (asocieri ale entităţilor cu ele însele);
o complexe (între mai mult de două entităţi distincte).

c) Identificarea atributelor entităţilor şi a asocierilor dintre entităţi. Atributele unei entităţi reprezintă
proprietăţi ale acestora. Atributele sunt substantive, iar pentru fiecare atribut i se va preciza tipul fizic
(integer, float, char, string etc.)

d) Stabilirea atributelor de identificare a entităţilor. Un atribut de identificare (numit cheie primară),


reprezintă un atribut care se caracterizează prin unicitatea valorii sale pentru fiecare instanţă a entităţii.

În cadrul diagramei entitate-asociere, un atribut de identificare se marchează prin subliniere sau prin
marcarea cu simbolul # plasat la sfârşitul numelui acestuia.

Pentru ca un atribut să fie atribut de identificare, acesta trebuie să satisfacă unele cerinţe:
• oferă o identificare unică în cadrul entităţii;
• este uşor de utilizat;
• este scurt (de cele mai multe ori, atributul de identificare apare şi în alte entităţi, drept cheie
externă).

Pentru o entitate pot exista mai multe atribute de identificare, numite atribute (chei) candidate. Dacă
există mai mulţi candidaţi cheie, se va selecta unul, preferându-se acela cu valori mai scurte şi mai
puţin volatile.

2. Baze de date relaţionale


2.1. Noțiunile de bază de date relaţională, sistem de gestiune a bazelor de date relaţionale

O bază de date relaţională (BDR) reprezintă un ansamblu de relaţii, prin care se reprezintă datele şi
legăturile dintre ele.

În cadrul bazei de date relaţionale, datele sunt organizate sub forma unor tablouri bidimensionale
(tabele) de date, numite relaţii. Asocierile dintre relaţii se reprezintă prin atributele de legătură. În
cazul legăturilor de tip „una-la-multe”, aceste atribute figurează într-una dintre relaţiile implicate în
asociere. În cazul legăturilor de tip „multe-la-multe”, atributele sunt situate într-o relaţie distinctă,
construită special pentru explicarea legăturilor între relaţii.

8
Prin sistem de gestiune a bazelor de date relaţionale (SGBDR) se înţelege un SGBD care utilizează
drept concepţie de organizare a datelor modelul relaţional.

Definirea unui SGBDR impune o detaliere a caracteristicilor pe care trebuie să le prezinte un SGBD
pentru a putea fi considerat relaţional. În acest sens, Codd a formulat (în 1985) 13 reguli, care exprimă
cerinţele pe care trebuie să le satisfacă un SGBD.

2.2. Regulile lui Codd

Regulile lui Codd pentru SGBD-urile relaţionale:


R0: Gestionarea datelor la nivel de relaţie. Sistemul trebuie să gestioneze BD numai prin mecanisme
relaţionale.

R1: Reprezentarea logică a datelor. Într-o bază de date relaţionată, informaţia este reprezentată la nivel
logic sub forma unor tabele (relaţii). Acest lucru înseamnă că toate datele trebuie să fie memorate şi
prelucrate în acelaşi mod.

R2: Garantarea accesului la date. Orice dată din baza de date relaţionată trebuie să poată fi accesată
prin specificarea numelui relaţiei (tabelei), a valorii cheii primare și numelui atributului (coloană).

R3: Valorile nule:


• sistemul trebuie să permită declararea şi manipularea sistematică a valorilor NULL (semnifică
lipsa unor date);
• valorile NULL diferă de şirurile de caractere „spaţiu”, şirurile vide de caractere.
• valorile NULL sunt deosebit de importante în implementarea restricţiilor de integritate:
integritatea entităţilor; integritatea referenţială.

R4: Metadatele. Utilizatorii autorizaţi trebuie să poată aplica asupra descrierii bazei de date aceleaşi
operaţii ca şi asupra datelor obişnuite.

R5: Facilităţile limbajelor utilizate:


• trebuie să existe cel puţin un limbaj care să exprime oricare din următoarele operaţii:
o definirea relaţiilor;
o să vizualizeze datele;
o să regăsească informaţia;
o să poată reactualiza informaţia;
o să verifice şi să corecteze datele de intrare etc.
• în general, toate implementările SQL respectă această regulă.

R6: Actualizarea tabelelor virtuale:


• toate tabelele/relaţiile virtuale trebuie să poată fi actualizate;
• nu toate tabelele virtuale sunt teoretic actualizate.

Exemplu: Fie tabela de bază PRODUS, cu următoarea schemă PRODUS (Denumire_produs:D1,


Cantitate:D2, Pret_unitar:D3), cu ajutorul tabelei PRODUS este definită o tabelă virtuală FACTURA,
cu schema: FACTURA (Denumire_produs:D1, Cantitate:D2, Pret_unitar:D3, Valoare:D4). Valorile
atributului „Valoare” se calculează astfel:
Valoare=Cantitate*Pret_unitar

9
Presupunem că se doreşte schimbarea preţului unitar la un anumit produs, această schimbare trebuie
efectuată în tabela de bază PRODUS, atributul „Pret_unitar” din tabela virtuală FACTURA, fiind
actualizabil, întrucât actualizarea se poate propaga spre tabela de bază.

Presupunem că se doreşte schimbarea valorii (Valoare) la un anumit produs:


 modificarea de la tabela virtuală spre tabela de bază nu mai este posibilă, atributul „Valoare”
nu este actualizabil, deoarece schimbarea valorii (Valoare) se poate datora schimbării
cantităţii (Cantitate) şi/sau a preţului unitar (Pret_unirar);
 astfel trebuie să existe un mecanism prin care să se poată determina dacă anumite vizualizări
pot fi modificate sau nu.

Majoritatea implementărilor SQL îndeplinesc această cerinţă.

R7: Actualizările în baza de date (inserările, modificările şi ştergerile din baza de date):
• un SGBDR nu trebuie să oblige utilizatorul să caute într-o relaţie, tuplu cu tuplu, pentru a
regăsi informaţia dorită;
• această regulă exprimă cerinţa ca în operaţiile prin care se schimbă conţinutul bazei de date să
se lucreze la un moment dat pe o întreagă relaţie.

R8: Independenţa fizică a datelor:


• o schimbare a structurii fizice a datelor nu trebuie să blocheze funcţionarea programelor de
aplicaţii;
• într-un SGBDR trebuie să se separe aspectul fizic al datelor (stocare sau acces la date) de
aspectul logic al datelor.

R9: Independenţa logică a datelor. Schimbarea relaţiilor bazei de date nu trebuie să afecteze
programele de aplicaţie.

R10: Restricţiile de integritate. Restricţiile de integritate trebuie să fie definite într-un limbaj
relaţional, nu în programul de aplicaţie.

R11: Distribuirea geografică a datelor. Distribuirea datelor pe mai multe calculatoare dintr-o reţea de
comunicaţii de date nu trebuie să afecteze programele de aplicaţie.

R12: Prelucrarea datelor la nivelul de bază. Dacă sistemul posedă un limbaj de bază orientat pe
prelucrarea de tupluri şi nu pe prelucrarea relaţiilor, acest limbaj nu trebuie să fie utilizat pentru a evita
restricţiile de integritate (se introduc inconsistenţe).

Clasificarea regulilor lui Codd


În funcţie de tipul de cerinţe pe care le exprimă, regulile sunt grupate în 5 categorii:
1) reguli de bază: R0 şi R12;
2) reguli structurale: R1 şi R6;
3) reguli privind integritatea datelor: R3 şi R10;
4) reguli privind manipularea datelor: R2, R4, R5, R7;
5) reguli privind independenţa datelor: R8, R9, R11.

2.3. Componentele bazelor de date relaționale:

Orice model de date, conform unei sugestii a lui Codd, trebuie să se bazeze pe trei componente:
1) structurile de date. O bază de date relaţională (BDR) reprezintă un ansamblu de relaţii, prin
care se reprezintă date şi legăturile dintre ele. Structurile sunt definite de un limbaj de definire
10
a datelor (Data Definition Language). Datele în modelul relațional sunt structurate în relații
(tabele) bidimensionale;
2) operatorii de manipulare a datelor. Relațiile pot fi manipulate utilizând un limbaj de
manipularea datelor (Data Manipulation Language). În modelul relațional, limbajul folosește
operatori relaționali bazați pe conceptul algebrei relaționale. În afară de acesta, există limbaje
echivalente algebrei relaționale, cum ar fi calculul relațional orientat pe tuplu și calculul
relațional orientat pe domeniu;
3) constrângerile de integritate. Prin integritatea datelor se subînțelege că datele rămân stabile, în
siguranță și corecte. Integritatea în modelul relațional este menținută de constrângeri interne
care nu sunt cunoscute utilizatorului.

1) Structura relaţională a datelor


Prezentarea structurii relaţionale a datelor impune definirea noţiunilor de: domeniu, tabelă (relaţie),
atribut, tuplu, cheie şi schema tabelei.

Domeniul este un ansamblu de valori caracterizat printr-un nume. El poate fi explicit sau implicit.

Tabela/relaţia este un subansamblu al produsului cartezian al mai multor domenii, caracterizat printr-
un nume, prin care se definesc atributele ce aparţin aceleaşi clase de entităţi.

Atributul este coloana unei tabele, caracterizată printr-un nume.

Cheia este un atribut sau un ansamblu de atribute care au rolul de a identifica un tuplu dintr-o tabelă.
Tipuri de chei: primare/alternate, simple/comune, externe.

Tuplul este linia dintr-o tabelă şi nu are nume. Ordinea liniilor (tuplurilor) şi coloanelor (atributelor)
dintr-o tabelă nu trebuie să prezinte nici-o importanţă.

Schema tabelei este formată din numele tabelei, urmat între paranteze rotunde de lista atributelor, iar
pentru fiecare atribut se precizează domeniul asociat.

Schema bazei de date poate fi reprezentată printr-o diagramă de structură în care sunt puse în evidenţă
şi legăturile dintre tabele. Definirea legăturilor dintre tabele se face logic construind asocieri între
tabele cu ajutorul unor atribute de legătură. Atributele implicate în realizarea legăturilor se găsesc fie
în tabelele asociate, fie în tabele distincte construite special pentru legături. Atributul din tabela iniţială
se numeşte cheie externă, iar cel din tabela finală este cheie primară. Legăturile posibile sunt 1:1,
1:M, N:M. Potenţial, orice tabelă se poate lega cu orice tabelă, după orice atribute.

Legăturile se stabilesc la momentul descrierii datelor prin limbaje de descriere a datelor (LDD), cu
ajutorul restricţiilor de integritate. Practic, se stabilesc şi legături dinamice la momentul execuţiei.

2) Operatorii modelului relaţional


Operatorii modelului relaţional sunt operatorii din:
a) algebra relaţională;
b) calcul relaţional: orientat pe tuplu; orientat pe domeniu

a) Algebra relaţională este o colecţie de operaţii formale aplicate asupra tabelelor (relaţiilor), şi a
fost concepută de E.F. Codd. Operaţiile sunt aplicate în expresiile algebrice relaţionale care sunt
cereri de regăsire. Acestea sunt compuse din operatorii relaţionali şi operanzi. Operanzii sunt
întotdeauna tabele (una sau mai multe). Rezultatul evaluării unei expresii relaţionale este format
dintr-o singură tabelă.
11
Algebra relaţională are cel puţin puterea de regăsire a calcului relaţional. O expresie din calculul
relaţional se poate transforma într-una echivalentă din algebra relaţională şi invers.

Codd a introdus 6 operatori de bază (reuniunea, diferenţa, produsul cartezian, selecţia, proiecţia,
joncţiunea) şi 2 operatori derivaţi (intersecţia şi diviziunea). Ulterior au fost introduşi şi alţi operatori
derivaţi (speciali). În acest context, operatorii din algebra relaţională pot fi grupaţi în două categorii:
operatori pe mulţimi şi operatori speciali.
Fie R1, R2, R3 - relaţii (tabele).

Operatorii pe mulţimi sunt:


• reuniunea. R3 = R1 ∪ R2, unde R3 va conţine tupluri din R1 sau R2 luate o singură dată;
• diferenţa. R3 = R1 \ R2, unde R3 va conţine tupluri din R1 care nu se regăsesc în R2;
• produsul cartezian. R3 = R1 × R2, unde R3 va conţine tupluri construite din perechi (x1,x2),
cu x1∈R1 şi x2∈R2;
• intersecţia. R3 = R1 ∩ R2, unde R3 va conţine tupluri care se găsesc în R1 şi R2 în acelaşi
timp etc.

Operatorii relaţionali speciali sunt:


• selecţia. Din R1 se obţine o subtabelă R2, care va conţine o submulţime din tuplurile iniţiale
din R1 ce satisfac un predicat (o condiţie). Numărul de atribute din R2 este egal cu
numărul de atribute din R1. Numărul de tupluri din R2 este mai mic decât numărul de
tupluri din R1;
• proiecţia. Din R1 se obţine o subtabelă R2, care va conţine o submulţime din atributele iniţiale
din R1 şi fără tupluri duplicate. Numărul de atribute din R2 este mai mic decât numărul de
atribute din R1;
• joncţiunea este o derivaţie a produsului cartezian, ce presupune utilizarea unui calificator care
să permită compararea valorilor unor atribute din R1 şi R2, iar rezultatul în R3. R1 şi R2
trebuie să aibă unul sau mai multe atribute comune care au valori comune.

b) Calculul relaţional se bazează pe calculul predicatelor de ordinul întâi şi a fost propus de E.F.
Codd. Predicatul este o relaţie care se stabileşte între anumite elemente şi care poate fi confirmată sau
nu. Predicatul de ordinul 1 este o relaţie care are drept argumente variabile care nu sunt predicate.
Variabila poate fi de tip tuplu (valorile sunt dintr-un tuplu al unei tabele) sau domeniu (valorile sunt
dintr-un domeniu al unei tabele). Cuantificatorii (operatorii) utilizaţi în calculul relaţional sunt:
universal (∀) şi existenţial (∃).

Construcţia de bază în calculul relaţional este expresia relaţională de calcul tuplu sau domeniu.

Expresia relaţională de calcul este formată din:


• operaţia de efectuat;
• variabile (tuplu respectiv domeniu);
• condiţii (de comparaţie, de existenţă);
• formule bine definite (operanzi-constante, variabile, funcţii, predicate, operatori);
• cuantificatori.

Pentru implementarea acestor operatori există comenzi specifice în limbajele de manipulare a datelor
(LMD) din sistemele de gestiune a bazelor de date relaţionale (SGBDR). Aceste comenzi sunt utilizate
în operaţii de regăsire (interogare).

12
După tehnica folosită la manipulare, LMD sunt bazate pe:
• calculul relaţional (QUEL în Ingres, ALPHA propus de Codd);
• algebra relaţională (ISBL, RDMS);
• transformare (SQL, SQUARE);
• grafică (QBE, QBF).

Transformarea oferă o putere de regăsire echivalentă cu cea din calculul şi algebra relaţională. Se
bazează pe transformarea (mapping) unui atribut sau grup de atribute într-un atribut dorit prin
intermediul unor relaţii. Rezultatul este o relaţie (tabelă) care se poate utiliza într-o altă transformare.

Grafica oferă interactivitate mare pentru construirea cererilor de regăsire. Utilizatorul specifică cererea
alegând sau completând un ecran structurat grafic. Poate fi folosită de către toate categoriile de
utilizatori în informatică.

Algebra relaţională este prin definiţie neprocedurală (descriptivă), iar calculul relaţional permite o
manieră de căutare mixtă (procedurală/neprocedurală).

3) Restricţii de integritate ale modelului relaţional


Restricţiile de integritate ale modelului relaţional reprezintă cerinţe pe care trebuie să le îndeplinească
datele din cadrul bazei de date pentru a putea fi considerate corecte şi coerente în raport cu lumea reală
pe care o reflectă. Dacă o bază de date nu respectă aceste cerinţe, ea nu poate fi utilizată cu un maxim
de eficienţă.

Restricţiile sunt de două tipuri: restricţii de integritate structurală și restricţii de integritate de


comportament.

Restricţii de integritate structurale, care se definesc prin egalitatea sau inegalitatea unor valori din
cadrul relaţiilor. Acestea sunt:
• restricţia de unicitate a cheii - cheia primară trebuie să fie unică și minimală;
• restricţia de integritate a referirii. Într-o tabelă t1 care referă o tabelă t2, valorile cheii externe
trebuie să figureze printre valorile cheii primare din t2 sau să ia valoarea NULL
(neprecizat);
• restricţia de integritate a entităţii. Într-o tabelă, atributele din cheia primară nu trebuie să ia
valoarea NULL.

Cele trei restricţii de mai sus sunt minimale.

Pe lângă acestea, există o serie de alte restricţii structurale care se referă la dependenţele dintre date:
funcţionale, multivaloare, joncţiune etc. (sunt luate în considerare la tehnicile de proiectare a bazelor
de date relaţionale - BDR).

Restricţii de integritate de comportament - sunt cele care se definesc prin comportamentul datelor şi
ţin cont de valorile din BDR. Acestea sunt:
• restricţia de domeniu. Domeniul corespunzător unui atribut dintr-o tabelă trebuie să se
încadreze între anumite valori;
• restricţii temporale. Valorile anumitor atribute se compară cu nişte valori temporale (rezultate
din calcule etc.).

Restricţiile de comportament fiind foarte generale se gestionează fie la momentul descrierii datelor (de
exemplu prin clauza CHECK), fie în afara modelului la momentul execuţiei.

13
2.4. Tipuri de constrângeri de integritate

Restricţiile de integritate suportate de Oracle sunt:


• NOT NULL - nu permite valori NULL în coloanele unei tabele;
• UNIQUE - nu sunt permise valori duplicat în coloanele unei tabele;
• PRIMARY KEY - nu permite valori duplicate sau NULL în coloana sau coloanele definite
astfel;
• FOREIGN KEY - presupune ca fiecare valoare din coloana sau setul de coloane definit astfel
să aibă o valoare corespondentă identică în tabela de legătură, tabelă în care coloana
corespondentă este definită cu restricţia UNIQUE sau PRIMARY KEY;
• CHECK - elimină valorile care nu satisfac anumite cerinţe (condiţii) logice.

Termenul de cheie (keys) este folosit pentru definirea câtorva categorii de constrângeri, şi sunt:
PRIMARY KEY, UNIQUE KEY, FOREIGN KEY, REFERENCED KEY.

3. Proiectarea bazelor de date relaţionale


Proiectarea BDR se realizează prin proiectarea schemelor BDR şi proiectarea modulelor funcţionale
specializate.

A. Proiectarea schemelor BDR


Schemele bazei de date sunt: conceptuală, externă şi internă.

a) Proiectarea schemei conceptuale porneşte de la identificarea setului de date necesar sistemului.


Aceste date sunt apoi integrate şi structurate într-o schemă (exemplu: pentru BDR relaţionale cea mai
utilizată tehnică este normalizarea). Pentru acest lucru se parcurg paşii:
• stabilirea schemei conceptuale iniţiale - care se deduce din modelul entitate-asociere. Pentru
acest lucru, se transformă fiecare entitate din model într-o colecţie de date (fişier), iar
pentru fiecare asociere se definesc cheile aferente. Dacă rezultă colecţii izolate, acestea se
vor lega de alte colecţii prin chei rezultând asocieri (1:1, 1:M, N:M);
• ameliorarea progresivă a schemei conceptuale - prin eliminarea unor anomalii (exemplu: cele
cinci forme normale pentru BDR relaţionale);
• stabilirea schemei conceptuale finale - trebuie să asigure un echilibru între cerinţele de
actualizare şi performanţele de exploatare (exemplu: o formă normală superioară asigură
performanţe de actualizare, dar timpul de răspuns va fi mai mare).

Tehnica de normalizare
Tehnica de normalizare este utilizată în activitatea de proiectare a structurii BDR şi constă în
eliminarea unor anomalii (neajunsuri) de actualizare din structură.

Anomaliile de actualizare sunt situaţii nedorite care pot fi generate de anumite tabele în procesul
proiectării lor:
• anomalia de ştergere - stergând un tuplu dintr-o tabelă, pe lângă informaţiile care trebuie
şterse, se pierd şi informaţiile utile existente în tuplul respectiv;
• anomaliile de adăugare - nu pot fi incluse noi informaţii necesare într-o tabelă, deoarece nu se
cunosc şi alte informaţii utile (de exemplu valorile pentru cheie);
• anomalia de modificare - este dificil de modificat o valoare a unui atribut atunci când ea apare
în mai multe tupluri.

14
Normalizarea este o teorie construită în jurul conceptului de forme normale (FN), care ameliorează
structura BDR prin înlăturarea treptată a unor neajunsuri şi prin imprimarea unor facilităţi sporite
privind manipularea datelor.

Normalizarea utilizează ca metodă descompunerea (top-down) unei tabele în două sau mai multe
tabele, păstrând informaţii (atribute) de legătură.

Codd a definit iniţial 3 forme normale, notate prin FN1, FN2 şi FN3. Întrucât într-o primă formulare,
definiţia FN3 ridică ceva probleme, Codd şi Boyce au elaborat o nouă variantă, cunoscută sub numele
de Boyce-Codd Normal Form (BCNF). Astfel, BCNF este reprezentată separat în majoritatea
lucrărilor. R. Fagin a tratat cazurile FN4 şi FN5.

O relaţie este într-o formă normală dacă satisface o mulţime de constrângeri.

Normalizarea bazei de date relaţionale poate fi imaginată ca un proces prin care pornindu-se de la
relaţia iniţială/universală R se realizează descompunerea succesivă a acesteia în subrelaţii, aplicând
operatorul de proiecţie. Relaţia R poate fi ulterior reconstruită din cele n relaţii obţinute în urma
normalizării, prin operaţii de joncţiune.

3.1. Formele normale: FN1; FN2; FN3

Prima formă normală (FN1)


FN1 este strâns legată de noţiunea de atomicitate a atributelor unei relaţii. Astfel, aducerea unei relaţii
în FN1 presupune introducerea noţiunilor de:
• atribut simplu (atribut atomic) - atribut care nu mai poate fi descompus în alte atribute, în caz
contrar, atributul este compus (atribut neatomic);
• atribut compus;
• grupuri repetitive de atribute - atribut (grup de atribute) dintr-o relaţie care apare cu valori
multiple pentru o singură apariţie a cheii primare a relaţiei nenormalizate.

Aducerea unei relaţii universale în FN1


FN1 este tratată în general cu superficialitate, deoarece principala cerinţă – atomicitatea valorilor –
este uşor de îndeplinit (cel puţin la prima vedere).

Dintre toate formele normale, doar FN1 are caracter de obligativitate. Se spune că o bază de date este
normalizată dacă toate relaţiile se află măcar în FN1.

O relaţie este în FN1 dacă domeniile pe care sunt definite atributele relaţiei sunt constituite numai din
valori atomice. Un tuplu nu trebuie să conţină atribute sau grupuri de atribute repetitive.

Aducerea relaţiilor în FN1 presupune eliminarea atributelor compuse şi a celor repetitive.

Se cunosc trei soluţii pentru determinarea grupurilor repetitive:


1) eliminarea grupurilor repetitive pe orizontală (în relaţia R iniţială, în locul atributelor compuse
se trec componentele acestora, ca atribute simple);
2) eliminarea grupurilor repetitive prin adăugarea de tupluri;
3) eliminarea grupurilor repetitive prin construirea de noi relaţii.

Primele două metode generează relaţii stufoase prin duplicarea forţată a unor atribute, respectiv
tupluri, creându-se astfel redundanţe masive cu multiple anomalii de actualizare.

15
Metoda a treia presupune eliminarea grupurilor repetitive prin construirea de noi relaţii, ceea ce
generează o structură ce oferă cel mai mic volum de redundanţă.

Exemplu: Fie relaţia nenormalizată (primară) FACTURI. Să se stabilească o structură de tabele care să
permită stocarea informaţiilor conţinute în document (factură) şi obţinerea unor situaţii sintetice
privind evidenţa sumelor facturate pe produse, pe clienţi, pe anumite perioade de timp.

FACTURI

nr_factura#
data_factura
nume_client
adresa_client
telefon_client
email_client
banca_client
nr_cont_client
delegat
cod_produs
denumire_produs
unitate_de_masura
data_expirarii
cantitate
pret_unitar
valoare
valoare_tva
total_valoare_factura
total_valoare_tva
Relaţia FACTURI nenormalizată

În cazul în care o factură conţine mai multe produse, relaţia de mai sus va avea grupurile repetitive:
„cod_produs”, „denumire_produs”, „data_expirarii”, „cantitate”, „pret_unitar”, „valoare”,
„valoare_tva”.

Etapele de aducere a unei relaţii în FN1 sunt:


I. se construieşte câte o relaţie pentru fiecare grup repetitiv;
II. în schema fiecărei noi relaţii obţinute la pasul 1 se introduce şi cheia primară a relaţiei R
nenormalizată;
III. cheia primară a fiecărei noi relaţii va fi compusă din atributele chei ale relaţiei R, plus unul
sau mai multe atribute proprii.

Exemplu: Deoarece o factură poate avea unul sau mai multe produse înscrise pe aceasta, informaţiile
legate de produse vor fi separate într-o altă tabelă. Aplicând etapele de aducere în FN1, se obţin două
relaţii.

16
FACTURI LINII_FACTURI

nr_factura# nr_factura#
data_factura cod_produs#
nume_client denumire_produs
adresa_client unitate_de_masura
telefon_client data_expirarii
banca_client cantitate
nr_cont_client pret_unitar
delegat valoare
toal_valoare_factura valoare_tva
toal_valoare_tva
Relaţia FACTURI adusă în forma normală FN1

Observaţii:
• Câmpul „adresa_client” cuprinde informaţii despre judeţul, localitatea, strada şi numărul
domicililului clientului. Dacă se consideră că este de interes o evidenţă a sumelor
factorizate pe judeţe sau localităţi, se vor pune în locul câmpului „adresa_client” trei
câmpuri distincte: „judet_client”, „localitate_client”, „adresa_client”, uşurând în acest fel
interogările;
• Între tabela FACTURI şi tabela LINII_FACTURI există o relaţie de „una-la-multe”, adică
unui număr unic de factură îi pot corespunde unul sau mai multe produse care sunt
memorate ca înregistrări în tabela LINII_FACTURI. Cheia primară în această tabelă este
o cheie compusă, formată din două câmpuri: „nr_factura” şi „cod_produs”.

Însă, eliminarea grupurilor repetitive, adică aducerea unei relaţii în FN1, nu rezolvă complet problema
normalizării.

A doua formă normală (FN2)


FN2 este strâns legată de noţiunea de dependenţă funcţională (DF).

O relaţie se află în a doua formă normală (FN2) dacă:


1. se află în forma normală FN1 şi
2. fiecare atribut, care nu este cheie, este dependent de întreaga cheie primară.

Etapele de aducere a unei relaţii de la FN1 la FN2 sunt:


I. se identifică posibila cheie primară a relaţiei aflate în FN1;
II. se identifică toate dependenţele dintre atributele relaţiei, cu excepţia acelora în care sursa este
un atribut component al cheii primare;
III. se identifică toate dependenţele care au ca sursă un atribut sau subansamblu de atribute din
cheia primară;
IV. pentru fiecare atribut (sau subansamblu) al cheii de la pasul III se creează o relaţie care va
avea cheia primară atributul (subansamblul) respectiv, iar celelalte atribute vor fi cele care
apar ca destinaţie în dependenţele de la etapa III.

Exemplu: Relaţia care conţine date redundante (de exemplu, modificarea denumirii unui produs atrage
după sine modificarea în fiecare tuplu în care apare acest produs) este relaţia LINII_FACTURI. Se
observă că nu există nici o dependenţă funcţională între atributele necomponente ale cheii. În schimb,
toate atributele care nu intră în alcătuirea cheii compuse sunt dependente de aceasta, iar DF dintre
17
atributul component al cheii primare sunt: cod_produs --> denumire_produs, cod_produs -->
unitate_de_masura, data_expirarii. Ca urmare se formează încă două relaţii.

FACTURI LINII_FACTURI PRODUSE

nr_factura# nr_factura# cod_produs#


data_factura cod_produs# denumire_produs
nume_client cantitate unitate_de_masura
adresa_client pret_unitar data_expirarii
telefon_client valoare
email_client valoare_tva
banca_client
nr_cont_client
delegat
toal_valoare_factura
toal_valoare_tva
Relaţia FACTURI în a doua formă normală FN2

Chiar dacă au fost eliminate o parte din redundanţe, mai rămân şi alte redundanţe ce se vor elimina
aplicând alte forme normale.

A treia formă normală (FN3)


O relaţie este în forma normală trei (FN3) dacă:
1. se găseşte în FN2 şi
2. fiecare atribut care nu este cheie (nu participă la o cheie) depinde direct de cheia primară. A
treia regulă de normalizare cere ca toate câmpurile din tabele să fie independente între ele.

Exemplu: În relaţia FACTURI se observă că atributul „nume_client” determină în mod unic atributele
„adresa_client”, „telefon_client”, „email_client”, „banca_client” şi „nr_cont_client”. Deci pentru
atributul „nume_client” se construieşte o relaţie CLIENTI în care cheia primară va fi acest atribut, iar
celelalte atribute vor fi „adresa_client”, „telefon_client”, „email_client”, „banca_client” şi
„nr_cont_client”. Câmpurile „valoare” şi „valoare_tva” depind de câmpurile „cantitate”, „pret_unitar”,
şi de un procent fix de TVA. Fiind câmpuri ce se pot calcula în orice moment, ele vor fi eliminate din
tabelă LINII FACTURI, deoarece constituie informaţie memorată redundant.

FACTURI LINII_FACTURI PRODUSE CLIENTI

nr_factura# nr_factura# cod_produs# nume_client#


data_factura cod_produs# denumire_produs adresa_client
nume_client cantitate unitate_de_masura telefon_client
delegat pret_unitar data_expirarii email_client
toal_valoare_factura banca_client
toal_valoare_tva nr_cont_client

Relaţia FACTURI în a treia forma normală FN3

Etapele de aducere a unei relaţii de la FN2 la FN3 sunt:


I. se identifică toate atributele ce nu fac parte din cheia primară şi sunt surse ale unor dependenţe
funcţionale;
18
II. pentru aceste atribute, se construieşte câte o relaţie în care cheia primară va fi atributul
respectiv, iar celelalte atribute, destinaţiile din DF considerate;
III. din relaţia de la care s-a pornit se elimină atributele destinaţie din DF identificată la pasul I,
păstrându-se atributele surse.

Observaţii:
• Această a treia formă normală mai poate suferi o serie de rafinări pentru a putea obţine o
structură performantă de tabele ale bazei de date. De exemplu, se observă că
„nume_client” este un câmp în care este înscris un text destul de lung format dintr-o
succesiune de litere, semne speciale (punct, virgulă, cratimă), spaţii, numere. Ordonarea şi
regăsirea informaţiilor după astfel de câmpuri este lentă şi mai greoaie decât după câmpuri
numerice. Din acest motiv se poate introduce un nou atribut „cod_client” care să fie
numeric şi care să fie cheia primară de identificare pentru fiecare client;
• O altă observaţie care poate fi făcută în legătură cu tabelele aflate în cea de a treia formă
normală este aceea că „total_valoare_factura” este un câmp care ar trebui să conţină
informaţii sintetice obţinute prin însumarea valorii tuturor ofertelor aflate pe o factură.
Este de preferat ca astfel de câmpuri să fie calculate în rapoarte sau interogări şi să nu fie
memorate în tabelele bazei de date.

FACTURI LINII_FACTURI PRODUSE CLIENTI

nr_factura# nr_factura# cod_produs# cod_client#


data_factura cod_produs# denumire_produs nume_client
nume_client cantitate unitate_de_masur adresa_client
delegat pret_unitar a telefon_client
data_expirarii email_client
banca_client
nr_cont_client

Verificarea aplicării corecte a procesului de normalizare se realizează astfel încât uniunea acestor
relaţii să producă relaţia iniţială, cu alte cuvinte, descompunerea este fără pierderi.

Celelalte forme normale se întâlnesc mai rar în practică. Aceste forme nu sunt respectate, în general,
pentru că beneficiile de eficienţă pe care le aduc nu compensează costul şi munca de care este nevoie
pentru a le respecta.

Forma normală Boyce Codd (FNBC)


O definiţie mai riguroasă pentru FN3 a fost dată prin forma intermediară BCNF (Boyce Codd Normal
Form):
• o tabelă este în BCNF dacă fiecare determinant este un candidat cheie. Determinantul este un
atribut elementar sau compus faţă de care alte atribute sunt complet dependente
funcţional.

A patra formă normală (FN4)


O tabelă este în FN4 dacă şi numai dacă:
• este în FN3 şi
• nu conţine două sau mai multe dependenţe multivaloare. Într-o tabelă T, fie A, B, C trei
atribute. În tabela T se menţine dependenţa multivaloare A dacă şi numai dacă mulţimea
valorilor lui B ce corespunde unei perechi de date (A,C), depinde numai de o valoare a lui
A şi este independentă de valorile lui C.
19
A cincea formă normală (FN5) (numită şi forma normală proiecţie-uniune)
O tabelă este în FN5 dacă şi numai dacă:
• este în FN4 şi
• orice dependenţă de uniune a lui R este o consecinţă a unei chei candidat a lui R. În tabela T
(A,B,C) se menţine dependenţa joncţiune (AB,AC) dacă şi numai dacă T menţine
dependenţa multivaloare A -->> B sau C.

Fiecare dintre cele 6 forme normale este mai restrictivă ca predecesoarea sa. Astfel, de exemplu, o
schemă de relaţie aflată în forma normală trei este şi în forma normală doi, aşa cum se reprezintă în
figura de mai jos:

FN 5
FN 1 FN 3 FNBC FN 4
FN 2

Forme normale

Scopul formelor normale este acela de a elimina redundanţele din cadrul relaţiilor prin descompunerea
acestora în două sau mai multe relaţii, fără însă a pierde informaţie, ceea ce înseamnă faptul că este
posibilă, în orice moment, revenirea la relaţia originară doar pe baza relaţiilor obţinute din
descompunere.

Dependenţa multivaloare este caz particular al dependenţei joncţiune. Dependenţa funcţională este caz
particular al dependenţei multivaloare.

b) Proiectarea schemei externe are rolul de a specifica viziunea fiecărui utilizator asupra BDR. Pentru
acest lucru, din schema conceptuală se identifică datele necesare fiecărei viziuni. Datele obţinute se
structurează logic în subscheme ţinând cont de facilităţile de utilizare şi de cerinţele utilizator. Schema
externă devine operaţională prin construirea unor vizualizări (view) cu SGBD-ul şi acordarea
drepturilor de acces. Datele într-o vizualizare pot proveni din una sau mai multe colecţii şi nu ocupă
spaţiul fizic.

c) Proiectarea schemei interne presupune stabilirea structurilor de memorare fizică a datelor şi


definirea căilor de acces la date. Acestea sunt specifice fie SGBD-ului (scheme de alocare), fie
sistemului de operare. Proiectarea schemei interne înseamnă estimarea spaţiului fizic pentru BDR,
definirea unui model fizic de alocare (trebuie văzut dacă SGBD-ul permite explicit acest lucru) şi
definirea unor indecşi pentru accesul direct, după cheie, la date.

B. Proiectarea modulelor funcţionale specializate


Proiectarea modulelor funcţionale ţine cont de concepţia generală a BDR, precum şi de schemele
proiectate anterior. În acest sens, se proiectează fluxul informaţional, modulele de încărcare şi
manipulare a datelor, interfeţele specializate, integrarea elementelor proiectate cu organizarea şi
funcţionarea BDR.

20
Realizarea componentelor logice. Componentele logice ale unei BD sunt programele de aplicaţie
dezvoltate, în cea mai mare parte, în SGBD-ul ales. Programele se realizează conform modulelor
funcţionale proiectate în etapa anterioară. Componentele logice ţin cont de ieşiri, intrări, prelucrări şi
de colecţiile de date. În paralel cu dezvoltarea programelor de aplicaţii se întocmesc şi diferite
documentaţii (tehnică, de exploatare, de prezentare).

Punerea în funcţiune şi exploatarea. Se testează funcţiile BDR mai întâi cu date de test, apoi cu date
reale. Se încarcă datele în BDR şi se efectuează procedurile de manipulare, de către beneficiar cu
asistenţa proiectantului. Se definitivează documentaţiile aplicaţiei. Se intră în exploatare curentă de
către beneficiar conform documentaţiei.

Dezvoltarea sistemului. Imediat după darea în exploatare a BDR, în mod continuu, pot exista factori
perturbatori care generează schimbări în BDR. Factorii pot fi: organizatorici, datoraţi progresului
tehnic, rezultaţi din cerinţele noi ale beneficiarului, din schimbarea metodologiilor etc.

4. Limbajul SQL (Structured Query Language)


Limbajul SQL (Structured Query Language) este limbajul utilizat de majoritatea sistemelor de baze de
date relaţionale (SGBDR) pentru definirea şi manipularea datelor.

4.1. Structura lexicală a limbajului SQL

Elementele unei instrucţiuni (statement) sunt:


• cuvinte cheie (key words) - dintre care fac parte comenzile (SELECT, UPDATE, INSERT
etc), operatorii (AND, OR, NOT, LIKE), clauzele (WHERE, SET, VALUES etc);
• identificatori (identifier) - sunt elementele care denumesc tabela, coloana sau alt obiect al BD.
SQL face diferenţa între literele mari şi mici, deci este „case-sensitive”; identificatorul
care conţine ghilimele se numeşte identificator delimitat;
• constante (literali) - reprezintă şiruri de caractere (‘ ‘), numere întregi, numere reale (ex. 3.5;
4.; .001; 5e2), constanta NULL, constante de tip logic (1 pentru TRUE şi 0 pentru
FALSE);
• caractere speciale - cum ar fi (;) care semnifică terminarea comenzilor; (.) care semnifică
virgula zecimală; sau (*) care simbolizează operatorul de înmulţire.

4.2. Operatori SQL

SQL are următorii operatori:


• operatori aritmetici binari:
+
-
*
% modulo
^ ridicarea la putere
& AND orientat pe biţi
| OR orientat pe biţi
# XOR orientat pe biţi
<< deplasare la stânga
>> deplasare la dreapta

21
• operatori binari de comparaţie:
<
>
<=
>=
=
<> sau != diferit
• operatori aritmetici mari:
@ valoarea absolută
! factorial
!! factorial, operator postfix
~ NOT orientat pe biţi
• operatori de comparaţie:
A BETWEEN min AND max (compară A cu două valori: min şi max)
A IN (v1,...,vn) compară A cu o listă de valori
A IS NULL
A IS NOT NULL
A LIKE model_şir
• operatori logici:
Operatorii logici sunt legaţi prin cuvintele cheie AND, OR, NOT şi returnează o valoare
logică TRUE, FALSE sau NULL.
• operatori relaţionali:
UNION (reuniune)
INTERSECT (intersecţie)
MINUS (diferenţă)

4.3. Funcţii definite în SQL

Categorii de funcţii SQL:


• funcții pe un sigur rând (funcţii scalare) - realizează operații asupra unui singur rând și
returnează un singur rezultat pentru fiecare rând. Funcțiile pe un sigur rând cuprind
următoarele tipuri de funcții:
o funcții de tip caracter - acceptă argumente de tip caracter și întorc rezultate de tip
caracter (CHR, CONCAT, INITCAP, LOWER, LPAD, LTRIM, REPLACE, RPAD,
RTRIM, SUBSTR, UPPER etc.) sau numeric (ASCII, INSTR, LENGTH);
o funcții de tip numeric (de calcul trigonometric: sin, cos, tg, ctg etc.; de calcul al
logaritmului: ln, log, lg; de calcul al puterilor: pow; de rotunjire: floor, ceil etc.) -
acceptă argumente de tip numeric și întorc rezultate de tip numeric;
o funcții de tip dată calendaristică (ADD_MONTHS, LAST_DAY, MONTHS_
BETWEEN, NEXT_DAY, SYSDATE etc.) - acceptă argumente de tip dată
calendaristică și întorc rezultate de tip dată calendaristică cu excepția funcției
MONTH_BEETWEEN care întoarce o valoare numerică;
o funcții de conversie (TO_CHAR, TO_NUMBER, TO_DATE, CAST) - fac conversia
dintr-un tip de dată în altul;
o funcții generale: NVL, DECODE.

• funcții pe mai mutle rânduri (funcții de grup) - lucrează cu grupuri de rânduri pentru a returna
un singur rezultat pentru fiecare grup. Aceste funcții sunt cunoscute cu denumirea de
funcții de grup. Toate funcţiile de grup, mai puţin COUNT(*) ignoră valorile NULL.
Majoritatea funcţiilor de grup acceptă opţiunile: DISTINCT (determină luarea în calcul
22
numai a valorilor distincte ale rândurilor din cadrul grupului) şi ALL (este implicit și
determină luarea în calcul a tuturor valorilor grupului de rânduri).

Funcţiile agregat - calculează un rezultat din mai multe linii ale unui tabel (funcţii de totalizare):
o COUNT (furnizează numărul de linii ale unui rezultat);
o SUM (execută suma tuturor valorilor dintr-o coloană);
o MAX (returnează valoarea cea mai mare dintr-o coloană);
o MIN (returnează valoarea cea mai mică dintr-o coloană);
o AVG (calculează media valorilor dintr-o coloană).

Aceste funcţii vor fi folosite în instrucţiunea SELECT.

Funcţiile scalare - primesc unul sau mai multe argumente şi returnează valoarea calculată sau NULL
în caz de eroare. Argumentele funcţiilor pot fi constante sau valori ale atributelor specificate prin
numele coloanelor corespunzătoare.

4.4. Tipuri de date

În limbajul SQL sunt definite mai multe tipuri de date: numeric, şir de caractere, şir de biţi, dată
(calendaristică), timp.

Denumirile tipurilor de date precum şi limitele acestora diferă de la un SGBD la altul, dar în general,
sunt destul de asemănătoare.

• Tipul numeric include:


 numere întregi:
o INTEGER sau INT reprezentat pe 4 octeţi;
o SMALLINT reprezentat pe 2 octeţi;
 numere reale reprezentate în virgulă flotantă, cu diferite precizii:
o FLOAT reprezentat pe 4 octeţi;
o REAL reprezentat pe 8 octeţi;
o DOUBLE [PRECISION] reprezentat pe 8 octeţi;
 numere zecimale reprezentate cu precizia dorită:
o tipul NUMERIC sau DECIMAL, cu forma numeric[(p,s)], unde p este numărul total
de cifre afişate, iar s este numărul de cifre după punctul zecimal.

• Tipul şir de caractere


o CHARACTER (n) sau CHAR (n) definesc şiruri de caractere cu lungime fixă;
o CHARACTER VARYING sau VARCHAR (n) defineşte şirul de caractere cu
lungime variabilă.

Asemănarea dintre cele două tipuri prezentate mai sus este aceea că ambele reprezintă şiruri de
maxim n caractere, iar deosebirea este aceea că pentru şiruri cu număr de caractere mai mic ca n,
CHAR (n) completează şirul cu spaţii albe până la n caractere, iar VARCHAR (n) memorează
numai atâtea caractere câte are şirul dat.

• Tipul şiruri de biţi


o BIT(n) defineşte secvenţe de cifre binare (care pot lua valoarea 0 sau 1) de lungime
finită n;
o BIT VARYING (n) defineşte secvenţe de lungime variabilă, cu limita maximă n.

23
• Tipuri pentru data calendaristică şi timp
o DATE permite memorarea datelor calendaristice în formatul yyyy-mm-dd;
o TIME permite memorarea timpului, folosind trei câmpuri hh:mm:ss;
o TIMESTAMP(p) permite memorarea combinată a datei calendaristice şi a timpului,
cu precizia p pentru câmpul SECOND (al secundelor); valoarea implicită a lui p este
6;
o INTERVAL este utilizat pentru memorarea intervalelor de timp.

Tipurile de date sunt „case-insensitive”, deci nu ţin cont de caracterele mari sau mici.

4.5. Categorii de instrucţiuni SQL

În funcţie de tipul acţiunii pe care o realizează, instrucţiunile SQL se împart în mai multe categorii.

Datorită importanţei pe care o au comenzile componente, unele dintre aceste categorii sunt evidenţiate
ca limbaje relaționale în cadrul SQL, şi anume:
• limbajul de definire a datelor (LDD sau DDL – Data Definition Language);
• limbajul de interogare a datelor (LQD sau DQL - Data Query Language);
• limbajul de prelucrare a datelor (LMD sau DML – Data Manipulation Language);
• limbajul de control al datelor (LCD sau DCL – Data Control Language).

Pe lângă comenzile care alcătuiesc aceste limbaje, SQL cuprinde:


• instrucţiuni pentru controlul sesiunii;
• instrucţiuni pentru controlul sistemului;
• instrucţiuni SQL încapsulate.

5. Limbajul de definire a datelor (LDD)


Limbajele relaționale de definire a datelor oferă următoarele facilități utilizatorilor:
• facilități de descriere a datelor la nivel conceptual. În vederea descrierii datelor la nivel
conceptual, limbajele relaționale conțin o serie de comenzi, și anume:
o crearea unei BD (dicționarul BD): CREATE DATABASE;
o ștergerea unei BD: DROP DATABASE;
o crearea tabelelor de bază: CREATE TABLE;
o ștergerea tabelelor de bază: DROP TABLE;
o crearea de sinonime: CREATE SYNONYM;
o ștergerea sinonimelor: DROP SYNONYM;
o actualizarea structurii unei tabele: ALTER TABLE cu opțiunile ADD, MODIFY,
DROP;
o adăugarea restricțiilor de integritate: ASSERT ON. În Oracle restricțiile de integritate
sunt: NULL, CHECK, pe cheie (PRIMARY, UNIQUE, REFERENTIAL).

• facilități de descriere a datelor la nivel logic. Pentru descrierea datelor la nivel logic,
limbajele relaționale dispun de o serie de comenzi, precum:
o crearea tabelelor virtuale: CREATE VIEW;
o ștergerea tabelelor virtuale: DROP VIEW;
o acordarea drepturilor de acces la BD:
 GRANT CONNECT – conectarea la BD a unui utilizator;
 GRANT drepturi – acordarea unor drepturi de acces (pentru regăsire,
actualizare etc.).

24
o retragerea drepturilor de acces la BD:
 REVOKE drepturi – retragerea unor drepturi;
 REVOKE CONNECT – deconectarea unui utilizator de la BD.

 facilități de descriere a datelor la nivel fizic. Pentru definirea unor caracteristici legate de
organizarea la nivel fizic a datelor din baza de date, limbajele relaționale dispun de o serie
de comenzi, și anume:
o crearea indecşilor: CREATE INDEX;
o ștergerea indecşilor: DROP INDEX;
o controlul alocării spațiului fizic al BD:
 CREATE SPACE – creează un model de alocare a spațiului fizic pentru o
BD;
 ALTER SPACE – actualizează modelul de alocare a spațiului fizic;
 DROP SPACE – şterge un model de alocare a spațiului fizic.
o regruparea fizică a datelor dintr-o BD (clustere):
 CREATE CLUSTER – creează un cluster dintr-o BD;
 ALTER CLUSTER– actualizează un cluster;
 DROP CLUSTER – şterge un cluster.

5.1. Comenzi (CREATE, ALTER, DROP)

Limbajul de definire a datelor (a schemei unei BD) include instrucţiuni ce permit:


 crearea schemei bazei de date;
 adăugarea relaţiilor la schema bazei;
 ştergerea unor relaţii existente;
 adăugarea de noi atribute relaţiilor existente;
 optimizarea bazei de date (index, grup, declanşator);
 definirea structurii fizice şi logice a unei BD;
 restricţii cu privire la utilizarea structurii.

Comenzi pentru crearea unei baze de date


CREATE DATABASE nume_baza;

Comenzi pentru suprimarea unei baze de date


DROP DATABASE nume_baza;
Această comandă distruge BD cu numele nume_baza.

Comenzi pentru crearea relaţiilor de bază


În cadrul acestor comenzi se precizează numele relaţiei, precum şi numele şi tipul atributelor.
CREATE TABLE nume_tabela (atribute);

Crearea unei relaţii indicând cheia la nivel de coloană


Exemplu: Să se creeze relaţia PRODUSE(cod_produs, denumire_proddus,
unitate_de_masura, data_expirarii).
CREATE TABLE PRODUSE
(cod_produs VARCHAR(5) PRIMARY KEY,
denumire_proddus VARCHAR(30),
unitate_de_masura VARCHAR(2),
data_expirarii DATE);

25
Crearea unei relaţii indicând cheile la nivel de tabel
Exemplu: Să se creeze relaţia LINII_FACTURI(nr_factura, cod_produs, cantitate,
PRET_UNIRAR).
CREATE TABLE LINII_FACTURI
(nr_factura VARCHAR(5),
cod_produs CHAR (5),
cantitate REAL,
pret_unitar REAL,
PRIMARY KEY (nr_factura, cod_produs),
FOREIGN KEY (cod_produs)
REFERENCES PRODUSE (cod_produs));
Dacă cheia primară are mai mult de o coloană atunci cheile trebuie indicate la nivel de tabel.

Crearea unui tabel prin copiere


Exemplu: Să se creeze relaţia PRODUSE_PAINE(cod_produs, denumire_proddus,
unitate_de_masura, data_expirarii), utilizând copierea datelor din relaţia PRODUSE.
CREATE TABLE PRODUSE_PAINE
SELECT cod_produs, denumire_proddus, unitate_de_masura,
data_expirarii
FROM PRODUSE
WHERE denumire_proddus LIKE 'PAINE';

Comenzi pentru suprimarea unei relaţii de bază


DROP TABLE nume_tabela;
Comanda SQL distruge relaţia nume_tabela.

Comenzi pentru schimbarea numelui unei relaţii


RENAME nume_tabela TO nume_tabela_nou;
Exemplu: Să se modifice numele relaţiei PRODUSE_PAINE în PROD_PAINE, apoi să se suprime
relaţia PROD_PAINE.
RENAME TABLE PRODUSE_PAINE TO PROD_PAINE;
DROP TABLE PROD_PAINE;

Comenzi pentru modificarea structurii unei relaţii


Prin modificarea structurii unei relaţii se înţelege:
• extinderea schemei relaţiei prin adăugarea de noi atribute;
• restrângerea schemei unei relaţii prin suprimarea unor atribute;
• modificarea numelui şi/sau tipului unui atribut din cadrul relaţiei.

Unele limbaje relaţionale (QBE) admit toate aceste tipuri de modificări în schema unei relaţii, iar
altele (SQL sau QUEL) numai o parte.
ALTER TABLE nume_tabel ...

Adăugarea unui atribut cu ajutorul opţiunii ADD


Exemplu: Să se adauge atributul „TOTAL_VALOARE_FACTURA” la relaţia LINII_FACTURI.
ALTER TABLE LINII_FACTURI
ADD (TOTAL_VALOARE_FACTURA REAL);

Modificarea unui atribut cu ajutorul opţiunii MODIFY


Exemplu: Să se modifice forma preţului unitar din relaţia LINII_FACTURI.

26
ALTER TABLE LINII_FACTURI
MODIFY pret_unitar DECIMAL (10,2);

Comenzi pentru declararea restricţiilor de integritate (a constrângerilor)


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ângeri 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.
Prin comanda CREATE TABLE pot fi specificate anumite restricţii (constrângeri) prin care se
exprimă o condiţie care trebuie respectată de toate tuplurile uneia sau mai multor relaţii. Acestea pot fi
definite cu ajutorul comenzii:
ALTER TABLE

Constrângerile declarative pot fi:


• constrângeri de domeniu, care definesc valorile luate de un atribut:
o DEFAULT
o NOT NULL
o UNIQUE
o CHECK
• constrângeri de integritate a entităţii, care precizează cheia primară:
o PRIMARY KEY
• constrângeri de integritate referenţială, care asigură corespondenţa între cheile primare şi
cheile externe corespunzătoare:
o FOREIGN KEY

Fiecărei restricţii i se poate da un nume, lucru util atunci când, la un moment dat (salvări, restaurări,
încărcarea BD) se doreşte dezactivarea uneia sau mai multora dintre acestea. Astfel se prefigurează
numele fiecărei restricţii cu tipul său:
• pk_(PRIMARY KEY) - pentru cheile primare;
• un_(UNIQUE) - pentru cheile alternative - care impune respectarea unicității valorilor;
• nn_(NOT NULL) - pentru atributele obligatorii;
• ck_(CHECK) - pentru reguli de validare la nivel de atribut;
• fk_(FOREIGN KEY) - pentru cheile străine.

Exemplu: Să se realizeze constrângerea de cheie primară, de cheie externă şi constrângerea de


domeniu pentru relaţia LINII_FACTURI.
CREATE TABLE LINII_FACTURI
(nr_factura VARCHAR(5) NOT NULL,
CONSTRAINT pk_nr PRIMARY KEY (nr_factura),
cod_produs CHAR (5),
CONSTRAINT FOREIGN KEY fk_co(cod_produs)
REFERENCES PRODUSE (cod_produs),
cantitate REAL,
PRET_UNIRAR REAL);

Observaţii:
• Liniile ce nu respectă constrângerea sunt depuse automat într-un tabel special;
• Constrângerile previn ştergerea unui tabel dacă există dependenţe;
• Constrângerile pot fi activate sau dezactivate în funcţie de necesităţi.
• Constrângerile pot fi create o dată cu tabelul sau după ce acesta a fost creat.
27
Modificarea unei restricţii de integritate
ALTER TABLE nume_tabela
MODIFY(nume_atribut TIP_CONSTRÂNGERE);

Exemplu: Să se modifice una din constrângerile din exemplul de mai sus:


ALTER TABLE LINII_FACTURI
MODIFY PRET_UNIRAR REAL NOT NULL;

Activarea şi/sau dezactivarea unei constrângeri


Activarea sau dezactivarea unei constrângeri se realizează cu ajutorul opţiunilor ENABLE sau
DISABLE.

Exemplu: Să se dezactiveze, apoi să se activeze constrângerea de cheie primară din relaţia


LINII_FACTURI.
ALTER TABLE LINII_FACTURI
ADD (CONSTRAINT pk_nr PRIMARY KEY (nr_factura) DISABLE);
ALTER TABLE LINII_FACTURI ENABLE (CONSTRAINT pk_nr);

Suprimarea unei constrângeri cu ajutorul opţiunii DROP


ALTER TABLE nume_tabela DROP PRIMARY KEY;

Exemplu: Să se suprime restricţia de cheie primară (pentru atributul „nr_factura”) din tabela
LINII_FACTURI.
ALTER TABLE LINII_FACTURI DROP PRIMARY KEY;

Adăugarea unei constrângeri cu ajutorul opţiunii ADD


ALTER TABLE nume_tabela ADD CONSTRAINT ...;

Exemplu: Să se adauge restricţia de cheie primară „nr_factura” pentru relaţia LINII_FACTURI.


ALTER TABLE LINII_FACTURI
ADD CONSTRAINT pk_nr PRIMARY KEY (nr_factura);

Observaţii:
• Comanda ALTER TABLE realizează modificarea structurii tabelului (la nivel de coloană sau
la nivel de tabel), dar nu modificarea conţinutului acestuia;
• Constrângerile pot fi adăugate (ADD CONSTRAINT), şterse (DROP CONSTRAINT),
activate (ENABLE) sau dezactivate (DISABLE), dar nu pot fi modificate;
• Dacă există o cheie externă care referă o cheie primară ş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ă urmărind
sintaxa:
ALTER TABLE Nume_tabela
DROP PRIMARY KEY CASACDE;

28
6. Limbajul de manipulare a datelor (LMD)
Instrucţiunile LMD (sau DML, Data Manipulation Language) sunt utile pentru interogarea și
prelucrarea datelor din obiectele unei scheme. Aceste instrucţiuni permit:
• interogarea bazei de date (SELECT);
• adăugarea de înregistrări în tabele (sub forma rândurilor din tabele) sau vizualizări (INSERT);
• modificarea valorilor unor coloane din înregistrările existente în tabele sau vizualizări
(UPDATE);
• suprimarea de înregistrări din tabele sau vizualizări (DELETE).

O colecție de comenzi LMD care formează o unitate logică de lucru se numește tranzacție.

Instrucţiunile LMD individuale afectează datele dintr-un singur tabel. Este posibil ca într-o
instrucţiune LMD să se refere şi o vizualizare care conţine date din mai multe tabele (adică o
vizualizare care conţine o uniune de tabele), dar, în acest caz, instrucţiunea LMD poate referi numai
coloane dintr-un singur tabel al vizualizării. Cu alte cuvinte, atunci când o instrucţiune LMD foloseşte
o vizualizare, toate coloanele vizualizării referite în instrucţiunea LMD trebuie să corespundă unor
coloane dintr-un singur tabel fizic al bazei de date.

Sistemul SGBD nu va efectua în baza de date nici o modificare care încalcă una din restricţii.

La formarea instrucțiunilor LMD, trebuie să se ţină seama de următoarele aspecte referitoare la


restricţiile tabelului modificat:
• restricţii de tip cheie primară. Atunci când se inserează un nou rând într-un tabel, cheia
primară a noului rând trebuie să fie unică în întregul tabel. Când se modifică valoarea unei
chei primare (ceea ce se întâmplă rareori), noua valoare trebuie să fie unică în întregul
tabel;
• restricţii de unicitate. Ca şi în cazul cheilor primare, coloanele pe care a fost definită o
restricţie de unicitate trebuie sa aibă valori unice în întregul tabel;
• restricţii NOT NULL. O valoare nula (NULL) este o modalitate specială prin care sistemul
SGBD tratează valoarea unei coloane pentru a indica faptul că valoarea coloanei
respective nu este cunoscută. O valoare nulă nu este același lucru cu un spațiu liber, un șir
vid sau valoarea zero – este o valoare specială care nu este egală cu nimic altceva.
În cazul instrucţiunilor INSERT, trebuie specificate valori pentru toate coloanele cu
restricţii NOT NULL.
În cazul instrucţiunilor UPDATE nu se pot înlocui valorile unei coloane cu valori nule
dacă pe coloana respectivă este definită o restricţie NOT NULL.
Dacă instrucţiunea LMD referă o vizualizare, nu poate fi folosită într-o instrucţiune
INSERT dacă una dintre coloanele tabelului cu o restricţie NOT NULL (obligatorii)
lipseşte din definirea vizualizării;
• restricţii referenţiale. Nu se poate insera sau actualiza valoarea unei chei externe decât dacă
există deja rândul părinte corespondent care conţine valoarea cheii în coloana cheii
primare. În sens invers, nu se poate şterge un rând părinte dacă există rânduri subordonate
care referă valoarea din rândul părinte, decât dacă restricţia a fost definită cu opţiunea
ON DELETE CASCADE. În general inserările în tabele trebuie făcute ierarhic (mai întâi
rândurile părinte, apoi rândurile copii), iar ştergerile trebuie făcute în ordine inversă
(copiii înaintea părinţilor);
• restrictii de verificare (CHECK). O instructiune INSERT sau UPDATE nu poate stoca într-o
coloană o valoare care încalcă o restricţie CHECK definită pentru coloana respectivă.

29
Actualizarea datelor se referă la adăugarea unor noi rânduri într-o tabelă (cu instrucţiunea INSERT), la
modificarea valorilor uneia sau mai multor valori dintr-un rând (cu comanda UPDATE) şi la ştergerea
unui rând dintr-o tabelă (cu comanda DELETE).

6.1. Interogarea datelor (Comanda SELECT)

Comanda fundamentală a standardului SQL este SELECT, aceasta permiţând interogarea unei baze de
date.

Componentele interogării se numesc clause.

Sintaxa generală a comenzii SELECT este următoarea:


SELECT [ALL/DISTINCT/UNIQUE] listă de selecţie
FROM listă de relaţii (tabele)
WHERE condiţie de căutare asupra liniilor
GROUP BY listă de atribute care permit partiţionarea
HAVING condiţie asupra partiţiilor
ORDER BY listă de atribute;

Clauzele SELECT şi FROM sunt obligatorii. SELECT specifică datele care se selectează, iar clauza
FROM specifică relaţiile din care se selectează. Restul clauzelor sunt opţionale.

Exemplul 1: Să se selecteze toate produsele împreună cu toate datele acestora existente în baza de
date.
SELECT * FROM PRODUSE;

Exemplul 2: Să se selecteze toate produsele care expiră în data de 2017-07-03.


SELECT * FROM PRODUSE
WHERE data_expirarii=’2017-07-03’;

Interogarea datelor folosind operatorii IS şi IS NOT


Exemplu: Să se selecteze numele tuturor clienților care au completată adresa, apoi să se afişeze
numele tuturor persoanelor care nu au numărul de telefon completat.
SELECT nume_client FROM CLIENTI
WHERE adresa_client IS NOT NULL;

SELECT nume_client FROM CLIENTI


WHERE telefon_client IS NULL;

Interogarea datelor folosind operatorii logici AND, OR, NOT


Sintaxa pentru interogarea care utilizează un operator logic este:
condiţie1 AND condiţie 2;
condiţie1 OR condiţie 2;
NOT condiţie;

Exemplu: Să se determine numărul facturii şi codul produselor pentru produsele cu o cantitate mai
mare de 300 şi cu un preţ unitar mai mare sau egal ca 100.
SELECT cod_produs, nr_factura FROM LINII_FACTURI
WHERE cantitate>’300’ AND pret_unitar>=’100’;

30
Interogarea datelor folosind operatorul IN
SELECT valoare_câmp IN (valoare1, valoare2,...);

Această sintaxă a operatorului IN este similară cu următoarea listă de disjuncţii:


Valoare_câmp=valoare1 OR valoare_câmp=valoare2 OR ...;

Exemplu: Să se selecteze numărul facturii și codul produselor pentru produsele cu prețul unitar de 70,
80, 90.
SELECT * FROM LINII_FACTURI
WHERE pret_unitar IN (70.00,80.00,90.00);

Interogarea datelor folosind DISTINCT


Pentru a selecta seturi de valori distincte, adică eliminarea valorilor duplicat, în SQL se foloseşte
sintaxa DISTINCT, micşorând astfel setul de date.

Sintaxa acestei comenzi este:


SELECT DISTINCT nume_câmp1, nume_câmp2,...
FROM nume_tabela
WHERE comenzi;
sau
SELECT DISTINCT *
FROM nume_tabela;

Sintaxa DISTINCT se referă la o înregistrare care poate cuprinde unul sau mai multe câmpuri.

Exemplu: Să se afişeze toate datele distincte despre produse.


SELECT DISTINCT denumire_produs FROM PRODUSE;

Interogarea datelor folosind operatorul LIKE


Se cunosc mai multe modalităţi de utilizare a expresiei LIKE, şi anume:
• pentru o expresie care începe cu o anumită literă, de exemplu litera ‘A’: LIKE ‘A%’;
• pentru o expresie care se termină cu o anumită literă, de exemplu litera ‘A’: LIKE ‘%A’;
• pentru o expresie care include o anumită literă, de exemplu litera ‘A’: LIKE ‘%A%’;

Exemplu: Să se selecteze numele adresa şi emailul tuturor persoanelor din București care au adresă de
email pe gmail sau personal.
SELECT nume_client, adresa_client, email_client
FROM CLIENTI
WHERE adresa_client LIKE ‘%BUCUREȘTI %’ AND
(email_client LIKE ‘%gmail%’ OR email_client LIKE’%personal%’);

Interogarea datelor folosind operatorul BETWEEN


Operatorul se utilizează în combinaţie cu două valori între care se află valoarea la care se referă
operatorul.

Sintaxa este:
val BETWEEN minim AND maxim;
sau
val>=min AND val<=max;

31
Cele trei expresii val, min, max pot fi de tip numeric (numeric, decimal, int, smalint etc.) sau de tip
dată calendaristică.

Exemplu: Să se selecteze codurile tuturor facturilor înregistrate în perioada 1 ianuarie 2017 şi 1 mai
2017.
SELECT nr_factura
FROM FACTURI
WHERE data_factura BETWEEN ‘2017-01-01’ AND ‘2017-05-01’;

Interogarea datelor folosind funcţiile calendaristice YEAR, DAY, MONTH


Funcţiile YEAR, DAY, MONTH reţin dintr-un câmp de tip dată calendaristică anul, ziua, respectiv luna.

Exemplu: Să se vizualizeze codurile tuturor facturilor înregistrate în luna mai.


SELECT nr_factura
FROM FACTURI
WHERE MONTH(data_factura)=05;

Interogarea datelor folosind ordonarea


Datele se pot ordona după orice câmp. Ordonarea se poate face atât crescător cât şi descrescător.

Sintaxa pentru interogarea


• ordonată crescător este:
ORDER BY nume_câmp (ASC);
• ordonată descrescător este:
ORDER BY nume_câmp (DESC);

Dacă ORDER BY nu este urmat de ASC sau DESC, ordonarea se face implicit crescător.

Exemplu: Să se vizualizeze lista clienților în ordine alfabetică.


SELECT nume_client
FROM CLIENTI
ORDER BY nume_client;

Interogarea datelor din mai multe tabele


Atunci când este necesară obţinerea de informaţii din mai multe tabele se utilizează condiţii de join. În
acest fel liniile dintr-un tabel pot fi puse în legătură cu cele din alt tabel conform valorilor comune ale
unor coloane. Interogarea datelor din mai multe relaţii este strâns legată de noţiunea de cheie primară,
cheie secundară, restricţii de integritate, asocieri între relaţii.

Exemplu: Să se afişeze facturile, numele și adresa clienților corespunzătoare facturilor.


SELECT FACTURI.nr_factura, CLIENTI.nume_client,
CLIENTI.adresa_client
FROM FACTURI, CLIENTI
WHERE FACTURI.nume_client = CLIENTI.nume_client;

Observaţii:
• Atunci când în clauza FROM a unei comenzi SELECT apar mai multe tabele se realizează
produsul cartezian al acestora. De aceea numărul de linii rezultat creşte considerabil, fiind
necesară restricţionarea acestora cu o clauza WHERE. Se utilizează sintaxa:
nume_tabel.nume_câmp
Clauza FROM specifică două relaţii (FACTURI și CLIENTI).
32
Clauza SELECT cuprinde valori din relaţia FACTURI şi din relaţia CLIENTI, prin
urmare trebuie definite câmpurile în funcţie de tabela din care fac parte.
• Clauza WHERE include condiţii care exprimă o egalitate între valorile identificatorului
nume_câmp a relaţiei nume_tabel şi a celei ale referinţei la acest identificator în tabela
referită.

Tipuri de asocieri pentru relaţii


Rolul unei relaţii este de a modela entităţi, între relaţii există aceleaşi tipuri de asocieri ca şi între
entităţi, şi anume asocieri una-la-una, una-la-multe, multe-la-multe.

• Asocieri de la una-la-una
Două relaţii stochează informaţii în asocierea una-la-una dacă unei înregistrări din relaţia A îi
corespunde (sau nu) o singură înregistrare din B.
Acest tip de asociere este utilizată mai rar. Există, totuşi, cazuri în care este necesară şi utilă stabilirea
unei astfel de relaţii.

Exemplu:

LINII_FACTURI PRODUSE

nr_factura# cod_produs#
cod_produs# denumire_produs
cantitate unitate_de_masura
pret_unitar data_expirarii

Asociere de tip 1:1

• Asocieri de la una-la-multe
O relaţie A se află într-o asociere de una-la-multe cu o relaţie B dacă fiecărei înregistrări din A îi
corespund una sau mai multe înregistrări din relaţia B. Unei înregistrări din relaţia B nu îi corespunde
decât maxim o înregistrare din relaţia A.

Sunt utilizate următoarele denumiri:


• B este relaţia copil, sau relaţia care referă la A, sau relaţia cheie străină;
• A este relaţia părinte (master), sau relaţia referită, sau relaţia cheie primară.

Exemplu:
FACTURI LINII_FACTURI

nr_factura# nr_factura#
data_factura cod_produs#
nume_client cantitate
delegat pret_unitar

Asociere de tip 1:M

Observaţie: Relaţia A are cheia primară „ nr_factura”, iar relaţia B are atributul „ cod_produs” cheie
externă.

33
• Asocieri de la mai multe-la-multe
O relaţie A se află în asociere de tipul multe-la-multe cu o relaţie B dacă unei înregistrări din relaţia A
îi pot corespunde mai multe înregistrări din relaţia B şi unei înregistrări din relaţia B îi pot corespunde
mai multe înregistrări din relaţia A.

O asociere N la M nu se defineşte direct, asocierea construindu-se cu ajutorul unei relaţii de joncţiune.


În această relaţie se păstrează legătura între cele două relaţii, precum şi informaţiile necesare.

Exemplu:
A 1:M B 1:M C
FACTURI LINII_FACTURI PRODUSE

nr_factura# nr_factura# cod_produs#


data_factura cod_produs# denumire_produs
nume_client cantitate unitate_de_masura
delegat pret_unitar data_expirarii

Asociere de tip N:M

Observaţie: În exemplul de mai sus, relaţia LINII_FACTURI realizează joncţiunea între relaţiile
FACTURI şi PRODUSE, stocând informaţiile privind nr_factura, cod_produs, cantitate, pret_unitar
etc.

Astfel, asocierea N la M este vizualizată sub forma a două relaţii de 1 la M.

Interogarea datelor din mai multe relaţii folosind aliasuri (sau pseudonime)
Un alias este o redenumire fie a unui câmp, fie a unei relaţii. Aliasurile sunt utilizate la eliminarea
rescrierii complete a denumirii unei relaţii sau a unui câmp, redenumindu-le într-un mod simplificat.

Sintaxa utilizată este:


nume_relaţie/camp AS nume_nou;
sau
nume_relaţie/camp nume_nou;

Există posibilitatea de a utiliza aliasuri pentru tabelele din clauza FROM şi utilizarea lor în cadrul
comenzii SELECT respective (alias.coloana). Această identificare (prin 'tabel.coloana' sau
'alias.coloana') este obligatorie atunci când se face referinţă la o coloană ce apare în mai mult de un
tabel din clauza FROM.

Exemplu: Să se afişeze facturile, numele și adresa clienților corespunzătoare facturilor, folosind


aliasuri.
SELECT F.nr_factura, C.nume_client, C.adresa_client
FROM FACTURI F, CLIENTI C
WHERE F.nume_client = C.nume_client;

Observaţie: În cazul în care un atribut apare doar într-o relaţie dintre cele menţionate în listă, nu este
obligatorie precizarea relaţiei (adică a aliasului) din care face parte atributul respectiv.

Interogarea datelor din mai multe relaţii folosind tipuri de asocieri


Tipurile de asocieri utilizate în interogarea mai multor relaţii sunt:
34
1) INNER JOIN (joncţiunea internă);
2) LEFT OUTER JOIN (semijoncţiunea la stânga);
3) RIGHT OUTER JOIN (semijoncţiunea la dreapta);

1) INNER JOIN (joncţiunea internă). Sintaxa


SELECT ...FROM tabel_A INNER JOIN tabel_B ON (condiţii de join)

selectează toate informaţiile din relaţiile A şi B care corespund condiţiilor de asociere.

Exemplu: Selectaţi numărul facturii şi denumirea produselor fiecărei facturi folosind operaţia de join,
apoi utilizând clauza WHERE.
SELECT F.nr_factura, P.cod_produs, P.denumire_produs
FROM LINII_FACTURI F INNER JOIN PRODUSE P
ON (F.cod_produs =P.cod_produs);

SELECT F.nr_factura, P.denumire_produs


FROM LINII_FACTURI F, PRODUSE P
WHERE F.cod_produs =P.cod_produs;

Observaţii:
• Rezultatul este acelaşi. Valorile NULL vor fi ignorate;
• Sintaxei SELECT-FROM-INNER JOIN i se pot adăuga şi alte condiţii, neincluse în condiţiile
de join, dacă acestea se referă la alte câmpuri decât cele care participă la join.

2) LEFT OUTER JOIN (semijoncţiunea la stânga). Sintaxa


SELECT ...FROM tabel_A LEFT OUTER JOIN tabel_B
ON (condiţii de join)

selectează toate informaţiile din A, pe care le completează cu informaţii din B, în măsura în care
satisfac condiţiile de join; acolo unde nu vor exista informaţii din B, acestea vor fi completate cu
NULL.

Exemplu: Selectaţi toate facturile. Dacă există informaţii despre aceste facturi, afişaţi şi aceste
informaţii.
SELECT *
FROM LINII_FACTURI F LEFT OUTER JOIN PRODUSE P
ON (F.cod_produs =P.cod_produs);

Observaţie: Ordinea în care se scrie denumirea relaţiei în sintaxa LEFT OUTER JOIN este foarte
importantă. Astfel, relaţia din stânga este relaţia primară, adică relaţia pentru care se doreşte returnarea
tuturor informaţiilor; relaţia din dreapta este relaţia secundară, adică informaţiile din ea sunt necesare
doar în măsura în care se potrivesc condiţiilor de asociere. Astfel se explică şi denumirea de asociere
de la stânga spre exterior.

3) RIGHT OUTER JOIN (semijoncţiunea la dreapta). Sintaxa


SELECT ...FROM tabel_A RIGHT OUTER JOIN tabel_B
ON (condiţii de join)

selectează toate informaţiile din B, pe care le completează cu informaţii din A, în măsura în care
satisfac condiţiile de join; acolo unde nu vor exista informaţii din A, acestea vor fi completate cu
NULL.
35
Exemplu: Selectaţi toate facturile și produsele corespunzătoare, inclusiv facturile fără niciun produs.
SELECT *
FROM PRODUSE P RIGHT OUTER JOIN LINII_FACTURI F
ON (P.cod_produs =F.cod_produs);

Observaţie: Sintaxa RIGHT OUTER JOIN este utilizată mai rar; de obicei se utilizează sintaxa LEFT
OUTER JOIN.

Interogarea datelor din mai multe relaţii folosind instrucţiunea UNION


Sintaxa interogării datelor din mai multe relaţii folosind instrucţiunea UNION este:
SELECT Câmp 1, Câmp 2, ..., Câmp n
FROM Tabel 1
UNION (ALL)
SELECT Câmp 1A, Câmp 2A,..., Câmp nA
FROM Tabel 2

şi returnează înregistrări distincte dacă este folosită instrucţiunea UNION, şi toate înregistrările dacă
se foloseşte UNION ALL. Astfel operatorul UNION elimină duplicatele, iar UNION ALL
vizualizează toate înregistrările, inclusiv duplicatele.

Pentru a utiliza această interogare, trebuie să se ţină seama de două cerinţe: domeniile Câmp 1A, Câmp
2A,..., Câmp nA şi Câmp 1, Câmp 2, ..., Câmp n trebuie să fie respectiv aceleaşi şi, numărul de
câmpuri din fiecare interogare trebuie să coincidă.

Operatorul UNION se foloseşte atunci când între relaţii nu există o asociere directă.

Interogarea datelor mai multor relaţii folosind operatorul de concatenare a două şiruri de caractere
Rolul operatorului de concatenare a două şiruri de caractere este de a uni două şiruri de caractere într-
unul singur. Este utilizat în toate SGBD-urile, cu mici modificări ale simbolului: în SQL se foloseşte
simbolul ‚+’, în Oracle simbolul ‚||’ etc.

Se pot concatena o constantă cu un câmp, sau două câmpuri. Câmpurile trebuie să fie de tip text.

Sintaxa pentru concatenarea a două câmpuri este


CONCAT(Câmp1, Câmp2)

sau inserând virgula, spaţiu sau oricare marcaj de delimitare


CONCAT(Câmp1,’,’, Câmp2)
sau
CONCAT(Câmp1,’ ’, Câmp2)
concatenează cele două constante într-una singură ’ Câmp1 Câmp2’.

Observaţie: Concatenarea prezintă dezavantajul afişării câmpurilor NULL.

Interogarea datelor folosind funcţiile totalizatoare:


• MAX
• MIN
• COUNT
• SUM
• AVG
36
• Interogarea datelor folosind funcţia MAX
Sintaxa:
SELECT MAX(Nume_câmp) FROM Nume_tabela

returnează un număr egal cu valoarea maximă a câmpului Nume_câmp din relaţia Nume_tabela,
valorile NULL fiind ignorate.

Exemplu: Selectaţi cea mai recentă factură din tabela FACTURI, fără a da un nume rezultatului, apoi
cu nume pentru câmpul rezultat.
SELECT MAX(data_factura) FROM FACTURI;

SELECT MAX(data_factura) AS data_ultimei_înregistrari


FROM FACTURI;

• Interogarea datelor folosind funcţia MIN


Funcţia MIN este o funcţie similară cu funcţia MAX, cu ajutorul căreia se poate determina valoarea
cea mai mică dintr-un câmp.

Atât funcţia MIN cât şi funcţia MAX se pot aplica doar pentru tipurile de date numeric sau dată
calendaristică.

• Interogarea datelor folosind funcţia COUNT


Sintaxa:
• SELECT COUNT (*) FROM Nume_tabela - returnează un număr egal cu numărul de
înregistrări ale tabelei Nume_tabela;
• SELECT COUNT (Nume_câmp) FROM Nume_tabela - returnează un număr egal cu
numărul de valori nenule ale câmpului Nume_câmp din tabela Nume_tabela. Sunt
ignorate valorile NULL;
• SELECT COUNT(DISTINCT Nume_câmp) FROM Nume_tabela - returnează un
număr egal cu numărul de valori distincte nenule ale câmpului Nume_câmp din tabela
Nume_tabela. Sunt ignorate valorile NULL.

Exemplu: Precizaţi numărul de produse.


SELECT COUNT(cod_produs) AS nr_produselor FROM PRODUSE;

• Interogarea datelor folosind funcţia SUM


Sintaxa:
• SELECT SUM (Nume_câmp) FROM Nume_tabela - returnează un număr egal cu
suma tuturor valorilor câmpului Nume_câmp din relaţia Nume_Tabela. Sunt ignorate
valorile NULL;
• SUM (DISTINCT Nume_câmp) FROM Nume_tabela - returnează un număr egal cu
suma valorilor distincte ale câmpului Nume_câmp din relaţia Nume_Tabela.

Funcţia SUM se aplică acelor câmpuri care au domeniul de valori de tipul FLOAT, DECIMAL,
NUMERIC, INT etc. şi nu are sens pentru câmpuri de tip text.

Exemplu: Precizaţi suma tuturor încasărilor existente pe facturile emise.


SELECT SUM(DISTINCT total_valoare_factura) FROM FACTURI;

37
• Interogarea datelor folosind funcţia AVG
Sintaxa:
AVG (nume_câmp) FROM Nume_tabela
returnează un număr egal cu media aritmetică a tuturor valorilor câmpului Nume_câmp din relaţia
Nume_tabela. Valorile NULL sunt ignorate.

Funcţia AVG se utilizează doar pentru date de tip numeric: INT, FLOAT, NUMERIC.

Exemplu: Selectaţi media prețurilor produselor.


SELECT AVG (pret_unitar) FROM LINII_FACTURI;

Interogarea datelor folosind instrucţiunea GROUP BY


Prin instrucţiunea GROUP BY se grupează datele după fiecare produs în parte.

Exemplu: Selectaţi fiecare produs în parte grupându-le crescător şi precizaţi cantitatea vândută din
fiecare tip.
SELECT P.denumire_produs, SUM(F.cantitate) AS suma
FROM PRODUSE P, LINII_FACTURI F
WHERE F.cod_produs= P.cod_produs
GROUP BY P.cod_produs;

Observație: Menţionarea clauzelor SELECT, FROM, WHERE, GROUP BY, ORDER BY în această
ordine este obligatorie. Greşeala frecventă care duce la apariţia unor mesaje de eroare este aceea a
introducerii unor câmpuri după care se grupează în clauza SELECT şi neintroducerea lor în clauza
GROUP BY.

Funcţiile de agregare se pot folosi ca extensii ale clauzei GROUP BY:


• ROLLUP - permite instrucţiunii SELECT să calculeze niveluri de subtotal multiple peste un
grup de dimensiuni;
• CUBE - generează toate subtotalurile care pot fi calculate dintr-un CUBE pe dimensiunile
specificate;
• GROUPING;
• GROUPING SET.

Interogarea datelor folosind instrucţiunea HAVING


Instrucţiunea HAVING se utilizează numai în combinaţie cu instrucţiunea GROUP BY. Clauza
HAVING este utilizată când se doreşte filtrarea datelor grupate conform unor criterii. Aceste criterii
presupun compararea unor valori obţinute prin apelarea unor funcţii totalizatoare. Aceste tipuri de
comparări presupun gruparea datelor. Din această cauză, HAVING cere obligatoriu clauza GROUP
BY.

Exemplu: Selectaţi produsele grupate după cod care au preţul unitar cuprins între 500 şi 3000.
SELECT P.denumire_produs, P.cod_produs, F.pret_unitar
FROM PRODUSE P, LINII_FACTURI F
WHERE F.cod_produs= P.cod_produs
GROUP BY P.cod_produs
HAVING F.PRET_UNIRAR BETWEEN 500 AND 3000;

38
6.2. Adăugarea de noi tupluri (Comanda INSERT)

În vederea adăugării unor rânduri noi într-o tabelă sau într-o vizualizare se utilizează comanda
INSERT. Instrucţiunea are două forme de bază: una în care valorile coloanelor sunt specificate chiar în
instrucţiune şi alta în care valorile sunt selectate dintr-un tabel sau o vizualizare, folosind o
subinterogare.

Inserarea unui singur rând de date folosind clauza Values


Instrucţiunea INSERT care foloseşte o clauză VALUES poate crea un singur rând la fiecare rulare,
deoarece valorile pentru rândul de date respectiv sunt specificate chiar în instrucţiune.

Sintaxa generală a instrucţiunii este următoarea:


INSERT INTO nume_tabel_sau_vizualizare[(lista_de_coloane)]
VALUES (lista_de_valori);
sau
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).

Exemplu:
INSERT INTO PRODUSE (cod_produs, denumire_produs,
unitate_de_masura, data_expirarii)
VALUES (50, ‘PAINE’, ‘KG’,’2017-05-15’);

Clauza VALUES specifică valorile ce vor fi introduse în tabel sau vizualizare. Pentru a insera mai
multe linii prin aceeaşi instrucţiune INSERT, în locul acestei clauze se va preciza o subcerere.
Dacă nu se mai cunoaşte ordinea de declarare a coloanelor se foloseşte comanda DESCRIBE care va
afişa lista coloanelor definite pentru tabela respectivă, tipul şi lungimea lor.

Se pot remarcă următoarele:


• lista de coloane este opţională, dar dacă este inclusă trebuie să fie încadrată între paranteze
rotunde;
• dacă lista de coloane este omisă, trebuie specificată o valoare pentru fiecare coloană din tabel,
în ordinea în care sunt definite coloanele în tabel. Este bine ca întotdeauna să se includă
lista de coloane, deoarece omiterea acesteia face ca instrucţiunea INSERT să fie
dependentă de definiţia tabelului. Dacă o coloană este modificată sau în tabel este
adăugată o nouă coloană, chiar şi opţională, probabil instrucţiunea INSERT va eşua la
următoarea rulare;
• dacă lista de coloane este specificată, lista de valori trebuie să conţină o valoare pentru fiecare
coloană din listă, în aceeaşi ordine. Cu alte cuvinte, între lista de coloane şi lista de valori
trebuie să existe o corespondenţă una-la-una. Orice coloană care lipseşte din listă va primi
o valoare nulă, presupunund că valorile nule sunt acceptate în coloana respectivă;
• în clauza VALUES, valorile de tip caracter şi dată calendaristică trebuie incluse între
apostrofuri. Nu se recomandă includerea între apostrofuri a valorilor numerice, întrucât
aceasta ar determina conversii implicite la tipul NUMBER;
• pentru introducerea de valori speciale în tabel pot fi utilizate funcţii;
• adăugarea unei linii care va conţine valori NULL se poate realiza în mod implicit, prin
omiterea numelui coloanei din lista de coloane. Exemplu:

39
INSERT INTO PRODUSE (cod_produs, denumire_produs,
unitate_de_masura)
VALUES (50, ‘PAINE’, ‘KG’);

sau explicit, prin specificarea în lista de valori a cuvântului cheie NULL sau a şirului vid (‘’)
în cazul şirurilor de caractere sau datelor calendaristice. Exemplu:
INSERT INTO PRODUSE (cod_produs, denumire_produs,
unitate_de_masura, data_expirarii)
VALUES (50, ‘PAINE’, ‘KG’, NULL);

Inserări masive folosind instrucţiunea SELECT internă


Aşa cum se observă, este nevoie de foarte mult cod pentru a insera în tabel un singur rând de date
folosind o instrucţiune INSERT cu clauza VALUES.
O altă soluţie, care poate fi folosită pentru a insera rânduri multiple într-un tabel, este forma care
foloseşte o instrucţiune SELECT internă. Această formă este utilă şi pentru stabilirea următoarei valori
disponibile pentru o cheie primară cu valori secvenţiale. De asemenea, poate fi folosită atunci când se
creează un tabel temporar pentru testare, care va fi populat cu toate datele dintr-un alt tabel.

Sintaxa generală a instrucţiunii este:


INSERT INTO nume_tabel_sau_vizualizare[(lista_de_coloane)]
SELECT instructiune_select;

Se remarcă următoarele:
• lista de coloane este opţională, dar dacă este inclusă trebuie să fie încadrată între paranteze
rotunde;
• dacă lista de coloane este omisă, instrucţiunea SELECT internă trebuie să furnizeze o valoare
pentru fiecare coloană din tabel, în ordinea în care sunt definite coloanele în tabel. Este
bine ca întotdeauna să se includă lista de coloane, deoarece omiterea acesteia face ca
instrucţiunea INSERT să fie dependentă de definiţia tabelului. Dacă o coloană este
modificată sau în tabel este adăugată o nouă coloană, chiar şi opţională, probabil
instrucţiunea INSERT va eşua la următoarea rulare;
• dacă lista de coloane este specificată, instrucţiunea SELECT internă trebuie să furnizeze o
valoare pentru fiecare coloană din lista de valori, în aceeaşi ordine. Cu alte cuvinte, între
lista de coloane şi setul de rezultate al instrucţiunii SELECT trebuie să existe o
corespondenţă una-la-una. Orice coloană care lipseşte din listă va primi o valoare nulă,
presupunând că valorile nule sunt acceptate în coloana respectivă;
• cuvântul cheie NULL poate fi folosit în instrucţiunea SELECT pentru specificarea unei valori
nule pentru o coloană.

Inserarea unor valori specifice de tip dată calendaristică


Formatul DD-MON-YY este de obicei folosit pentru a insera o valoare de tip dată calendaristică. Cu
acest format, secolul este implicit cel curent. Deoarece data conţine de asemenea informaţii despre
timp, ora implicită este 00:00:00.

Dacă o dată calendaristică necesită specificarea altui secol sau oră, trebuie folosită funcţia TO_DATE.

Exemplu:
INSERT INTO PRODUSE (cod_produs, denumire_produs,
unitate_de_masura, data_expirarii)
VALUES (50, ‘PAINE’, ‘KG’, TO_DATE(‘FEB-3 , 2017’, 'MON-DD,
YYYY’));
40
Inserare de valori folosind variabile de substituţie

• Crearea unui script interactiv prin folosirea variabilelor de substituţie SQL*Plus


Exemplu:
INSERT INTO PRODUSE (cod_produs, denumire_produs, unitate_de_masura)
VALUES (‘&cod_produs’, ‘&denumire_produs’, ‘&unitate_de_masura’)

• Crearea unui script pentru manipularea datelor


Comanda împreună cu variabilele de substituţie pot fi salvate într-un fişier şi acesta poate fi executat.
De fiecare dată când se execută fişierul sunt cerute valori noi pentru variabile. Prin intermediul
comenzii SQL*Plus ACCEPT, mesajele afișate la cererea introducerii valorilor pot fi modificate.
• ACCEPT - memoreaza valoarea într-o variabilă;
• PROMPT - afişează textul specificat.

Exemplu:
ACCEPT cod_produs PROMPT 'Introduceti codul produsului:'
ACCEPT denumire_produs PROMPT 'Introduceti denumirea produsului:'
INSERT INTO PRODUSE (cod_produs, denumire_produs)
VALUES (‘&cod_produs’, ‘&denumire_produs’)

Exemplul înregistrează informaţia pentru un produs, în tabelul PRODUSE. Utilizatorului îi sunt cerute
codul produsului şi denumirea produsului, folosind mesajele de prompt stabilite în ACCEPT.

Parametrul de substitutie SQL*Plus nu trebuie precedat de & când este referit într-o comanda
ACCEPT. Pentru a continua o comandă SQL*PLUS pe linia următoare se foloseşte o linie (-).

Copierea înregistrarilor dintr-un alt tabel


Comanda INSERT poate fi folosită pentru a adăuga înregistrări într-un tabel, valorile pentru câmpuri
fiind extrase dintr-un tabel existent. Pentru aceasta se foloseşte, în locul clauzei VALUES, o
subinterogare (Nu se mai folosește clauza VALUES).

Sintaxa este următoarea:


INSERT INTO nume_tabel [ coloana ( , coloana ) ]
Subinterogare;

Numărul şi tipul câmpurilor (coloanelor) din lista specificată în comanda INSERT trebuie să
corespundă numărului şi tipului valorilor din subinterogare.

Exemplu:
INSERT INTO PRODUSE (cod_produs, denumire_produs,
unitate_de_masura)
SELECT cod_produs, denumire_produs, unitate_de_masura
FROM PRODUSE
WHERE denumire_produs = 'PAINE';

Inserări multitabel
O inserare multitabel presupune introducerea de linii calculate pe baza rezultatelor unei subcereri, în
unul sau mai multe tabele. Acest tip de inserare, introdus de Oracle, este util în mediul data
warehouse. Astfel, datele extrase dintr-un sistem sursă, pot fi transformate utilizând instrucţiuni
INSERT multitabel, spre a fi încărcate în obiectele bazei de date.
41
Sintaxa clauzei inserare_multi_tabel este următoarea:
INSERT ALL INTO…[VALUES…] [INTO…[VALUES…] …]
| inserare_condiţionată| subcerere

Clauza inserare_condiţionată are forma următoare:


[ALL | FIRST]
WHEN condiţie THEN INTO…[VALUES…]
[INTO…[VALUES…] …]
[WHEN condiţie THEN INTO…[VALUES…]
[INTO…[VALUES…] …] …]
[ELSE INTO…[VALUES…]
[INTO…[VALUES…] …] …]

Pentru a efectua o inserare multitabel necondiţionată, sistemul va executa câte o instrucţiune


INSERT…INTO pentru fiecare linie returnată de subcerere.

Utilizând clauza inserare_condiţionată, decizia inserării unei linii depinde de condiţia specificată prin
intermediul opţiunii WHEN. Expresiile prezente în aceste condiţii trebuie să facă referinţă la coloane
returnate de subcerere. O instrucţiune de inserare multitabel poate conţine maxim 127 clauze WHEN.

Specificarea opţiunii ALL determină evaluarea tuturor condiţiilor din clauzele WHEN. Pentru cele a
căror valoare este TRUE, se inserează înregistrarea specificată în opţiunea INTO corespunzătoare.

Opţiunea FIRST determină inserarea corespunzătoare primei clauze WHEN a cărei condiţie este
evaluată TRUE. Toate celelalte clauze WHEN sunt ignorate.

Dacă nici o condiţie din clauzele WHEN nu este TRUE, atunci sistemul execută clauza INTO
corespunzătoare opţiunii ELSE, iar dacă aceasta nu există, nu efectuează nici o acţiune.

Inserările multitabel pot fi efectuate numai asupra tabelelor, nu şi asupra vizualizărilor. De asemenea,
acest tip de inserare nu se poate efectua asupra tabelelor distante. Subcererea dintr-o instrucţiune
corespunzătoare unei inserări multitabel nu poate utiliza o secvenţă.

6.3. Modificarea tuplurilor din tabele (Comanda UPDATE)

În funcţie de momentul în care se doreşte realizarea modificărilor asupra bazei de date, utilizatorul
poate folosi una din următoarele comenzi:
• SET AUTOCOMMIT IMM[EDIATE] (schimbările se efectuează imediat);
• SET AUTOCOMMIT OFF (schimbările sunt păstrate într-un buffer).

La execuţia comenzii COMMIT se permanentizează schimbările efectuate, iar la execuţia comenzii


ROLLBACK se renunţă la schimbările realizate.

Instrucţiunea UPDATE este folosită pentru actualizarea datelor din coloanele unui tabel (sau ale unei
vizualizări).

Valorile câmpurilor care trebuie modificate pot fi furnizate explicit sau pot fi obţinute în urma unei
cereri SQL.

Sintaxa generală a instrucţiunii UPDATE:


42
UPDATE nume_tabel_sau_vizualizare
SET nume_coloana = expresie[,nume_coloana = expresie...]
[ WHERE conditie];

Sau mai general, expresia poate fi o cerere:


UPDATE nume_tabel_sau_vizualizare
SET (coloana1[,coloana2[,…]]) = (subinterogare) / coloana =
exprresie /(interogare)
[WHERE conditie]

Dacă este nevoie, se pot modifica mai multe înregistrări simultan.

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.

Se remarcă următoarele:
• clauza SET conţine o listă cu una sau mai multe coloane, împreună cu o expresie care
specifică noua valoare pentru fiecare coloană. Aceasta este o listă de perechi
(NUME,VALOARE), separate prin virgule, cu un operator de egalitate între fiecare
NUME şi VALOARE;
• expresia poate fi o constantă, un alt nume de coloană sau orice altă expresie pe care SQL o
poate transforma într-o singură valoare, care poate fi apoi atribuită coloanei respective;
• clauza WHERE conţine o expresie care limitează rândurile actualizate. Dacă această clauză
este omisă, motorul SQL va încerca să actualizeze toate rândurile din tabel sau din
vizualizare.

Oracle permite utilizarea valorii implicite DEFAULT în comenzile INSERT și UPDATE. Unei
coloane i se atribuie valoarea implicită definită la crearea sau modificarea structurii tabelului dacă:
• nu se precizează nici o valoare;
• 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. Cuvântul cheie DEFAULT nu poate fi specificat la actualizarea vizualizărilor.

Cazurile în care instrucţiunea UPDATE nu poate fi executată sunt similare celor în care eşuează
instrucţiunea INSERT.

Notă: În general, se folosește cheia primară pentru a identifica o singură înregistrare. Folosirea altor
coloane poate determina modificarea mai multor înregistrări.

De exemplu, identificarea unei singure înregistrări în tabelul PRODUSE prin denumire poate fi
periculoasă, deoarece pot exista mai multe produse cu aceeaşi denumire.

Comanda UPDATE modifică anumite înregistrări dacă este specificată clauza WHERE.

Exemplul următor mărește prețul unitar cu 25% pentru produsul cu codul 50.
UPDATE LINII_FACTURI
43
SET pret_unitar = pret_unitar * 1.25
WHERE cod_produs = 50;

Actualizarea înregistrarilor folosind subinterogări după mai multe câmpuri


Exemplul următor măreşte prețul unitar cu 15% pentru produsele care au prețul unitar identic cu cel al
produsului cu codul 50.
UPDATE LINII_FACTURI
SET pret_unitar = pret_unitar * 1.15
WHERE pret_unitar IN
(SELECT pret_unitar
FROM LINII_FACTURI
WHERE cod_produs = 50);

Modificarea înregistrarilor folosind subinterogări după mai multe câmpuri (folosind valori dintr-un
alt tabel)
În clauza SET a unei comenzi UPDATE pot fi implementate subinterogări după mai multe câmpuri.
UPDATE nume_tabel
SET (coloana, coloana, ...) =
(SELECT coloana, coloana,
FROM nume_tabel
WHERE conditie)
WHERE conditie;

Dacă se încercă atribuirea unei valori unui câmp care are legată de o constrângere de integritate, va
rezulta o eroare.

6.4. Ştergerea tuplurilor din tabele (Comanda DELETE)

Instrucţiunea DELETE şterge unul sau mai multe rânduri dintr-un tabel. Instrucţiunea poate să
folosească şi o vizualizare, dar numai dacă aceasta se bazează pe un singur tabel (ceea ce înseamnă că
instrucţiunile DELETE nu pot fi folosite pentru vizualizări care conţin uniuni). În instrucţiunile
DELETE nu sunt referite niciodată coloane, doarece instrucţiunea şterge rânduri întregi de date,
inclusiv toate valorile datelor (toate coloanele) din rândurile afectate. Dacă se şterge o singură valoare
din rândurile existente, se folosește instrucţiunea UPDATE pentru a înlocui valorile respective cu
valori nule (presupunând că valorile nule sunt permise în acele coloane).

Sintaxa generală a instrucţiunii DELETE este:


DELETE FROM nume_tabel_sau_vizualizare [AS alias]
[ WHERE conditie ];

Se remarcă următoarele:
• comanda DELETE nu şterge structura tabelului;
• clauza WHERE este opţională. Totuşi, este folosită aproape întotdeauna, deoarece o
instrucţiune DELETE fără o clauză WHERE încearcă să şteargă toate rândurile din tabel.
În clauza WHERE pot fi folosite şi subcereri;
• atunci când este inclusă, clauza WHERE specifică rândurile care urmează să fie şterse. Orice
rând pentru care condiţia WHERE este evaluată ca adevărată este şters din tabel;
• nu se pot şterge rânduri dacă se încalcă o restricţie referenţială. În general, rândurile
subordonate trebuie şterse înaintea rândurilor părinte;
• pentru a şterge linii identificate cu ajutorul valorilor din alte tabele, se utilizează subcereri;

44
• comanda nu poate fi folosită pentru ştergerea valorilor unui câmp individual. Acest lucru se
poate realiza cu ajutorul comenzii UPDATE.

Dacă se încearcă ştergerea unei înregistrări care conţine o valoare implicată într-o constrângere de
integritate, atunci va fi returnată o eroare.

În cazul în care constrângerea de integritate referenţială a fost definită utilizând opţiunea ON DELETE
CASCADE, atunci instrucţiunea DELETE va şterge atât liniile indicate, cât şi liniile „copil“ din
tabelele corespunzătoare.

Ştergerile accidentale pot fi omise, restaurându-se valorile iniţiale prin comanda AUTOCOMMIT
OFF.

Exemplu: Stergeţi toate produsele care expiră înainte de 1 Ianuarie, 2017. Ştergerile să nu fie efectuate
imediat ci ulterior.
SET AUTOCOMMIT OFF
DELETE FROM PRODUSE
WHERE data_expirarii > TO_DATE('01-01-17', 'DD-MM-YY');

Ştergerea înregistrărilor folosind valori dintr-un alt tabel


Pot fi folosite subinterogări pentru a şterge înregistrări dintr-un tabel, folosind informaţiile din altul.

Exemplul de mai jos şterge toate produsele cu denumirea PAINE. Subinterogarea caută în tabelul
PRODUSE codul produsului PAINE, apoi furnizează codul interogării principale, care şterge
înregistrările din LINII_PRODUSE pe baza acestuia.
DELETE FROM LINII_PRODUSE
WHERE cod_produs =
(SELECT cod_produs
FROM PRODUSE
WHERE denumire_produs = 'PAINE');

Încălcarea constrângerii de integritate


Dacă se încerarcă ştergerea unei înregistrări care conţine un câmp cu o valoare legată de o
constrângere de integritate, se obţine o eroare.

În exemplul de mai jos se încearcă ştergerea produsului cu codul 10 din tabelul PRODUSE, dar
aceasta provoacă o eroare, deoarece codul produsului este folosit ca şi cheie externă în tabelul
LINII_FACTURI.

Dacă înregistrarea părinte, care se încearcă să se şteargă, are înregistrări fii, atunci se primește un
mesaj de eroare: child record found violation ORA - 02292.
DELETE FROM PRODUSE
WHERE cod_produs = 50;

7. Limbajul de control al datelor (LCD)


Limbajul pentru controlul datelor (LCD – Data Control Language) include instrucţiuni SQL care
permit administratorilor să controleze accesul la datele din baza de date şi folosirea diferitelor
privilegii ale sistemului DBMS, cum ar fi privilegiul de oprire şi pornire a bazei de date.

45
Controlul unei baze de date cu ajutorul SQL-ului se referă la:
• asigurarea confidentialităţii şi securităţii datelor;
• organizarea fizică a datelor;
• realizarea unor performanţe;
• reluarea unor acţiuni în cazul unei defecţiuni;
• garantarea coerenţei datelor în cazul prelucrării 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.

Comenzile de control la dispoziția administratorului (DBA) - GRANT, REVOKE – sunt utilizate pentru
a da sau a lua drepturi de acces (la comenzi LMD, deci la operarea unor modificări a bazei de date).

Sintaxa:
GRANT
[Privilegii]
ON
TO
Utilizator IDENTIFIED BY ’DenumireParola’;

REVOKE
[Privilegii]
ON
TO
Utilizator IDENTIFIED BY ’DenumireParola’;

7.1. Asigurarea confidențialității și securității datelor

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. Pentru acestea, există
mecanisme care permit identificarea şi autentificarea utilizatorilor şi există proceduri de acces
autorizat care depind de date şi de utilizator, cum ar fi:
 conturi pentru utilizatori, cu parolă folosită pentru autentificare;
 grupuri, roluri, privilegiile și profilurile - acestea permit nu numai constrângeri ci și stabilirea
unei politici de securitate. Pentru a accesa un obiect, un utilizator trebuie să aibă privilegiile
necesare. Privilegiile pot fi acordate direct unui utilizator sau pot fi grupate în roluri, care la
rândul lor pot fi acordate utilizatorului.
Exemplu: Un forum de discuții are utilizatori grupați pe roluri ca: administrator, moderator,
membru. Fiecare rol poate avea privilegii diferite: administratorul poate configura baza de
date (modifică schema, adaugă tabele, configurează interfața); moderatorul poate valida,
modifica, șterge postările membrilor; membrii pot adăuga înregistrări.

7.2. Reluarea unor acțiuni în cazul unei defecțiuni

Reluarea unor acțiuni în cazul apariţiei unei defecțiuni hard sau soft presupune recuperarea ultimei
stări coerente a bazei de date. În funcţie de defecţiunea care a determinat întreruperea lucrului,
restaurarea bazei de date se realizează automat de SGBD sau manual, adică necesită intervenţie
umană.

46
Salvarea bazei de date se realizează conform unei strategii existând combinaţiile:
 copii ale bazei de date şi copii ale jurnalelor acestora;
 jurnale ale tranzacţiilor;
 jurnale ale imaginii înregistrărilor din baza de date.

Copiile bazei de date - pot fi realizate automat de sistem la anumite intervale de timp sau la comanda
administratorului bazei de date, ori de câte ori este nevoie şi de obicei pe un alt suport magnetic decât
cele pe care rezidă baza de date. Aceste copii pot fi utilizate doar în situaţia în care prelucrările
efectuate între momentul realizării copiilor şi cel al apariţiei unei defecţiuni pot fi reluate. Acest lucru
este posibil doar dacă prelucrările sunt efectuate într-o secvenţă cunoscută iar timpul necesar pentru
reprocesarea nu este foarte mare. Durata mare de execuţie pentru astfel de copii face ca anumite
SGBD-uri să recurgă la copii ale jurnalelor bazei de date. Volumul datelor care vor fi copiate în acest
caz va fi mai mic, iar procesul de restaurare va implica într-o măsură mai mică intervenţia umană.

Jurnalul tranzacţiilor - este un fişier special întreţinut de SGBD, în care sunt memorate informaţiile
despre tranzacţiile efectuate asupra bazei de date, cum sunt:
 identificatorul sau codul tranzacţiei;
 momentul începerii execuţiei tranzacţiei;
 numărul terminalului sau identificatorul utilizatorului care a iniţiat tranzacţia;
 datele introduse;
 înregistrările modificate şi tipul modificării.

Jurnalul imaginilor înregistrărilor din baza de date - se deosebeşte de jurnalul tranzacţiilor prin aceea
că el nu conţine descrierea operaţiilor efectuate asupra bazei de date, ci efectul acestora.

7.3. Garantarea coerenței datelor în cazul prelucrării concurente

Sistemul de gestiune a bazelor de date asigură accesul concurent al mai multor utilizatori la baza de
date. Fiecare utilizator trebuie să aibă o vedere validă și consistentă asupra bazei de date, incluzând și
modificările făcute de alți utilizatori; în același timp, procesarea incorectă a datelor trebuie evitată,
pentru a nu afecta consistența datelor sau integritatea acestora.

În funcție de complexitatea operației de acces concurent, problema gestionării concurenței se


complică:
 acces concurent a mai multor utilizatori numai pentru consultarea datelor;
 acces concurent a mai multor utilizatori cu unul dintre ei modificând datele;
 acces concurent a mai multor utilizatori cu mai mulți dintre ei modificând datele.

Pentru ultimele două, se utilizează blocarea datelor (primul utilizator care le accesează, le blochează).
Cu cât dimensiunea datelor blocate este mai mică, cu atât gestionarea accesului concurențial este mai
eficientă.

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ă (COMMIT), iar modificările (INSERT, DELETE, UPDATE) aduse de

47
tranzacţie devin definitive (modificările sunt înregistrate şi sunt vizibile tuturor utilizatorilor). Din
acest punct prima instrucţiune SQL executabilă va genera automat începutul unei noi tranzacţii.

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ă (ROLLBACK). 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. Executarea unei instrucţiuni ROLLBACK presupune terminarea tranzacţiei curente
şi începerea unei noi tranzacţii.

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.

Controlul tranzacţiilor constă în:


• definirea începutului şi sfârşitului unei tranzacţii;
• validarea sau anularea acesteia;
• o 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:


• SET AUTO[COMMIT] {ON | OFF} - 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).
Dacă este setată pe ON, fiecare comandă LMD individuală duce la salvarea modificărilor,
imediat ce este executată. Nu se mai poate reveni la situaţia dinainte (un rollback nu mai este
posibil).
Dacă este setată pe OFF, COMMIT poate fi dată explicit. De asemeni, COMMIT este
executată odată cu o comanda LDD sau la ieşirea din SQL*Plus;
• ROLLBACK [TO [SAVEPOINT] savepoint] - permite restaurarea unei stări
anterioare a bazei de date.
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;
• ROLLBACK TO SAVEPOINT name - şterge savepoint-ul şi toate schimbările de după el
(temporare);
• SAVEPOINT name - folosită în conjuncţie cu instrucţiunea ROLLBACK, pentru definirea
unor puncte de salvare în fluxul programului. 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ă. În acest mod este posibilă împărţirea
tranzacţiei în subtranzacţii.
Punctele de salvare nu sunt obiecte ale schemei, prin urmare, nu sunt referite în dicţionarul
datelor. 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;

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;
48
• 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.

8. Exerciţii de fixare a noţiunilor

Procedura de instalare Oracle XE (Oracle Database 11g Express Edition) și


Apex (Oracle Application Express) pe Windows

Oracle XE este o versiune de bază de date ideală pentru training și inițiere în tehnologia bazelor de
date. Este gratuită și poate fi instalată pe orice mașina (fizică sau virtuală) singurele ei limitari fiind
cele legate de spațiul de stocare (poate folosi până la 11 GB), respectiv memorie și processor (până la
1 Gb RAM și 1 procesor/mașină). Suportul este asigurat pe Oracle Discussion Forum, o comunitate
monitorizată de Oracle și alți experți în domeniu. Pașii preliminari sunt:
1. Se descarcă Oracle XE în funcție de sistemul de operare pe care se va instala (32 bit/64 bit):
http://www.oracle.com/technetwork/database/database-technologies/express-
edition/downloads/index.html
2. Se descarcă Apex:
http://www.oracle.com/technetwork/developer-tools/apex/downloads/index.html
3. Se instalează Oracle XE, singurele input-uri așteptate de la utilizator fiind:
a. calea unde va fi instalat (default pe drive-ul C)
b. parola pentru administratorul bazei de date (sysdba)
Datorită faptului că Oracle XE conține o versiune mai veche de Apex, aceasta trebuie
upgradată cu versiunea descarcată la pasul 2. Pașii de upgrade sunt următorii:

49
1. Se dezarhivează versiunea descarcată la pasul 2 în directorul C:\apex
2. Se deschide un command prompt și se navighează în calea de mai sus:
cd C:\apex
3. Folosind SQLPLUS ne conectăm la baza de date instalată anterior:
{Command prompt} C:\apex> sqlplus /nolog
SQL> CONNECT SYS as SYSDBA
Enter Password: SYS_Password // parola de sysdba setată anterior
4. Se instalează Apex:
SQL> @apexins SYSAUX SYSAUX TEMP /i/
5. Se loghează din nou în SQL Plus și se execută comanda:
{Command prompt} C:\apex> sqlplus /nolog
SQL> CONNECT SYS as SYSDBA
Enter Password: SYS_Password
SQL> @apxldimg.sql C:\
6. Se introduce parola pentru apex-ul nou instalat:
SQL> @apxchpwd
Enter password for Application Express ADMIN account.
7. Pentru a accesa Apex-ul nou instalat se accesează link-ul:
http://localhost:8080/apex/apex_admin
în Username, enter ADMIN
în Password, enter the password entered în Step 6

50
ORACLE SQL DEVELOPER

Crearea unui user


-- USER SQL
CREATE USER PROF IDENTIFIED BY 123456
DEFAULT TABLESPACE "USERS"
TEMPORARY TABLESPACE "TEMP";
-- QUOTAS
-- ROLES
GRANT "CONNECT" TO PROF WITH ADMIN OPTION;
GRANT "RESOURCE" TO PROF WITH ADMIN OPTION;
ALTER USER PROF DEFAULT ROLE "CONNECT","RESOURCE";
-- SYSTEM PRIVILEGES
GRANT CREATE TRIGGER TO PROF WITH ADMIN OPTION;
GRANT CREATE TABLE TO PROF WITH ADMIN OPTION;
GRANT CREATE VIEW TO PROF WITH ADMIN OPTION;
GRANT CREATE SEQUENCE TO PROF WITH ADMIN OPTION;
GRANT CREATE SYNONYM TO PROF WITH ADMIN OPTION;
GRANT UNLIMITED TABLESPACE TO PROF WITH ADMIN OPTION;
GRANT CREATE PROCEDURE TO PROF WITH ADMIN OPTION;

51
APLICAȚII REZOLVATE

Fie baza de date H-R cu diagrama reprezentată în figura următoare:

Să se creeze tabelele din figura de mai sus în care sa fie precizate restricțiile de integritate:

DDL (Data Definition Language)

Crearea tabelelor
create table prof.emp --contine angajatii unei firme
(empno number(6,0) constraint emp_empno_pk
primary key, --cheia primara
firstname varchar2(25),
lastname varchar2(25) constraint
emp_lastname_nn not null,
cnp varchar(13),
phone varchar2(20),
email char(50) constraint emp_email_nn not
null,
adr varchar2(60) default 'necunoscuta',
jobid varchar2(10) constraint emp_jobid_nn
not null,
hiredate date constraint
emp_hiredate_nn not null, --data angajarii pe postul actual
mgr number(6,0), --cod manager
sal number(9,2),
comm number(9,2), --comision
deptno number(4,0)
);
52
Vizualizarea campurilor
describe prof.emp;

create table prof.regions


(regionid number(4,0) constraint
regions_regionid_pk primary key,
region varchar2(40) --denumirea regiunii
);
describe prof.regions;

create table prof.countries


(countryid char(3) constraint
countries_countryid_pk primary key,
country varchar2(40), --denumire
regionid number(3,0) constraint
countries_regionid_fk
references
prof.regions (regionid) --cheie straina
);
describe prof.countries;

create table prof.locations


(locid number(4,0) constraint
locations_locid_pk primary key,
street varchar2(40),
postalcode varchar2 (12),
city varchar2(20) constraint
locations_city_nn not null,
stateprovince varchar2(25) default
'bucharest', --judetul
countryid char(3) constraint
locations_countryid_fk
references
prof.countries (countryid)
);
describe prof.locations;

create table prof.dept --descrie departamentele din care fac parte


angajatii
(deptno number(4,0) constraint dept_deptno_pk
primary key,
dname varchar2(40) constraint dept_dname_uk
unique, --cheie unica
locid number(4,0) constraint dept_locid_fk
references
prof.locations(locid)
);
describe prof.dept;

53
create table prof.jobs
(jobid varchar2(10) constraint jobs_jobid_pk
primary key,
job varchar2(40) constraint jobs_job_nn not
null, --denumire job
minsal number(9,2),
maxsal number(9,2)
);
describe prof.jobs;

create table prof.jobgrades


(gradelevel varchar2(3),
lowestsal number(9,2),
highestsal number(9,2)
);
describe prof.jobgrades;

create table prof.jobhistory


(empno number(6,0) constraint
jobhistory_empno_fk
references prof.emp(empno)
constraint
jobhistory_empno_nn not null,
startdate date constraint
jobhistory_startdate_nn not null,
enddate date constraint
jobhistory_enddate_nn not null,
jobid varchar2(10) constraint
jobhistory_jobid_fk
references
prof.jobs(jobid)
constraint
jobhistory_jobid_nn not null,
deptno number(4,0) constraint
jobhistory_deptno_fk
references
prof.dept(deptno)
);
describe prof.jobhistory;

Schema curenta
alter session set current_schema=prof;

Adaugarea constrangerilor
alter table emp
add constraint emp_deptno_fk foreign key(deptno)
references prof.dept(deptno);

alter table emp


add constraint emp_jobid_fk foreign key(jobid)
references prof.jobs(jobid);
54
DML (Data Manipulation Language): INSERT, UPDATE, DELETE
Introducerea valorilor in tabele
--introducerea valorilor in tabelul jobgrade
insert into jobgrades values('a',1000,2999);
…………….
select * from jobgrades;

-- introducerea valorilor in tabelul job


insert into jobs values('ad_pres' , 'president',2000,40000);
……………………
select * from jobs;

-- introducerea valorilor in tabelul region


insert into regions values (1,'europe');
……………………………
select * from regions;

-- introducerea valorilor in tabelul countries


insert into countries values('ca','canada',2);
……………………………
select * from countries;

-- introducerea valorilor in tabelul location


insert into locations values(1,'2014 jabberwocky
rd','26192','southlake','texas','us');
--sau
insert into prof.locations(locid, street, postalcode, city,
stateprovince, countryid) values (7,'ghica
13','o71','bucharest','bucharest','ro');
--sau
insert into prof.locations (locid,street,postalcode,city, countryid)
values(6,'fabricii 46g','o73','bucharest','ro');
…………….
select * from locations;

-- introducerea valorilor in tabelul dept


insert into dept values(10,'adminstration',1);
…………………………………
select * from dept;
-- sau

Inserare de valori folosind variabile de substitutie - ampersand unic (&)


Enter value for department_id: 120
Enter value for department_name: oracle
Enter value for location_id: 1
insert into dept(deptno, dname, locid) values (&department_id,
'&department_name',&location_id);

55
Crearea unui script pentru manipularea datelor
Prin intermediul comenzii sql*plus ACCEPT, mesajele afisate la cererea introducerii valorilor pot fi
modificate.
• accept - memoreaza valoarea intr-o variabila;
• prompt - afiseaza textul specificat.

accept deptno prompt 'Introduceti codul departamentului:'


accept dname prompt 'Introduceti denumirea departamentului:'
accept locin prompt 'Introduceti codul localitatii:'
insert into dept (deptno, dname, locid) values (&deptno, '&dname',
&locid);
select * from dept;

--sau
--sa se adauge in tabela dept datele pentru noul departament (cu
date introduse de la tastatura).
prompt Sa se adauge in dept datele pentru:
insert into dept (deptno, dname,locid)
values(&deptno,'&dname',&locid);
select* from dept;

-- introducerea valorilor in tabelul emp


insert into emp values (7839, 'KINGA', 'R','1821110222233',
'0757000000', 'n.iacob@gmail.com', 'BUCURESTI', 'ad_pres',
to_date('20-01-2017','dd-mm-yyyy'), null, 1500, 300, 10);
insert into emp values (7900, 'JAMES','B', '1931117222233',
'0757022000', 'n.iacob.mi@spiruharet.ro', 'BUCURESTI','mk_rep',
to_date('30-10-2017','dd-mm-yyyy'), 7839, 8950, 2000, 10);
……………………
select * from emp;

-- introducerea valorilor in tabelul jobhistory


insert into jobhistory values (7839,to_date('13-01-2005','dd-mm-
yyyy'),to_date('24-07-2017','dd-mm-yyyy'),'it_prog',10);
………………
select * from jobhistory;

Copierea inregistrarilor dintr-un alt tabel


Numarul si tipul campurilor (coloanelor) din lista specificata in comanda insert trebuie sa corespunda
numarului si tipului valorilor din subinterogare.
create table managers
(id number(4,0),
name varchar2(30),
salary number(7,2));
insert into managers (id, name, salary)
select empno, firstname, sal from emp
where mgr is null;
select * from managers;

56
Modificarea tabelelor
--adaugati o noua coloana tabelului emp care sa contina comentarii
alter table emp
add (comments varchar2(80));
describe prof.emp;

--modificati dimensiunea coloanei firstname la 30 si pe cea a salariului la 12 cu 3 zecimale


alter table emp
modify (firstname varchar2(30), sal number(12,3));
describe prof.emp;

--eliminati coloana comments din tabelul emp


alter table emp
drop column comments;
describe prof.emp;

--redenumiti tabelul emp cu ang


rename emp to ang;
describe prof.ang;

--eliminati tabelul ang


drop table ang;

Tipuri de constrangeri
 Constrangerile de tip CHECK se pot implementa la nivel de coloana doar daca nu refera o alta
coloana a tabelului
--sa se adauge restrictia de validare: sal>0
alter table emp
add (constraint emp_sal_chk check(sal>0);

 Constrangerea de tip NOT NULL se poate declara doar la nivel de coloana

 Adaugarea unei chei primare (PRIMARY KEY)


alter table emp
add constraint emp_empno_pk primary key(empno);

 Adaugati o constrangere de cheie externa (foreign key) pe deptno din emp


alter table emp
add constraint emp_deptno_fk foreign key(deptno)
references dept(deptno);

 Adaugarea unei chei unice (UNIQUE)


alter table dept
add constraint dept_dname_uk unique(dname);

Instructiunnea SELECT
Sintaxa generala
select [all/distinct/unique] lista de selectie (coloane, alias)
from lista de relatii (tabele)
where conditie de cautare asupra liniilor
57
group by lista de atribute care permit partitionarea
having conditie asupra partitiilor
order by lista de atribute [asc|desc];

--afisati numele angajatilor


select firstname from emp;

--afisati codul, numele si salariul angajatilor


select empno, firstname, sal from emp;

--afisati date despre angajati


select * from emp;

Tipuri de operatori:
 operatori aritmetici: +, -, * , ...
 operatori de comparatie: <, <=, >, >=, =, <>, between, in, is, like...
 operatori logici: and, or, not
 operatori relationali: union, intersec, minus

--afisati salariul anual


select empno, sal, sal * 12 from emp;

Definirea alias-urilor pentru coloane. Cuvantul cheie "as" poate lipsi!


--sa se afiseze codul angajatilor si salariul anual
select empno cod_ang, sal, sal*12 as sal_anual from emp;

Functia generala nvl (expr1, expr2) forteaza functiile grup sa includa valori nulle.
select firstname, sal, sal*12, comm, sal*12 + nvl(comm,0)
venituri_anuale from emp;

Operatorul de concatenare (||)


--sa se afiseze numele fiecarui angajat si codul sefului direct superior
select firstname ||' lucreaza pentru managerul cu codul: ' || mgr
angajat_sef from emp;

Randuri duplicate
select deptno from emp;

Eliminarea randurilor duplicate


select distinct deptno from emp;

Ordonarea inregsitrarilor
--afisati angajatii in ordine alfabetica
select firstname
from emp
order by firstname;

58
--sa se afiseze numele si salariul tuturor angajatilor. Rezultatele sa se afiseze crescator dupa
numarul departamentului si descrescator dupa salariu:
select deptno, firstname, sal
from emp
order by deptno, sal desc;

Sortarea dupa aliasul numelui coloanei


--afisati veniturile anuale in ordine descrescatoare
select firstname, sal*12 + nvl(comm,0) venituri_anuale
from emp
order by venituri_anuale desc;

Sortarea dupa pozitia coloanei


select empno, firstname, sal, sal*12
from emp
order by 2;

Clauza WHERE
--ulterior se poate adauga la linia de stare (o selectie explicita, prin introducerea codului
corespunzator managerului).
select *
from emp
where mgr=&cod_manager; --7698

--sau, o selectie implicita prin specificarea direct a codului departamentului:


--afisati subordonatii managerului cu codul 7698
select *
from emp
where mgr=7698;

--afisati numele salariatilor angajati inainte de 01-jan-2017 pe job-ul actual


select empno, firstname,hiredate
from emp
where hiredate <= '01-jan-2017';

--afisati numele persoanelor angajate intre '02-apr-2015' si '08-dec-2016'


select firstname,hiredate
from emp
where hiredate between '02-apr-2015' and '08-dec-2016';

Operatorul in - egal cu oricare din elementele listei


--afisati date depre angajatii din departamentele 10, 20, 30
select firstname, deptno, jobid
from emp
where deptno in (10, 20, 30);

--afisati managerii
select firstname, deptno
from emp
where mgr is null;

59
--afisati numele care incep cu litera s, procent (%)
select *
from emp
where firstname like 's%';

--afisati numele care contin exact 5 caractere, caracterul underscore (_)


select firstname
from emp
where firstname like '_____';

--sa se selecteze numele, adresa si emailul tuturor persoanelor din bucuresti care au adresa de
email pe gmail sau spiruharet.
select firstname, adr, email
from emp
where adr like '%bucuresti%' and (email like '%gmail%' or email like
'%spiruharet%');

Negarea comparatiei
--afisati date depre angajatii care nu fac parte din departamentele 10 si 30
select *
from emp
where deptno not in(10,30);

--afisati numele care nu incep cu litera s


select *
from emp
where firstname not like 's%';

--afisati angajatii care au primit prima


select *
from emp
where comm is not null;

--afisati numele persoanelor care nu s-au angajat in perioada '02-apr-2016' si '08-dec-2016'


select firstname,hiredate
from emp
where hiredate not between '02-apr-2016' and '08-dec-2016';

Conditii multiple
--afisati salariatii din departamentul 10 care au salariul cel putin 1000
select *
from emp
where deptno = 10 and sal >= 1000;

--
select *
from emp
where deptno = 20 and jobid='ac_mgr' or jobid ='ad_vp' ;

60
--
select *
from emp
where deptno = 20 and (jobid='ac_mgr' or jobid ='ad_vp');

Functii de tip caracter - accepta argumente de tip caracter si intorc rezultate de tip caracter
(chr, concat, initcap, lower, upper, lpad & rpad, ltrim & rtrim, translate, replace, substr etc.) sau
numeric (ascii, instr, length).

--afisati toate persoanele al caror nume contine litera a (cu litere mici) pe orice pozitie
select *
from emp
where lower(firstname) like '%a%';

--sa se afiseze departamentele din alte localitati decat Bucuresti (cu litere mari).
select *
from locations
where upper (city) <> 'bucuresti' ;

--prima litera mare, restul mici


select initcap(city) from locations;

--lpad(string,len,pstring)
--rpad(string,len,pstring)
--completatii cu spatii la stanga
select lpad(city,10,'-') from locations;

----completatii cu spatii la dreapta


select rpad(city,10,'-') from locations;

--substr(string,pos,len)
--extrageti din coloanal CNP din tabelum emp, ziua, luna si anul nasterii
select firstname as numele, substr(cnp,6,2) as ziua, substr(cnp,4,2)
luna, substr(cnp,2,2) anul_nasterii
from emp;

--instr(string,search)
--instr(string,search,pos,n)
--in numele localitatilor, determinati pozitia de inceput pe care se gaseste subsirul tt
select city, instr(city,'tt') from locations;

--ltrim(string,rem)
--rtrim(string,rem)
--
select ltrim(' tech', ' ') from dual;
--
select rtrim('tech ', ' ') from dual;

--length(string)
--sa se afiseze lungimea atributului nume din tabela emp
select firstname, length (firstname) lungime_nume from emp;
61
--translate(string,from,to)
--in denumirea localitatilor inlocuiti litera o cu m
select city, translate(city,'o','m') from locations;

--replace(string,search,replace)
--replace(string,search)

--in denumirea localitatilor inlocuiti subsirul th cu g


select city, replace(city,'th','g') from locations;

Functii de tip numeric: mod, abs, sqrt,exp, de calcul trigonometric (sin, sinh, tan, tanh, cos,
cosh, ctg etc.; de calcul al logaritmului: ln, log, lg; de calcul al puterilor: pow; de rotunjire: floor, ceil,
round, trunc, etc.) - accepta argumente de tip numeric si intorc rezultate de tip numeric.

--round(number,n)
--afisati media primelor rotunjita la 2 zecimale
select avg(nvl(comm,0)), round (avg(nvl(comm,0)),2)from emp;

--trunc(number,n)
select avg(nvl(comm,0)),trunc (avg(nvl(comm,0)),1) from emp;

Functia trunc(data1,'char') gaseste prima zi a lunii care e continuta in data1, daca char = 'month',
sau gaseste prima zi a anului care contine data1 daca char= 'year'.
select sysdate data_curenta,
trunc (sysdate, 'month') prima_zi_luna,
trunc (sysdate,'year') prima_zi_an
from sys.dual;

--ceil(number)
--floor(number)
select avg(nvl(comm,0)), ceil(avg(nvl(comm,0))) from emp;

--
select avg(nvl(comm,0)), floor(avg(nvl(comm,0))) from emp;

Functii de tip data calendaristica (add_months, last_day, months_ between, next_day,


round, trunc, sysdate etc.) - accepta argumente de tip data calendaristica si intorc rezultate de tip data
calendaristica cu exceptia functiei month_between care intoarce o valoare numerica;

--afisaza data din sistem


select sysdate from sys.dual;

--months_between(date1,date2)
select firstname, hiredate,
round(months_between(sysdate,hiredate),0) from emp;

--add_months(date,mon)
select firstname, hiredate, add_months(hiredate,2) from emp;

62
--next_day(date,day)
--sa se afiseze urmatoarea zi de sambata (dupa data curenta-->sysdate)
select next_day (sysdate,'saturday') urmatoarea_sambata from dual;

--last_day(date)
select firstname, hiredate, last_day(hiredate) from emp;

--round(date,what),unde what = month sau year


--sa se afiseze angajatii care au cuvantul “james” in nume impreuna cu vechimea acestora.
Vechimea se va afisa in doua moduri: rotunjita in ani si in ani cu luni.
select firstname,
round ((sysdate-hiredate)/365, 0) ani,
round ((sysdate-hiredate)/365, 1) ani_cu_luni
from emp
where firstname like '%james%';

--sa se afiseze numele angajatilor si data implinirii limitei de varsta pentru pensionare (65 de
ani) precum si numarul de luni ramase pana la pensionare (65 ani*12 luni).
select firstname, datan,
add_months (datan, 65*12) data_pensionare,
round (months_between(add_months(datan,65*12),sysdate),2)
luni_ramase_pensionare
from emp;

Functii de conversie: to_char, to_number, to_date - fac conversia dintr-un tip de data in altul;
--to_char(number)
--to_char(number,format)
--to_char(date)
--to_char(date,format)

-- afisati data si ora din sistem


select to_char(sysdate,'dd month yyyy hh24:mi:ss') from dual;

--to_date(string)
--to_date(string,format)
--
select to_date(hiredate,'dd-mon-yyyy') from emp;

Functii care accepta orice tip de tip de date: nvl, greatest & least, decode
--
select nvl(comm,0)from emp;

--greatest(value1,value2, …)
--least(value1,value2, …)

--afisati cea mai mare valoare din sirul de numere 10,20,50,40


select greatest(10,20,50,40) from dual;

--afisati cea mai mica valoare din sirul de numere 10,20,50,40


select least(10,20,50,40) from dual;

63
Functia generala decode evalueaza o expresie intr-un mod similar structurii if-then-else.
decode( value,
, search1, result1
[, search2, result2 . . .]
, default)

Sa se evalueze valoarea lui jobid astfel:


- daca jobid este it_prog, sporul de salariu este de 10%;
- daca jobid este ac_cccount, sporul de salariu este de 15%
- iar daca jobid este ac_mgr, sporul de salariu este de 20%.
- pentru celelalte functii salariile nu se modifica.

select jobid, sal,


decode(jobid,
'it_prog', sal*1.1,
'ac_cccount', sal*1.15,
'ac_mgr', sal*1.20,
sal) revista_salarii
from emp;

Functii de grup: avg, count, max, min, stddev, sum, varianve


--sa se afiseze numarul de inregistrari din tabela dept
select count (*) nr_inreg from dept;

--
select count(distinct jobid) from emp;

--sa se afiseze salariul de baza mediu, minim si maxim pentru toti salariatii cu codul cuprins
intre 7000 si 7500.
select sum(sal), round (avg (sal),2) mediu, min (sal) minim, max
(sal) maxim
from emp
where empno between 7000 and 7500;

Instructiunea CASE
--sa se specifice daca un angajat dat are salariu mic, mediu, bun sau excellent dupa cum este mai
mic decat 5000, cuprins intre [5000,10.000), cuprins intre [10.000,15.000] sau mai mare decat
15.000.
select firstname, sal,
(case
when sal <5000 then 'mic'
when sal <10000 then 'mediu'
when sal <=15000 then 'bun'
else 'excelent'
end) as calificare
from emp;

64
Gruparea datelor
Functiile de agregare se pot folosi ca extensii ale clauzei group by:
• rollup - permite instructiunii select sa calculeze niveluri de subtotal multiple peste un grup de
dimensiuni;
• cube - genereaza toate subtotalurile care pot fi calculate dintr-un cube pe dimensiunile
specificate;
• grouping;
• grouping set.

--in departamentul 30 afisati media salariilor pentru fiecare job, daca aceasta este mai mare de
3700
select jobid, round(avg(sal),2)
from emp
where deptno = 30
group by jobid
having round(avg(sal),2) > 3700;

Interogari din mai multe tabele


select emp.firstname,dept.dname
from emp,dept
where dept.deptno = emp.deptno;

Selectii din mai multe tabele folosind alias-uri la tabele


select e.firstname,d.dname
from emp e,dept d
where e.deptno = d.deptno;

--
select firstname, e.deptno, dname, jobid
from emp e, dept d
where e.deptno = d.deptno and jobid = 'ac_mgr';

--listeaza numele tuturor angajatiilor impreuna cu numele managerului lor:


select e1.firstname, e2.firstname
from emp e1, emp e2
where e1.mgr = e2.empno;

--
select e.firstname, d.dname, d.deptno
from emp e, dept d
where e.deptno(+) = d.deptno;

Union
--afisaja job-urile din ambele departamente (10 si 30)
select jobid, deptno from emp
where deptno=10
union
select jobid, deptno from emp
where deptno=30;

65
Intersect
select deptno from dept
intersect
select deptno from emp;

Minus
select deptno from dept
minus
select deptno from emp;

Subinterogari
select column(s)
from table(s)
where column(s) = (select column(s)
from table(s)
where condition(s) );

--afisati numele angajatilor cu salariul mimim


select firstname,jobid,sal
from emp
where sal =
(select min(sal)
from emp);

--afisati angajatii care lucreaza pe acelasi post cu angajatul care are numarul 7369, si au salariul
mai mic ca cel al angajatului cu numarul 7782.
select firstname, jobid, sal
from emp
where jobid=
(select jobid
from emp
where empno=7369)
and sal<
(select sal
from emp
where empno = 7782);

--afisati codul firmei cu cei mai multi angajatii:


select deptno , count(*) nr_ang
from emp
group by deptno
having count(*) =
( select max(count(*))
from emp
group by deptno );

--sa se afiseze numele angajatilor care au cel mai mic salariu din departamentul din care fac
parte.
select firstname,sal,deptno
from emp
where (deptno,sal) in
66
(select deptno,min(sal)
from emp
group by deptno);

--afisati angajatii cara nu au mai putin de 3 luni de la data angajarii


select firstname,hiredate
from emp
where hiredate not in
(select hiredate
from emp
where months_between(sysdate,hiredate) <= 3);

--sa se afiseze codul si numele angajatilor care au primele doua salarii cele mai mari.
select empno, firstname, sal
from
(select *
from emp
order by sal desc)
where rownum < 3;

Operatorii any/some, all


Operatorul any - compara valoarea cu fiecare valoare returnata de subinterogare luata separat

--afisati toti angajatii care lucreaza in departamentul 10 si care castiga cel putin la fel ca
angajatii din departamentul 30
select firstname,sal,deptno
from emp
where sal >= any
(select sal
from emp
where deptno = 30)
and deptno = 10;

Operatorul all - compara valoarea cu toate valorile returnate de subinterogare


--afisati toti angajatii ale caror salarii sunt mai mici decat salariile medii la nivel de
departamente.
select empno, firstname, jobid, sal, deptno
from emp
where sal < all
(select round(avg(sal),2)
from emp
group by deptno);

--sa se gaseasca postul avand cel mai scazut salariu mediu.


select jobid, avg(sal)
from emp
group by jobid
having avg(sal) =
(select min(avg(sal))
from emp
group by jobid);

67
--afisati toti angajatii care lucreaza in departament cu managerul lor
select empno,firstname,jobid,mgr,deptno
from emp e1
where deptno in
(select deptno
from emp e
where e.empno = e1.mgr);

Folosind subinterogari in clauza from afisati numele angajatilor care realizeaza mai mult decat
media salariilor din departamentul in care lucreaza.
select e.firstname , e.sal , e.deptno , d.salavg
from emp e ,
(select deptno , round(avg(sal),2) salavg
from emp
group by deptno ) d
where e.deptno = d.deptno and e.sal > d.salavg;

--sa se afiseze, pentru fiecare angajat in parte, ce procent reprezinta salariul din totalul de
salarii de pe departament.
select e.firstname,e.deptno, round(e.proc/d.total*100,2) procent
from
(select firstname, deptno, sal proc
from emp
group by firstname, deptno, sal) e,
(select deptno,sum (sal) total
from emp
group by deptno) d
where e.deptno=d.deptno ;

Interogarea datelor din mai multe relatii folosind tipuri de asocieri:


1) inner join (jonctiunea interna);
2) left outer join (semijonctiunea la stanga);
3) right outer join (semijonctiunea la dreapta).

inner join (jonctiunea interna). Sintaxa


select ...from tabel_a inner join tabel_b on (conditii de join)
- selecteaza toate informatiile din relatiile a si b care corespund conditiilor de asociere.

left outer join (semijonctiunea la stanga).


select ...from tabel_a left outer join tabel_b on (conditii de join)
- selecteaza toate informatiile din a, pe care le completeaza cu informatii din b, in masura in care
satisfac conditiile de join; acolo unde nu vor exista informatii din b, acestea vor fi completate cu null.
--
select e.firstname, d.dname
from emp e left outer join dept d
on (e.deptno = d.deptno);

right outer join (semijonctiunea la dreapta). Sintaxa


select ...from tabel_a right outer join tabel_b on (conditii de
join)

68
- selecteaza toate informatiile din b, pe care le completeaza cu informatii din a, in masura in care
satisfac conditiile de join; acolo unde nu vor exista informatii din a, acestea vor fi completate cu null.
--
select e.firstname, d.dname
from dept d right outer join emp e
on (e.deptno = d.deptno);
--
select e.firstname, d.deptno
from emp e full outer join dept d
on (e.deptno = d.deptno);

Modificarea tuplurilor din tabele (comanda UPDATE)


In functie de momentul in care se doreste realizarea modificarilor asupra bazei de date, utilizatorul
poate folosi una din urmatoarele comenzi:
• set autocommit imm[ediate] (schimbarile se efectueaza imediat);
• set autocommit off (schimbarile sunt pastrate intr-un buffer).
La executia comenzii commit se permanentizeaza schimbarile efectuate, iar la executia comenzii
rollback se renunta la schimbarile realizate.

update table [alias]_or view


set column [,column…] =
{expression,subquery}
[where condition];

--majorati salariile cu 15% pentru angajatii din departamentele 10 si 30.


update emp
set sal = sal *1.15
where deptno in (10,30);
select * from emp;

--transferati angajatul cu numarul 7782 la departamentul 20.


update emp
set deptno = 20
where empno = 7782;
select * from emp;

--majorati salariul cu 15% pentru persoanele care au salariul identic cu cel al angajatului cu
codul 7788.
update emp
set sal=sal * 1.15
where sal in
(select sal
from emp
where empno = 7788);
select firstname,empno,sal from emp;

--modificati pentru angajatul numarul 7782 departamentul si slujba astfel incat sa coincida cu
cele ale angajatului numarul 7499.
update emp
set (jobid, deptno) =
69
(select jobid, deptno
from emp
where empno = 7499)
where empno = 7782;
select * from emp;

--modificati toate numerele de telefon din judetul maramures, astfel ca prefixul sa nu mai fie
0262 ci 0362, din baza de date emp.
update emp
set phone=concat('0362', substr(phone, 5))
where substr(phone,1,4)='0262';
select firstname,phone from emp;

--adaugati o noua coloana tabelului emp care sa contina salnet


alter table emp
add (salnet number(9,2));
describe prof.emp;

--sa se calculeze salariul net


update emp
set salnet=(case nvl(comm,0)
when 0 then sal
else sal+nvl(comm,0) --sal+sal*nvl(comm,0)/100
end);
select firstname,sal,nvl(comm,0), salnet from emp;

Comanda DELETE
delete [from] table
[where condition];

--stergeti departamentul cu numarul 10 din tabelul dept


delete from dept
where deptno = 10;
select * from dept;

--stergeti toate persoanele angajate dupa data de 10 iulie 1987. Stergerile sa nu fie efectuate
imediat ci ulterior.
set autocommit off
delete from emp
where hiredate > to_date('10-07-1987', 'dd-mm-yyyy');
select * from emp;

Stergerea inregistrarilor folosind valori dintr-un alt tabel


--stergeti toti subordonatii managerului JONES. Subinterogarea cauta in tabelul emp codul numele
managerului, apoi furnizeaza codul interogarii principale, care sterge inregistrarile din tabelul emp pe
baza acestuia.
delete from emp
where mgr =
(select empno
from emp
where firstname = 'jones');
70
Procesarea tranzactiilor
commit [work];

--
update emp
set sal = sal * 1.25;
commit;
select firstname, sal
from emp;

rollback [work];
rollback [work] to savepoint_name;

--
update emp
set sal = sal * 1.05
where deptno in
(select deptno
from dept
where locid = '1');
rollback;
select firstname, sal from emp;

savepoint savepoint_name;
--
update dept
set dname = upper(dname);
savepoint done_dept;
update emp
set sal = sal * 1.1;
rollback to done_dept;
commit;
select * from dept;
select * from emp;

--sa se stearga inregistrari din tabelul emp in functie de conditia introdusa: hiredate <
to_date('10-07-1987', 'dd-mm-yyyy')
accept p_conditie prompt 'introduceti conditia de stergere: '
begin
delete from emp
where &p_conditie;
end;
/
select * from emp;

--sa se afiseze pentru toti angajatii valoarea comisionului introdus de la tastatura


accept comision prompt 'introduceti comisionul: '
select firstname, sal, sal*&comision/1000 valoare_comision
from emp;

71
Folosirea atributului %type
Putem defini tipul unei variabile in functie de tipul altei variabile sau a unei coloane de tabela.
--sa se creeze un bloc anonim in care se declara o variabila v_jobid de tip jobid (%type) a carei
valoare va fi codul jobului salariatului cu codul 7698
set serveroutput on
declare
v_jobid emp.jobid%type;
begin
select jobid into v_jobid
from emp
where empno=7698;
dbms_output.put_line('jobul este '|| v_jobid);
end;
/

--sa se specifice daca un angajat dat are salariu mare, mediu sau mic dupa cum este mai mare
decat 5000, cuprins intre 2000 si 5000 sau mai mic decat 2000
define p_empno = 7698;
declare
v_empno emp.empno%type := &p_empno;
v_sal emp.sal%type;
v_comentariu varchar2(10);
begin
select sal into v_sal
from emp
where empno = v_empno;
if v_sal < 2000 then v_comentariu := 'mic';
elsif v_sal between 2000 and 5000 then v_comentariu :=
'mediu';
else v_comentariu:= 'mare';
end if;
dbms_output.put_line('salariatul avand codul '|| v_empno ||'
are salariu '|| v_sal || ' considerat '|| v_comentariu);
end;
/
select * from emp;

Variabile de legatura - se utilizeaza pentru transmiterea valorii unor variabile din pl/sql catre
sql*plus. Referirea la o variabila de legatura se face in pl/sql prin prefixarea acestei variabile cu
caracterul „ : ”. In sql*plus, pentru declararea acestui tip de variabila se foloseste comanda
VARIABLE, iar valoarea variabilei de legatura va fi tiparita utilizand comanda PRINT.
--
variable v_jobid varchar2(35)
begin
select job into :v_jobid
from emp
where empno=7698;
--dbms_output.put_line('jobul este '|| :v_jobid);
end;
/
print v_jobid
72
--afisarea salariului maxim al angajatilor din tabelul emp utilizand variabile de legatura
variable g_max_sal number
declare
v_max_sal number;
begin
select max(sal) into v_max_sal
from emp;
:g_max_sal :=v_max_sal;
end;
/
print g_max_sal

--afisarea salariului total al angajatilor din departamentul 10 din tabelul emp folosind variabile
de legatura:
variable g_sal number
declare
v_sum_sal emp.sal%type;
v_deptno number not null :=10;
begin
select sum(sal)into v_sum_sal-- functie grup
from emp
where deptno=v_deptno;
:g_sal:=v_sum_sal;
end;
/
print g_sal

Crearea si stergerea vederilor/vizualizarilor


create [or replace] view [{force | noforce}] view
view_name[(alias_name[, alias_name...])]
as subquery
[with {check option | read only} constraint constraint_name];

create [or replace] view <view-name> [(<column(s)>)] as


<select-statement> [with check option [constraint <name>]];

--Sa se creeze vizualizarea v_emp care sa contina codul si numele salariatilor din tabelul emp.
--sa se afiseze continutul acesteia.
--sa se insereze o noua inregistrare in aceasta vizualizare.
--sa se analizeze structura si continutul vizualizarii.
--sa se stearga vizualizarea v_emp
create view v_emp(empno,firstname)
as
select empno,firstname
from emp;
insert into v_emp values (7777, 'ionescu');
desc v_emp;
select * from v_emp;
drop v_emp;

73
--sa se creeze vizualizarea emp_dept care sa contina codul si numele departamentului, numarul
de angajati din departamentul respectiv si suma alocata pentru plata salariilor.
create view emp_dept (deptno,dname,nr_ang,val_sal)
as
select e.deptno,dname,count(*) nr_ang,sum(sal) val_sal
from emp e, dept d
where d.deptno = e.deptno
group by e.deptno,dname;
select * from emp_dept;

--
drop view emp_dept;

Definirea generatorului de numere de secventa:


create sequence sequence_name
increment by n
start with val_start;

--Sa se creeze o secventa secv care incepe cu valoarea 10 si se termina cu valoarea 10000, pasul
de incrementare 10 si nu cicleaza. Acesta secventa secv se va folosi ulterior pentru generarea
automata de numere unice pentru campul empno din tabela emp. Se vor genera succesiv,
crescator, numerele cuprinse intre 10 si 10000.
create sequence secv --nume secventa
increment by 10 --pasul de incrementare
start with 10 --valoarea de pornire a secventei
maxvalue 10000 --valoarea maxima a secventei
nocycle; --secventa finita

--sa se modifice toate liniile din tabelul emp, regenerand codul angajatilor a.i. sa utilizeze
secventa secv. Sa se anuleze modificarile
update emp
set empno=secv.nextval;
rollback;

--sa se afiseze valoarea curenta a secventei


select secv.currval val from dual;

--sa se modifice pasul secventei secv de la 1 la 10000


alter sequence secv
increment by 10000;

--sa se sterga secventa secv .


drop sequence secv;

Index
create [unique] index index_name
on table_name
(column [,column . . .]);

74
--sa se creeze un index nou pe atributul empno din tabela emp.
create unique index emp_idx01
on prof.emp
(empno);

--
create unique index emp_idx02
on prof.emp
(empno,hiredate);

Sinonim
create synonym <name> for <user>.<table> ;

--
create synonym ang
for prof.emp;
select * from ang;

--sa se creeze un sinonim public pentru tabela emp din schema de obiecte
create public synonym prod for emp;

Operatii pe tabele structurate arborescent:


Sa se afiseze datele salariatilor subordonati direct salariatului JONES (sau...empno=7566).
Returneaza nivelul liniilor rezultat ale unei cereri ierarhice.
- 1 pentru radacina,
- 2 pentru subdirector (copil) al radacinii etc.
Se utilizeaza in comanda select si cluza connect by
select level,empno,firstname,job, mgr,deptno
from emp
where level=2
connect by prior empno=mgr
start with firstname = 'jones';
--start with empno=7566;

APLICATII PROPUSE

Se consideră entitățile INSTITUTIE și FUNCTIONAR care au următoarele atribute:

INSTITUTIE (COD, DENUMIRE, ADRESA)


FUNCTIONAR (ID, NUME, PRENUME, FUNCTIE, SALARIU, PRIMA, ID_SEF, COD)

Știind că într-o instituție pot lucra mai mulți funcționari, iar un funcționar lucrează într-o singură
instituție, se cere să se scrie următoarele interogări:

1. crearea celor două tabele cu impunerea constrângerilor aferente și inserarea înregistrărilor în


ambele tabele în conformitate cu cerințele problemei;
2. stabilind un impozit de 18% din salariu, să se afișeze funcționarii în ordine crescătoare după
impozit;

75
3. să se specifice dacă un funcționar dat are prima mare, medie sau mică după cum este mai mare
decât 4500, cuprinsă între 1500 și 4500 sau mai mică decât 1500;
4. realizați o creștere a salariilor funcționarilor după funcție (considerăm trei funcții: SECRETAR,
CONTABIL și ADMINISTRATOR, și creșteri corespunzătoare de 10%, 15% și respectiv 20%),
folosind subprograme;
5. afișați funcționarii care nu sunt în instituția cu codul 20 (presupunând existența unei instituții cu
COD=20);
6. afișați pentru fiecare funcție salariul mediu;
7. după excluderea funcționarilor cu salariile mai mici decât 2000, să se afișeze funcțiile pentru care
media salariilor este mai mare decât 2600;
8. pentru fiecare funcție să se afișeze funcționarii cu salariile maxime;
9. afișați funcționarii care câștigă mai mult decât salariul maxim al funcționarilor care aparțin
instituției cu DENUMIRE=”Oracle”;
10. ștergeți instituția cu codul 20 (presupunând existența unei instituții cu COD=20);
11. să se gasească funcția cu cel mai scăzut salariu mediu;
12. afișați salariului total al angajaților din instituția cu codul 10, folosind variabile de legatură;
13. afișați funcționarii care lucrează pe aceeași funcție cu funcționarul care are ID=7369, și au salariul
mai mare ca cel al funcționarului cu ID=7876;
14. afișați funcționarii care nu au subalterni.

Bibliografie
• Bâscă, O., Baze de date, Editura All, 1997;
• Cârstoiu, D., Baze de date, Editura Matrix ROM, 2009;
• Connolly T., Begg C., Database Systems. A Practical Approach to Design, Implementation,
and Management, Ed. Addison Wesley, 2005
(http://www.palinfonet.com/download/software2/database%20systems.pdf);
• Fusaru D., Arhitectura bazelor de date-mediul SQL, Editura Fundației România de Mâine,
2002;
• Popa M., Baze de date (Fundamente, exemple, teste de verificare), Editura Fundației România
de Mâine, București 2006;
• Popescu I., Modelarea bazelor de date, Editura Tehnică, 2002;
• Popescu M, Baze de date, Editura Renaissance, Bucureşti, 2010;
• ***, Informatică pentru examenul de licență, Universitatea SPIRU HARET, 2017;
• ORACLE, https://www.oracle.com/index.html.

76

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