Documente Academic
Documente Profesional
Documente Cultură
Gestiunea Bazelor de
date DISTRIBUITE în
ORACLE folosind PL/SQL
Joshua Print
Vrsac, Republica SRBIJA
2020
CUPRINS
CAPITOLUL I. BAZE DE DATE ŞI SISTEME DE GESTIUNE A
BAZELOR DE DATE ................................................................................ 6
1.1. CONCEPTE UTILIZATE ÎN STUDIUL BAZELOR DE DATE ŞI AL
SISTEMELOR DE GESTIUNE A BAZELOR DE DATE ........................................ 6
1.1.1. Metoda prelucrării prin fişiere independente ............................ 6
1.1.2. Baze de date ............................................................................... 9
1.1.3. Depozite de date ....................................................................... 16
1.1.4. Proiectarea bazelor de date ..................................................... 21
a.Analiza structurală sau statică ................................................................ 23
b. Integrarea modelelor sistemului ............................................................ 24
c. Proiectarea structurii bazei de date ........................................................ 24
d. Încărcarea datelor în baza de date ......................................................... 28
e. Exploatarea şi întreţinerea bazei de date ............................................... 28
1.2.1 Tipuri de relaţii şi structuri de reprezentare a relaţiilor în cadrul
unei baze de date ................................................................................ 29
1.2.2 Modele de organizare a datelor în bazele de date .................... 31
1.3 SISTEME DE GESTIUNE A BAZELOR DE DATE ...................................... 43
2.4. PROTECŢIA ŞI SECURITATEA BAZELOR DE DATE ............................... 51
SECURITATEA BAZEI DE DATE ................................................................. 54
CAPITOLUL II. MEDIUL INTEGRAT DE GESTIUNE ŞI
PROGRAMARE ORACLE ..................................................................... 60
2.1 CE ESTE ORACLE ............................................................................ 60
2.2 INSTALAREA SISTEMULUI ORACLE 11G EXPRESS EDITION ................ 64
2.3. ORACLE FORMS BUILDER................................................................. 74
2.4. OBIECTELE ŞI TIPUL ACESTORA ÎN FORMS BUILDER ......................... 76
2.4.1. Forme (Forms) ......................................................................... 76
2.4.2. Declanşatoare (Triggers) ......................................................... 76
2.4.3. Ferestre de Avertizare (Alerts) ................................................. 77
2.4.4. Blocuri de date (Data Blocks) .................................................. 77
2.4.5. Elemente (Items) ...................................................................... 78
2.4.6. Relaţii (Relations) .................................................................... 78
2.4.7. Canvas-uri (Canvases) ............................................................. 78
2.4.8. Editoare (Editors) .................................................................... 78
2.4.9. Parametrii (Parameters) .......................................................... 79
2.4.10. Unităţi de program (Program Units) ..................................... 79
2.4.11. Ferestre (Windows) ................................................................ 80
1
2.5. ORACLE11G: DATABASE / APPLICATION SERVER / DEVELOPER
SUITE ...................................................................................................... 80
2.5.1. Oracle11g Database ................................................................ 80
2.5.2. Oracle11g Application Server .................................................. 82
2.5.3. Oracle11g Developer Suite ...................................................... 83
CAPITOLUI IV. LIMBAJUL DE DEFINIRE, INTEROGARE ŞI
MANIPULARE A BAZELOR DE DATE SQL ..................................... 86
3.1. EVOLUŢIE ŞI PERFORMANŢE ............................................................. 86
3.2. COMENZI PENTRU DESCRIEREA DATELOR. LIMBAJUL DDL (DATA
DESCRIPTION LANGUAGE) ...................................................................... 93
3.3. COMENZI PENTRU INTEROGAREA BAZELOR DE DATE. FRAZA SELECT
................................................................................................................ 96
3.3.1 Interogări care utilizează operatorii asamblişti din algebra
relaţională .......................................................................................... 99
3.3.2 Interogări care utilizează operatorii relaţionali din algebra
relaţională ........................................................................................ 100
a. Selecţia ................................................................................................ 100
b. Proiecţia. Opţiunea ORDER BY ......................................................... 104
c. Joncţiunea............................................................................................ 105
d. Sub-consultări. Operatorul IN ............................................................. 106
e. Funcţii de agregare (statistice): COUNT, SUM, AVG, MAX, MIN ... 109
f. Gruparea tuplurilor. Clauzele GROUP BY şi HAVING...................... 111
5.4. Comenzi pentru actualizarea bazelor de date ........................... 117
3.4. COMENZI PENTRU MANIPULAREA DATELOR. LIMBAJUL DML (DATA
MANIPULATION LANGUAGE) ................................................................ 118
3.4.1 Adăugarea de înregistrări ....................................................... 118
3.4.2 Ştergerea înregistrărilor ......................................................... 119
3.4.3 Modificarea valorilor unor atribute ........................................ 120
3.5 INTEROGAREA A UNEI BAZE DE DATE ORACLE 11G ........................ 121
CAPITOLUI IV. LIMBAJUL PL/SQL ................................................ 124
4.1. INTRODUCERE ................................................................................ 124
4.2. CREAREA UNUL BLOC DE BAZA PL/SQL ....................................... 126
4.2.1 Tipurile de blocuri .................................................................. 127
4.2.2. Operatori, delimitatori şi variabile ........................................ 128
4.2.3. Atribuirea unei valori variabilei ............................................ 130
4.2.4. Declararea Constantelor ....................................................... 132
4.2.5 Citirea şi afişarea variabilelor în PL/SQL .............................. 132
4.2.6 Atributele de transfer automat a tipului de date ..................... 133
a. Atributul %TYPE ................................................................................ 133
b. Atributul %ROWTYPE ...................................................................... 133
2
4.3. INSTRUCŢIUNI ÎN PL/SQL .............................................................. 135
4.3.1 Instrucţiuni de atribuire .......................................................... 135
4.3.2 Structuri de control ................................................................. 138
a. Instrucţiunea IF ................................................................................... 138
b. Instructiunea IF-THEN-ELSIF ........................................................... 140
c. Instructiunea CASE ............................................................................. 141
4.3.3 Structuri de ciclare.................................................................. 143
a. LOOP .................................................................................................. 143
b. Folosirea comenzii EXIT ................................................................... 143
c. Comanda EXIT-WHEN ..................................................................... 144
d. Etichetarea unei blucle PL/SQL ......................................................... 145
e. Bucla WHILE-LOOP .......................................................................... 145
f. Utilizarea buclei FOR-LOOP .............................................................. 146
4.3.4 Folosirea excepţiilor ............................................................... 148
a. Tratarea excepţiilor predefinite ale Serverului Oracle ......................... 150
b. Tratarea excepţiilor non-predefinite Oracle Server ............................. 152
c. Tratarea excepţiilor definite de utilizator ............................................ 153
CAPITOLUL V. POCEDURI ŞI FUNCŢII ÎN PL/SQL .................... 155
5.1. PROCEDURI STOCATE ŞI FUNCŢII ÎN PL/SQL .................................. 155
5.2. PACHETE DE PROCEDURI ÎN PL/SQL .............................................. 159
5.3. TRIGGERE ÎN PL/SQL..................................................................... 162
5.4. CURSOARE ÎN PL/SQL ................................................................... 170
5.4.1. Cursoare Implicite ................................................................. 170
5.4.2. Cursoare explicite .................................................................. 174
CAPITOLUL VI. PROIECTAREA FIZICĂ A BAZELOR DE DATE
RELAŢIONALE ..................................................................................... 185
6.1. CARACTERISTICI ALE UNEI BAZE DE DATE FIZICĂ ........................... 185
6.2 TRANSFORMĂRI LOGICO-FIZICE DE BAZĂ ........................................ 187
6.2.1 Partiţionarea verticală ............................................................ 188
6.2.2 Partiţionarea orizontală ......................................................... 190
6.2.3 Reuniunea ............................................................................... 191
6.2.4 Aplicabilitatea transformărilor ............................................... 194
6.2.5 Scheme virtuale (vederi utilizator) .......................................... 195
6.3. OPTIMIZAREA PERFORMANŢEI ........................................................ 196
6.3.1 Accesul la atribut .................................................................... 196
6.3.2. Reuniuni preconstruite ........................................................... 199
6.3.3 Buffere ..................................................................................... 201
6.3.4 Gruparea relaţiilor de bază ................................................... 202
6.4 BAZE DE DATE RELAŢIONALE DISTRIBUITE ...................................... 204
3
CAPITOLUL VII. TRANZACŢII ÎN BAZE DE DATE DISTRIBUITE
.................................................................................................................. 206
7.1 INTRODUCERE ................................................................................. 206
7.2 TRANZACŢII .................................................................................... 208
7.2.1 Definiţie................................................................................... 208
7.2.2 Caracterul atomic ................................................................... 208
7.2.3 Caracterul consistent .............................................................. 209
7.2.4 Izolare ..................................................................................... 209
7.2.5 Durabilitatea ........................................................................... 210
7.2.6 Probleme de control ................................................................ 210
7.2.7 Exemplu aplicativ .................................................................... 214
7.3 BLOCARE (LOCK) ............................................................................ 218
7.4 INTERBLOCARE (DEADLOCK) .......................................................... 222
7.5 SERIALIZARE ................................................................................... 224
7.6 BLOCARE IERARHICĂ ...................................................................... 230
CAPITOLUL VIII. ANOMALII DE COMPORTAMENT ŞI
ALGORITMI DE CONTROL A CONCURENŢEI ÎN SGBD
DISTRIBUITE ........................................................................................ 233
8.1. ANOMALII DE INTERFERENŢĂ ÎN BD DISTRIBUITE .......................... 235
8.1.1 Anomalia de actualizare pierdută ........................................... 235
8.1.2. Anomalia dată de citiri improprii .......................................... 236
8.1.3. Anomalia de citire nereproductibilă ...................................... 237
8.2. INTRODUCEREA RESTRICŢIILOR DE COMPORTAMET CONCURENT:
PRIMITIVELE LOCK ŞI UNLOCK ......................................................... 238
8.3. SERIALIZABILITATE: DEFINIRE ŞI EXEMPLU .................................... 242
8.4. FORMALIZAREA CONCEPTULUI DE SERIALIZABILITATE. PLANIFICAREA
OPERAŢIILOR CONCURENTE ÎN SGBDD ................................................ 245
8.5 ALGORITMI DE CONTROL AL CONCURENŢEI ŞI TESTARE A
SERIABILITĂŢII ...................................................................................... 251
8.5.1. Controlul concurenţei prin blocare........................................ 251
8.5.2 Algoritm de testare a serializabilităţii .................................... 253
8.5.3 Protocolul în două faze pentru asigurarea serializabilitătii .. 257
8.6. TRANZACŢII CU ACCESE DE TIP READ-ONLY ŞI READ-WRITE ........... 260
CAPITOLUL IX. PROCESAREA TRANZACTIILOR ÎN PL/SQL 263
9.1 FOLOSIREA COMENZII COMMIT IN PL/SQL .................................. 263
9.2 FOLOSIREA COMENZII ROLLBACK IN PL/SQL ............................. 265
9.3 FOSIREA COMENZII SAVEPOINT IN PL/SQL ................................. 267
9.4 SETAREA PROPRIETĂŢILOR TRANZACŢIILOR CU COMANDA SET
TRANSACTION .................................................................................. 269
4
9.4.1. SET TRANSACTION READ ONLY ........................................ 269
9.4.2. SET TRANSACTION READ WRITE ...................................... 270
9.4.3. Clauza ISOLATION LEVEL ................................................... 270
9.5 Blocări explicite ......................................................................... 271
BIBLIOGRAFIE .................................................................................... 275
ANEXĂ: FUNCŢII PREDEFINITE ÎN PL/SQL ................................ 277
5
Capitolul I. BAZE DE DATE
ŞI SISTEME DE GESTIUNE
A BAZELOR DE DATE
6
Aceleaşi date sunt înregistrate şi stocate în mai multe fişiere,
ceea ce reclamă programe distincte pentru actualizarea fiecărui fişier.
În plus, duplicarea datelor conduce la un consum mare de memorie şi
incoerenţă la trecerea datelor stocate dintr-un fişier în altul. Aceasta
duce la alterarea integrităţii datelor (datele nu mai concordă),
gestionarea complexă şi actualizarea greoaie a acestora, precum şi la
o monopolizare inutilă a spaţiului de memorie.
2. Complexitatea actualizărilor (adăugarea, ştergerea sau
modificarea datelor);
3. Dificultatea obţinerii de informaţii neplanificate (spontane
sau ad-hoc), chiar şi pentru o simplă interogare fiind
necesară scrierea unui program;
Data1
Data2 Raport
FIŞIER 1 Prelucrare 1 1
Data3 ...
Raport
Data2 FIŞIER 2 Prelucrare 2 2
Data4 Raport
... 3
Data3
FIŞIER 3 Prelucrare 3 Raport
Data1 4
Data2 Data5 ...
DATE FIŞIERE PRELUCRĂRI IEŞIRI
7
Exploatarea fişierelor independente presupune un cost ridicat,
atât în ceea ce priveşte resursele informatice (hardware şi software),
cât şi cele legate de personalul utilizat.
5. Separarea şi izolarea datelor;
Atunci când datele sunt izolate în fişiere separate, programatorul
de aplicaţii trebuie să se asigure că sunt extrase datele corecte, fiind
astfel necesară sincronizarea prelucrării datelor din fişiere diferite,
această operaţiune fiind dificilă când sunt solicitate date din mai
mult de două fişiere.
6. Formate de fişiere incompatibile, ceea ce face dificilă
prelucrarea lor simultană
Deoarece structura fişierelor este încorporată în programele de
aplicaţii, ea este dependentă de limbajul de programare în care sunt
scrise acestea. De exemplu, structura unui fişier generat de un
program scris cu limbajul COBOL poate să fie diferită de cea a unuia
generat cu un program în limbajul C. De aceea sunt necesare
programe de transformare a fişierelor într-un format comun.
7. Dependenţa datelor faţă de programele de aplicaţii
Organizarea fişierelor, adresa lor fizică în memorie şi programele
de aplicaţii folosite pentru accesarea fişierelor sunt interdependente.
Astfel, schimbările legate de dispunerea pe suportul de memorie, de
structura datelor şi modificarea înregistrărilor unui fişier presupun
modificări în toate programele în care este referit fişierul respectiv.
Întreţinerea acestor programe este dificilă putând genera incoerenţe
în fişierele de date. Incoerenţa şi lipsa de integritate sunt extrem de
dificil de corectat deoarece nu există un dicţionar central pentru
urmărirea definirii datelor.
Toate aceste probleme care apar în sistemul ce prelucrează
fişiere îşi găsesc rezolvarea prin folosirea bazelor de date şi a
sistemelor de gestiune a bazelor de date. Datele stocate în baze sunt
independente atât faţă de programele de aplicaţii care le folosesc, cât
şi faţă de tipul de memorie utilizat.
8
1.1.2. Baze de date
Pe măsura evoluţiei sistemelor de prelucrare automată a
datelor şi, în mod special, a componentei hardware şi software, dar şi
ca urmare a creşterii volumului datelor de prelucrat s-a dezvoltat un
nou concept, cel al bazelor de date. El îşi face apariţia în a doua parte
a anilor ’60, aducând un element de noutate, respectiv existenţa unui
fişier de descriere globală a datelor, ceea ce asigură independenţa
datelor de programe şi invers, fişier denumit dicţionar de date (vezi
fig. nr. 3.2). La momentul respectiv, în cadrul sistemelor informatice
implementate în întreprinderi, informaţiile erau organizate în fişiere
de date (secvenţiale, indexate etc.) create cu ajutorul unor programe
scrise în limbaje din generaţia a III-a: COBOL, FORTRAN etc.
Principiul fundamental al bazelor de date îl constituie
unicitatea informaţiilor, adică orice informaţie este înregistrată o
singură dată şi poate fi utilizată ori de câte ori este nevoie, de către
diferiţi utilizatori şi în diferite momente.
Baza de date reprezintă un ansamblu integrat de înregistrări
sau de fişiere reunite şi structurate în mod logic. În felul acesta datele
stocate anterior în fişiere independente/distincte sunt concentrate
într-un fond comun de înregistrări cu posibilitatea utilizării lor în
numeroase aplicaţii.
Baza de date este o colecţie partajată de date între care există
relaţii logice şi o descriere a acestor date, proiectată pentru a
satisface necesităţile informaţionale ale unei organizaţii. Ea
reprezintă un depozit de date unic care este definit o singură dată şi
este utilizat simultan de către mai multe departamente şi utilizatori.
În loc de a mai exista fişiere separate cu date redundante, toate datele
sunt integrate, cu o dublare minimă. Baza de date nu mai este
deţinută de un singur departament, ci constituie acum o resursă
comună, partajată. Ea conţine nu numai datele operaţionale ale
organizaţiei, ci şi o descriere a acestora. De aceea ea este definită şi
ca o colecţie autodescrisă de înregistrări integrate. Această descriere
a datelor este cunoscută sub denumirea de catalog de sistem sau
dicţionar de date sau meta-date (date despre date). Natura
autodescriptivă a bazelor de date este cea care determină
independenţa program-date.
9
BAZA DE DATE
Fişier de date 1
1
COnference on DAta SYstems Languages – Conferinţa despre
Limbajele Sistemelor de Date
2
Aceste elemente sunt numite diferit în literatura de specialitate.
[2],[6],[7]
10
Prin entitate se înţelege un obiect concret sau abstract
(operaţie economică, mijloc economic etc.) reprezentat prin
proprietăţile sau însuşirile sale. Orice proprietate poate fi exprimată
printr-o pereche atribut-valoare sau caracteristică-realizare. O
entitate este identificată printr-un nume şi cuprinde, în general, mai
multe valori sau realizări.
Atributul are rolul de a descrie însuşirile sau proprietăţile
obiectului, stabilind natura valorilor pe care acesta le poate lua.
Valoarea reprezintă mărimea ce se atribuie fiecărei
caracteristici din cadrul unei entităţi.
Relaţia reprezintă o asociaţie între mai multe entităţi.
Aceste elemente sunt prezentate în tabelul nr. 1.1:
3
Moréjon, J., Principes et conception d’une base de données
relationnelle, Les Editions d’organisation, Paris, 1992, p. 20
11
O non-redundanţă a informaţiei, informaţia conţinută în
baza de date trebuind să fie unică din punct de vedere
semantic şi fizic;
O independenţă a datelor faţă de prelucrări; datele
constituie imaginea fidelă a lumii reale, programele de
aplicaţii trebuind să fie concepute în raport cu această
structură a datelor;
Securitatea şi confidenţialitatea datelor; securitatea
datelor trebuie asigurată prin proceduri fizice, iar
confidenţialitatea prin proceduri care să împiedice
accesul utilizatorilor neautorizaţi;
Performanţe în exploatare, orice cerere de prelucrare
trebuind să fie satisfăcută într-un timp convenabil
utilizatorului, ceea ce presupune folosirea unor tehnici
de optimizare pentru reducerea timpului de prelucrare.
Dicţionarele de date
Accesul utilizatorilor la informaţiile despre structura unei baze
de date se realizează prin intermediul dicţionarului de date.
În principal, un dicţionar îndeplineşte următoarele funcţii:
definirea şi gestionarea datelor elementare ale întreprinderii (cod,
etichetă, atribute, reprezentare etc.);
definirea şi gestionarea ansamblurilor de date;
definirea şi gestionarea relaţiilor, de dependenţă sau ierarhice,
dintre date;
descrierea din trei puncte de vedere a utilizării datelor:
administrativ: care sunt posturile de lucru ce vor apela
datele şi care va fi utilizarea acestor date?
logic: care sunt fişierele sau bazele de date în care intră
elementele descrise?;
organic: în care unităţi de prelucrare vor fi utilizate
elementele descrise?
În plus dicţionarele de date permit automatizarea operaţiilor
de scriere, de descriere a fişierelor sau ecranelor, de control etc. utile
pentru întreţinerea şi dezvoltarea dosarelor de programe.
12
Bazele de date sunt concepute pentru a prelucra un volum
mare de informaţii. Gestiunea acestora impune nu numai o
structurare riguroasă a datelor, dar şi o raţionalizare a procedurilor de
acces şi prelucrare. Pentru a putea fi exploatată de către utilizatori o
bază de date trebuie să aibă asociat un set de programe, numit
generic sistem de gestiune a bazelor de date care să permită
exploatarea raţională a datelor conţinute. Obiectivul esenţial al unui
sistem de gestiune a bazelor de date este, deci, furnizarea unui mediu
eficient, adaptat utilizatorilor care doresc să consulte sau să
actualizeze informaţiile conţinute în baza de date.
Sistemul de gestiune a bazelor de date reprezintă un
ansamblu coordonat de programe care permite descrierea,
memorarea, manipularea, interogarea şi tratarea datelor conţinute
într-o bază de date. El trebuie, de asemenea, să asigure securitatea şi
confidenţialitatea datelor într-un mediu multi-utilizator.
Principalele beneficii ale bazelor de date constau în:
integrarea în aceeaşi structură a tuturor datelor pertinente
ale unui sistem;
gestionarea acestor date printr-un software specializat
(SGBD);
oferirea unei vederi parţiale asupra ansamblului de date
necesare fiecărui utilizator;
asigurarea partajării datelor între diferiţi utilizatori.
13
Niveluri de abstractizare a datelor în bazele de date
Abordarea datelor în contextul bazelor de date se face pe trei
niveluri, considerate niveluri de abstractizare:
Nivelul intern este nivelul elementar la care pot fi
considerate datele şi se referă la modul în care sunt stocate datele pe
suporturi - disc magnetic, bandă magnetică, disc optic etc. La acest
nivel structura datelor este foarte detaliată. Nivelul intern cuprinde
structurile de date şi organizările fişierelor utilizate pentru stocarea
datelor pe dispozitivele de stocare. El tratează probleme cum ar fi:
alocarea spaţiului de stocare pentru date şi indexuri, descrierile
înregistrărilor pentru stocare, cu dimensiunile de stocare pentru
articolele de date, plasarea înregistrărilor, tehnicile de comprimare şi
de codificare a datelor. Nivelul intern interacţionează cu metodele de
acces al sistemului de operare (tehnici de administrare a fişierelor,
pentru stocarea şi regăsirea înregistrărilor de date) pentru a plasa
datele pe suporturile de stocare, a regăsi datele, a realiza indexurile.
Nivelul conceptual corespunde administratorului bazei de date
care proiectează structura logică a bazei de date. Asigură o viziune
globală. a bazei de date, descriind ce date sunt stocate în baza de date şi
relaţiile dintre acestea. La acest nivel structura bazei de date se
concretizează în schema conceptuală. Nivelul conceptual asigură atât
transpunerea, cât şi independenţa dorită dintre nivelul extern şi cel
intern.
Nivelul conceptual reprezintă toate entităţile, atributele şi
relaţiile dintre ele, contrângerile asupra datelor, informaţii semantice
despre date, informaţii privind securitatea şi integritatea.
Nivelul extern reprezintă vederea utilizatorului asupra bazei de
date ce descrie acea parte a bazei de date relevantă pentru fiecare
utilizator. Recurgerea la acest nivel de abstractizare se face pentru
simplificarea interacţiunii utilizator-bază de date. Acest nivel
corespunde utilizatorilor care pot avea viziuni diferite asupra bazei de
date pe baza unor subscheme proprii. Vederea externă include numai
acele entităţi, atribute şi relaţii din lumea reală de care este interesat
utilizatorul. Se urmăreşte satisfacarea cerinţelor tuturor utilizatorilor în
condiţiile unei redundanţe minime şi controlate a datelor.
14
Văzută prin prisma celor trei niveluri, baza de date poate fi
reprezentată ca în figura nr.2.3.[7]
INTERFAŢA A INTERFAŢA B
INTERFAŢA
Schema internă
BAZA DE DATE MEMORATĂ P E DISC
15
etc.). Autonomia fizică este cea care asigură şi portabilitatea
bazei de date de pe un sistem de calcul pe altul fără modificarea
schemei conceptuale şi a programelor;
independenţa logică de date se referă la faptul că modificarea
schemei conceptuale a bazei de date (cum ar fi adăugarea sau
eliminarea unor entităţi, atribute sau relaţii) nu necesită şi
modificarea schemei externe sau rescrierea programelor de
aplicaţii.
Este important să se facă distincţie între descrierea bazei de
date şi baza de date însăşi. Descrierea bazei de date constituie
schema bazei de date. Ea este specificată în timpul procesului de
proiectare a bazei de date şi este schimbată rareori. Setul de date din
baza de date se numeşte instanţa bazei de date. Mai multe instanţe
ale bazei de date pot corespunde aceleiaşi scheme a bazei de date.
16
Patru elemente determinante caracterizează depozitul de date:
datele stocate privesc o funcţiune sau un proces din întreprindere
(sunt orientate pe subiect);
datele sunt integrate şi redefinite penteu a putea fi exploatate;
informaţiile sunt conservate mai mulţi ani, acesta reprezentând
un atu al depozitelor de date (se asigură continuitatea şi
comparabilitatea);
datele nu pot fi modificate sau şterse.
Datele organizate în depozite provin din datele preluate din
sistemul operaţional, din datele de arhivă (în perioada de constituire
a depozitului), precum din surse externe (baze de date publice, date
din recensăminte, date de prognoză economică etc.). Utilizarea
depozitelor de date se concretizează în extragerea unor rapoarte (la
cerere sau pe baza unui abonament cu o anumită periodicitate),
extragerea unor date pentru a putea fi utilizate de aplicaţiile de
birotică (programe de calcul tabelar, procesoare de texte, programe
de prezentare etc.), dar mai ales pentru a putea fi utilizate în aplicaţii
specializate de analiză.
Componentele unui depozit de date sunt următoarele [7]:
1. instrumente pentru modelarea datelor, asociate adesea cu
instrumente de tip CASE;
2. o enciclopedie a metadatelor care păstrează informaţiile
relevante despre fiecare dată a depozitului de date (ce reprezintă,
tipul său, unde se găseşte, cum poate fi accesată, formatul său, etc.);
3. baza de date - nucleu care este centrul depozitului şi ia
forma bazelor de date (foarte rar a fişierelor independente);
4. instrumente pentru transpotul datelor, proiectate pentru a
muta copii ale datelor din sistemul operaţional în baza de date;
5. instrumentele pentru extragerea, rafinarea şi
standardizarea datelor, sarcini foarte dificile în condiţiile în care
informaţiile sunt foarte complexe, iar instrumentele de lucru
eterogene;
6. middleware care asigură conectivitatea în cadrul reţelelor
de calculatoare atunci când datele sunt preluate din mai multe baze
17
de date sau o bază de date este distribuită pe mai multe noduri ale
unei reţele;
7. instrumente pentru accesul utilizatorilor la date şi
furnizarea informaţiilor care cuprind instrumente de tipul interfaţă
grafică utilizator (GUI) sau navigatoare (browsere) Web ce permit
utilizatorilor să acceseze şi analizeze informaţiile din depozitul de
date.
Una din preocuparea actuală a producătorilor de instrumente
de construire a depozitelor de date este integrarea celor şapte
categorii de instrumente prezentate mai sus într-un produs
atotcuprinzător, ceea ce unii au reuşit într-o oarecare măsură.4
Din punct de vedere al ariei de întindere, se întâlnesc trei
modele de depozite de date: depozite de întreprindere, data marts şi
depozite virtuale.
Un depozit de întreprindere colectează toate informaţiile
despre subiecte care privesc întreaga organizaţie. El necesită
cheltuieli mai mari pentru modelare şi ani de zile pentru proiectare şi
realizare. El conţine de regulă date detaliate, dar şi date agregate, iar
ca ordin de mărime porneşte de la câţiva gigabytes până la sute de
gigabytes, terabytes sau mai mult.
Un data marts poate fi considerat un subansamblu al unui
depozit de date, mai uşor de construit şi întreţinut şi mai puiţin
scump. El conţine un subset al volumului de date din organizaţie,
specific unui grup de utilizatori. Domeniul este limitat la subiecte
specifice. De exemplu, un data mats pentru marketing limitează
subiectele la clienţi, articole, vânzări. Un depozit virtual este un set
de viziuni (views) asupra bazelor de date operaţionale. Este uşor de
construit, dar necesită capacităţi suplimentare pe serverele de baze de
date. Pentru eficienţa procesării interogărilor, numai unele din
viziunile de agregare pot fi materializate.
4
Fotache, M., Depozitul de date, în Tribuna economică nr.36 /1998,
p.49
18
Baza de date reprezintă "inima" depozitului. În practică, baza
de date nucleu se poate regăsi sub forma fişierelor independente de
date (mai rar), poate fi o bază de date relaţională sau
multidimensională. În prezent se pune tot mai mult accent pe bazele
de date multidimensionale care sunt concepute pentru optimizarea
analizei indicatorilor (cifră de afaceri, marjă…) în raport cu
dimensiunile care le sunt asociate (timp, produs, regiune…). Ele
simplifică gestiunea volumelor mici sau mijlocii de date, sunt
adaptate la rezolvarea unor probleme concrete (fiind utilizate mai
ales pentru analize sofisticate cum ar fi simulările sau predicţiile),
adaptându-se astfel foarte bine în contexul depozitelor de date.
În ceea ce priveşte instrumentele de analiză şi acces la
informaţii, două categorii, instrumentele de interogare şi cele OLAP
se regăsesc pentru a combina accesul liber la informaţii şi funcţiile
de analiză, fiind concepute pentru a răspunde nevoilor foarte diverse
ale utilizatorilor finali. Astfel, anumiţi utilizatori sunt autonomi şi
doresc un acces liber la informaţii fără a se îngriji de căile de acces la
date. Instrumentele de tip interogare răspund nevoilor lor. Aceste
instrumente favorizează formularea de interogări bazându-se pe
logica asamblistă a bazelor de date relaţionale. Ele permit, de
exemplu, obţinerea listei cu numele şi prenumele clienţilor care au
cumpărat un anumit produs în cursul ultimelor trei luni. Alţi
utilizatori exprimă cerinţe de analiză, ceea ce necesită o informaţie
bine pregătită şi foarte organizată. Instrumentele de tip OLAP (On-
Line Analytical Processing) sunt mai bine adaptate exigenţelor lor.
Prelucrarea analitică on-line este un nou instrument la dispoziţia
managerilor şi analiştilor pentru examinarea interactivă şi
manipularea unui volum mare de date analitice sau agregate sub
diverse forme. OLAP înseamnă analiza relaţiilor complexe între mii
şi chiar milioane de date pentru a descoperi tendinţe, modele şi
excepţii. Operaţiile fundamentale în OLAP sunt consolidarea, forajul
(drill down) şi disecarea (slice and dice). Consolidarea înseamnă
agregarea datelor ce poate fi o simplă sumarizare sau o grupare
complexă, implicând date aflate în legătură. Forajul este operaţiunea
inversă şi se referă la afişarea datelor detaliate, pornind de la cele
consolidate. Disecarea porneşte de la capacitatea OLAP de a privi o
bază de date din mai multe perspective. Ea se realizează cel mai
19
adesea de-a lungul unei axe de timp pentru a analiza tendinţele şi a
descoperi modele de evoluţie.
Alţi utilizatori au nevoie de instrumente de data mining care
permit structurarea informaţiei fără preocuparea pentru modul în care
datele sunt puse în corelaţie, prin punerea în funcţiune a unor
mecanisme de inducţie.
Prelucrarea analitică on-line, referită de regulă ca OLAP (On
Line Analytical Processing) răspunde la întrebări pe care managerii
şi le pun la modul concret. Singura trăsătură comună a acestor
întrebări este caracterul lor multidimensional. Există totuşi câteva
tipuri uzuale de întrebări, care pot arunca o lumină asupra
complexităţii instrumentelor care trebuie să furnizeze răspunsuri:
Raporturi multidimensionale. De exemplu: Care este
contribuţia la vânzările săptămânale totale a produselor informatice
vândute prin magazinele situate în regiunea Moldova între 10 şi 20
septembrie?
Comparaţii. De exemplu: Care este media abaterii
procentuale de la planul de vânzări în lunile acestui an comparativ cu
anul trecut?
Clasificări şi profiluri statistice. De exemplu: Care este
volumul vânzărilor şi media profitului pentru primii 20% dintre
distribuitori şi care este contribuţia acestora la totalul vânzărilor pe
trimestrul trecut?
Agregări libere. De exemplu: Care sunt veniturile realizate
în ultimele patru trimestre de filialele judeţene din regiunea
Moldova?
Evaluări What-If. De exemplu: În ce măsură ar influenţa
profitul total o creştere cu 10 procente a vânzărilor în judeţele din
Moldova?
Instrumentele de data mining explorează bazele de date şi
extrag din acestea o multitudine de informaţii asupra tendinţelor şi
previziunilor. Câmpul de acţiune al data mining cuprinde nu numai
analiza datelor, ci şi a textelor.
Depozitele de date nu înseamnă totuşi numai avantaje, ci ele
ridică o serie de probleme înre care menţionăm:
20
dimensiunile extrem de mari la care pot ajunge, de ordinul
gigaocteţilor, ceea ce ridică problema suporturilor de stocare,
ca şi asigurarea unei viteze rezonabile de acces la date;
costuri de dezvoltare foarte mari şi timp îndelungat necesar
pentru construirea lor;
dificultatea integrării diferitelor platforme hardware şi
software existente în cadrul întreprinderii.
21
* alte ieşiri care ar putea fi trimise altor sisteme de
prelucrare a datelor;
* toate actualizările necesare;
* toate calculele necesare;
* toate restricţiile sistemului (de exemplu, restricţii
funcţionale sau restricţii de comportament);
* toate sinonimele utilizate pentru un atribut dat;
restricţiile fizice (volumul prelucrărilor şi evaluarea
performanţelor):
* numărul, dimensiunile şi frecvenţa rapoartelor;
* timpul de răspuns pentru fiecare interogare;
* timpul de răspuns pentru fiecare actualizare;
* măsurile de securitate prin restricţionarea accesului.
22
iar pentru modelul OO trebuie acordat maximum de atenţie analizei
temporale şi celei funcţionale.
23
* precizarea unor criterii de optimizare a prelucrărilor.
24
modelul conceptual este transpus într-un model al datelor care are
caracteristicile proprii SGBD-ului ales de proiectant.
Proiectarea structurii bazei de date implică următoarele
activităţi [5]:
* alegerea SGBD utilizat pentru implementarea şi exploatarea
BD;
* proiectarea schemei conceptuale a BD;
* proiectarea schemei externe (subschemei) BD;
* proiectarea schemei interne (de memorare) a BD.
Alegerea sistemului de gestiune a bazei de date
În alegerea unui SGBD, se au în vedere mai multe aspecte:
cerinţele utilizatorilor, sub aspectul:
* tipurilor de aplicaţii;
* timpului de răspuns;
* confidenţialităţii şi securităţii datelor;
* uşurinţei în utilizare;
cerinţele de ordin tehnic:
* portabilitatea SGBD;
* portabilitatea datelor şi programelor de aplicaţii;
* condiţiile de încărcare, exploatare şi întreţinere a
BD;
cerinţe de ordin economic:
* încadrarea în bugetul destinat acestui scop;
* timpul necesar pentru implementarea sistemului
(inclusiv pregătirea utilizatorilor).
În urma analizei acestor cerinţe, ca şi a SGBD-urilor
disponibile şi a modului cum ele oferă răspuns la cerinţele
utilizatorilor, se decide care va fi SGBD utilizat.
25
* determinarea legăturilor dintre colecţiile de date;
* testarea şi revizuirea eventuală a schemei obţinute;
* descrierea schemei conceptuale în maniera proprie SGBD
ales.
În stabilirea colecţiilor de date şi a legăturilor dintre acestea
se porneşte de la entităţile identificate în etapa de analiză. Astfel, în
cazul unui proces economic oarecare, aceste entităţi vor fi
participanţii la procesul în cauză. Spre exemplu, în cazul unei
activităţi comerciale, putem identifica la prima vedere câteva entităţi:
cumpărător, vânzător, marfă etc.
Pentru aceste entităţi se vor preciza atributele sau
proprietăţile care prezintă interes pentru utilizatorii informaţiei,
eventual şi o serie de atribute auxiliare, utilizate pentru a exprima
legături între entităţi.
Aceste entităţi alcătuiesc modelul semantic. Nu este
obligatoriu ca fiecare componentă a acestui model să atragă
constituirea unei colecţii de date distincte. Ąn practică, pentru
îmbunătăţirea performanţelor aplicaţiilor (în special optimizarea
timpului de acces la date), poate opera o sporire, dar şi o reducere a
numărului de colecţii de date proiectate iniţial.
În realizarea colecţiilor de date se poate porni şi de la
documentele de ieşire (cele care conţin informaţiile de care are
nevoie utilizatorul), caz în care toate atributele identificate concură la
alcătuirea unui dicţionar de date şi urmează a fi grupate în funcţie de
anumite legături identificabile între atribute.
Modul de reprezentare a legăturilor dintre colecţiile de date
identificate diferă în funcţie de modelul datelor pe care-l implică
SGBD utilizat. Spre exemplu, pentru modelele ierarhic şi reţea se
utilizează pointeri, iar pentru modelul relaţional, chei externe
(străine).
Testarea schemei conceptuale presupune verificarea
corectitudinii (a modului în care aceasta ilustrează cerinţele
utilizatorilor) şi consistenţei acesteia (a corespondenţei dintre
legăturile determinate şi lumea reală). De asemenea, trebuie ca
redundanţa datelor să se situeze la un nivel minim. Dacă în această
26
etapă se identifică erori, se poate reveni la etapa de proiectare şi
uneori chiar la cea de analiză a sistemului.
În ceea ce priveşte descrierea schemei conceptuale, aceasta
comportă transpunerea schemei în limbajul de manipulare a datelor
specific SGBD ales. Rezultatul acestui proces îl constituie schema
(în accepţiune CODASYL5) bazei de date.
5
abreviere de la "Conference on Data Systems Languages"
27
d. Încărcarea datelor în baza de date
Aceasta este o etapă inerentă proiectării bazei de date, şi
constă în specificarea conţinutului acesteia (a datelor pe care le va
memora). Deşi activitatea nu este pretenţioasă, ea este destul de
delicată, dat fiind volumul mare de date care trebuie vehiculate.
Un detaliu important este acela al încărcării BD numai cu
date corecte, scop în care sunt necesare proceduri de validare şi
corectare a datelor.
Sursele de date pot consta îndocumente primare,colecţii de
date aflate deja pe suporturi (de exemplu, sisteme de fişiere), date
preluate direct, fără intervenţia documentelor (prin schimb electronic
de date).
Nu trebuie să se exagereze în direcţia procedurilor de
validare utilizate, deoarece productivitatea introducerii datelor poate
scădea în mod drastic.
28
1.2 Modele conceptuale de structurare şi
organizare a datelor în baze de date
Pentru descrierea structurii datelor unei baze de date şi a
relaţiilor dintre acestea sunt folosite procedee formale, concretizate
în modele conceptuale. Acestea se particularizează prin terminologia
utilizată şi prin relaţiile dintre date.
X1 Y1
X2 Y2
.
.
.
.
Xn Yn
Domeniu Codomeniu
29
X1 Y1
Y2
.Y3.
Y4
X2 Y5
Domeniu Codomeniu
X1
X2 Y
X3
Domeniu Codomeniu
X1
Y1
Y2
.Y3.
X2 Y4
Domeniu Codomeniu
30
Relaţiile n-are presupun existenţa unei interdependenţe
logice între realizările unei mulţimi de caracteristici definită pe o
mulţime de tupluri.
Mecanismul de selecţie şi de identificare a componentelor
unei baze de date presupune existenţa unei structuri de date.
Concret o structură de date reprezintă o colecţie de date între care s-
au stabilit anumite relaţii. Structurile de date care au aceeaşi
organizare şi sunt supuse prelucrărilor cu un grup de operatori de
bază cu o semantică predefinită formează un anumit tip de structură.
Principalele tipuri de structuri sunt [14] punctuală, liniară,
arborescentă, reţea, relaţională. Dintre acestea sunt considerate de
bază structurile liniară şi arborescentă. Prin combinarea lor în funcţie
de opţiunile utilizatorilor, pot fi construite şi alte structuri cu grade
diferite de complexitate.
31
multe entităţi. De exemplu, atributele Număr şi Disponibil descriu
entitatea Cont la bancă. Atributele Nume, Adresă, etc. descriu
entitatea Client. Există o asociaţie care leagă un client de fiecare din
conturile pe care le are deschise la banca respectivă. Ansamblul
entităţilor de acelaşi tip formează o clasă de entităţi, iar ansamblul
asociaţiilor de acelaşi gen reprezintă o clasă de asociaţii.
În reprezentarea unei structuri de baze de date cu ajutorul
modelului E-R se realizează o diagramă, care utilizează simbolurile:
* dreptunghi, pentru clase de entităţi,
* elipse, pentru atribute,
* romburi, pentru clase de asociaţii,
* linii, pentru a lega atribute de clase de entităţi şi
clasele de entităţi de clasele de asociaţii.
Exemplu
Adresa Data
Furnizor Localitate Numar Valoare
32
Un model al datelor este o abstractizare a lumii reale ce
permite "tratarea" complexităţii inerente în cazul problemelor din
lumea reală prin concentrarea atenţiei asupra caracteristicilor
esenţiale şi interesante ale datelor de care are nevoie o organizaţie.
Un model orientat obiect este construit în jurul "obiectelor" tot aşa
cum modelul E-A are la bază entităţile. Totuşi un obiect încapsulează
atât datele cât şi comportamentul, ceea ce permite utilizarea unei
abordări orientate obiect nu doar pentru modelarea datelor, ci şi
pentru modelarea proceselor. Pentru a modela cu stricteţe o aplicaţie
din lumea reală trebuie să se modeleze atât datele, cât şi procesele ce
acţionează asupra datelor. Modelarea orientată obiect asigură un
mediu puternic pentru dezvoltarea unor sisteme complexe, datorită
posibilităţii de captare a datelor şi a proceselor şi datorită mai ales,
moştenirii şi reutilizării codului.
Ciclul de viaţă al proiectării orientate obiect constă din
reprezentarea progresivă a obiectelor în cadrul a trei faze: analiză,
proiectare şi implementare. Acest ciclu de viaţă este similar cu cel al
dezvoltării sistemelor. În primele etape, modelul pe care îl creăm este
abstract, concentrându-se asupra calităţii externe a sistemului. Pe
măsură ce modelul evoluează, acesta devine din ce în ce mai detaliat,
atenţia deplasându-se spre cum va fi construit sistemul şi mai ales,
cum va funcţiona. Accentul în modelare trebuie pus pe analiză şi
proiectare, în special pe problemele conceptuale front-end, faţă de
problemele de implementare back-end ce restricţionează opţiunile de
proiectare6.
În etapa de analiză este dezvoltat un model al aplicaţiei din
lumea reală ce reprezintă proprietăţile sale importante. Modelul
abstractizează concepte din domeniul aplicaţiei şi descrie ce anume
trebuie să realizeze sistemul mai degrabă decât cum va fi realizat
acest lucru. Modelul specifică în special comportamentul funcţional
al sistemului, independent de problemele legate de mediul în care va
fi implementat în final. Trebuie să se aloce suficient timp pentru
înţelegerea clară a tuturor cerinţelor problemei în discuţie. Modelul
6
Rumbaugh, J., Blaha, M., Premerlani, W., Eddy, F., Lorensen, W.,
Object-Oriented Modelling and Design, Pretice-Hall, 1991
33
de analiză captează aceste cerinţe în mod precis, concis şi cu
acurateţe.
În faza de proiectare orientată obiect se defineşte cum va fi
realizat modelul de analiză orientată obiect în cadrul mediului de
implementare. Există trei motive pentru utilizarea proiectării
orientate obiect:
1. Modelul de analiză nu este suficient de formal pentru a fi
implementat direct într-un limbaj de programare. Pentru a ne
deplasa către codul sursă trebuie să rafinăm mai întâi obiectele
prin adoptarea unei decizii privind operatorii ce vor fi asiguraţi
de un obiect, cum ar trebui să arate comunicaţia între obiecte, ce
mesaje vor fi transmise etc.
2. Sistemul actual trebuie să fie adaptat mediului în care sistemul
va fi implementat. Pentru a realiza acest lucru, modelul de
analiză trebuie să fie transformat într-un model conceptual de
proiectare, luând în considerare diferiţi factori cum ar fi:
cerinţele de performanţă, cerinţele de timp real şi concurenţă,
hardware-ul şi software-ul implicat, SGBD-ul şi limbajele de
programare ce vor fi adoptate etc.
3. Rezultatele etapei de analiză pot fi validate cu ajutorul proiectării
orientate obiect. În acestă etapă putem verifica dacă rezultatele
furnizate de analiză sunt adecvate pentru construirea sistemului
şi dacă este necesar să se efectueze modificări asupra modelului
de analiză.
Pentru dezvoltarea modelului de proiectare trebuie să fie
identificate şi investigate consecinţele pe care le va avea mediul de
implementare asupra proiectării. Toate deciziile de proiectare
strategice (cum va fi implementat SGBD-ul, cum vor fi asigurate
comunicaţiile între procese şi tratarea erorilor, care componente vor
fi reutilizate) vor fi adoptate şi vor fi apoi încorporate într-un prim
model de proiectare adaptat mediului de dezvoltare. În final, modelul
este formalizat pentru a descrie modul în care obiectele
interacţionează unele cu altele pentru fiecare scenariu sau caz.
Rumbaugh separă activitatea de proiectare în două etape:
proiectarea sistemului şi proiectarea obiectelor.
34
La proiectarea sistemulul trebuie propusă o arhitectură
globală a sistemului care îl organizează în componente, numite
subsisteme şi asigură contextul necesar adoptării deciziilor cum ar fi
identificarea concurenţei, alocarea subsistemelor pe procesoare şi
task-uri, asigurarea accesului la resursele globale, selectarea
modalităţilor de implementare a controlului software etc.
În etapa de proiectare a obiectelor va fi construit un model
de proiectare prin adăugarea unor detalii de implementare cum ar fi:
restructurarea claselor pentru eficienţă, structurile interne de date şi
algoritmii pentru implementarea fiecărei clase, implementarea
controlului şi a asociaţiilor (legăturilor), precum şi împărţirea în
module fizice în concordanţă cu strategia adoptată în timpul
proiectării sistemului. Clasele de obiecte specifice domeniului
aplicaţiei din cadrul modelului de analiză vor fi îmbogăţite cu o serie
de elemente specifice procedurilor de calcul în scopul optimizării
performanţelor.
Etapa de proiectare este urmată de o etapă de implementare.
În această fază, proiectul este implementat cu ajutorul unui limbaj de
programare sau a unui SGBD. Translatarea proiectului în cod sursă
este un proces relativ uşor datorită faptului că modelul de proiectare
încorporează deja o serie de aspecte ale limbajului de programare şi
SGBD-ului ales.
Unele din avantajele des citate în favoarea orientării spre
obiecte sunt:
Definiţia unui sistem prin intermediul obiectelor facilitează
construcţia de componente software care seamănă
îndeaproape cu domeniul de aplicaţie, contribuind astfel la
proiectarea şi înţelegerea sistemelor;
Datorită încapsulării şi ascunderii informaţiilor,
întrebuinţarea obiectelor şi mesajelor încurajează proiectarea
modulară;
Implementarea unui obiect nu depinde de structura internă a
acestuia, ci de modul cum acesta răspunde la mesaje;
Întrebuinţarea claselor şi a moştenirii promovează
dezvoltarea de componente reutilizabile şi extensibile în
35
contrucţia de noi sisteme sau pentru actualizarea celor
existente.
O bază de date orientată spre obiecte este o colecţie de
obiecte persistente şi partajabile care sunt definite de un model de
date orientat pe obiecte. Un sistem SGBD orientat pe obiecte este
administratorul unei baze de date orientată pe obiecte.
Aspecte structurale ale modelului de date orientat pe
obiecte:
* Obiectele sunt entităţi de bază care încorporează structuri de
date şi operaţii;
* Fiecare obiect are un identificator unic, atribuit de sistem;
* Clasele descriu tipuri generice de obiecte;
* Conceptul de clasă este strâns legat de conceptul de
moştenire;
* Clasele formează ierarhii de clase;
* Definirea unei clase este mecanismul de specificare a
schemei bazei de date;
* Schema bazei de date se poate extinde prin definirea de noi
clase;
* Definirea unei clase poate include atribute de tipuri definite
de utilizator (imagine, sunet);
* Se admit referiri recursive.
Operaţii ale modelului de date orientat pe obiecte:
* Obiectele comunică prin mesaje;
* Un mesaj poate fi trimis instanţelor din mai multe clase;
* Metodele pot fi definite, şterse sau modificate;
* Clasele pot fi definite, şterse sau modificate;
* Instanţa unei clase poate fi actualizată prin metode ce
modifică valorile variabilelor propriei instanţe.
Reguli de integritate ale modelului de date orientat pe
obiecte:
* Obiectele trebuie să respecte caracteristicile clasei din care
fac parte;
* Obiectele sunt încapsulate;
* Un obiect nu există fără să aibă un identificator; dacă
obiectul este şters, se şterge şi identificatorul;
36
* Restricţia de integritate cunoscută de la modelul relaţional
nu este implementată (nu există posibilitatea de ştergere în cascadă).
FURNIZORI FACTURI-PRIMITE
Furnizor Adresa Localita Furnizor Număr Data Valoar
te e
Alfa SRL Unirii 2 Iaşi Alfa SRL 12540 12/02/07 1259.8
Beta SA Apelor 5 Bacău Beta SA 14870 14/02/07 3265
Gama SA Viilor 56 Iaşi Alfa SRL 24550 22/02/07 2987.5
Gama SA 18960 28/02/07 5420
37
Acest model asigură organizarea datelor pe orice tip de
suport magnetic şi reducerea timpului de acces la înregistrări. El are
însă o serie de limite în special în operaţiile de actualizare când
adăugarea de noi înregistrări, cu excepţia celor din colecţia de date
rădăcină, se poate efectua numai cu specificarea colecţiilor de date
superioare, iar ştergerea unei înregistrări duce la eliminarea fizică a
tuturor înregistrărilor subordonate.
38
În plus, prin acest model este permisă reprezentarea unică a
realizărilor în baza de date.
Legăturile fizice pe suport sunt asigurate prin intermediul
unor caracteristici care exprimă pointer-ul (adresa de pe suport) a
realizării superioare sau a realizării subordonate. Astfel reţeaua este
un graf orientat alcătuit din noduri conectate prin arce. Nodurile
corespund tipurilor de înregistrare, iar arcele pointerilor. În felul
acesta este permisă introducerea înregistrărilor artificiale pentru a
reprezenta legăturile n-are (n>2)
FACTURI-EMISE
39
* existenţă proprie;
* poate fi abstractă sau concretă;
* aparţine unei familii de obiecte de aceiaşi natură,
numită clasă de entităţi;
* fiecare entitate este identificabilă şi caracterizată
fără ambiguitate.
Clasa de entităţi este deci un ansamblu de entităţi care au
proprietăţi comune. Gruparea entităţilor în clase este arbitrară, iar
clasele nu sunt întotdeauna disjuncte, ceea ce înseamnă că este
posibil ca o entitate care este încadrată într-o clasă să poată face parte
simultan şi din altă clasă de entităţi.
Orice entitate poate fi caracterizată printr-un ansamblu de
atribute. Un atribut este o proprietate comună tuturor entităţilor dintr-
o anumită clasă.
O entitate este legată cu una sau mai multe entităţi dintr-o
altă clasă prin intermediul unei asociaţii. O asociaţie este o relaţie
stabilită între două sau mai multe entităţi care, deşi nu are o existenţă
proprie, poate fi purtătoarea unor proprietăţi. Mai multe asociaţii cu
aceleaşi proprietăţi se reunesc în clase de asociaţii. O clasă de
asociaţii este o relaţie definită pe una sau mai multe clase de entităţi.
Pentru denumirea unei clase de asociaţii se alege un substantiv care
reflectă logica legăturii dintre cele două clase de entităţi.
Funcţia care atrage o entitate într-o asociaţie se numeşte rol.
Clarificarea rolului fiecărei clase de entităţi este esenţială în
proiectarea bazei de date.
Pentru reprezentarea grafică a unei diagrame entităţi-
asociaţii, în literatura de specialitate au fost propuse mai multe
soluţii. Una din cele mai utilizate este prezentată mai în figura nr.
2.13.
41
(perfect adevărat) şi fiecare furnizor ar întocmi o singură factură
(nerealist).
- cardinalitatea de tip 1 la n, în care o entitate din clasa X
poate fi asociată la n entităţi din clasa Y, în timp ce fiecare entitate
din clasa Y poate fi asociată unei singure entităţi din clasa X. Clasa
de asociaţii VÂNZARE are o astfel de cardinalitate, pentru că pentru
fiecare client se pot întocmi mai multe facturi, dar o factură are un
singur client (figura 1.17).
Observaţie: Într-o diagramă entităţi-asociaţii, cardinalitatea este
reprezentată prin indicarea, în dreptul clasei de entităţi a numărului
maxim de asociaţii la care poate participa o entitate din clasa
respectivă. Un client poate fi asociat la n facturi emise, dar o factură
poate fi asociată unui singur client. De remarcat că reprezentarea
grafică cardinalităţii se face invers faţă de modul de citire al acesteia.
- cardinalitatea de tip n la 1, în care o entitate din clasa X
este asociată unei singure entităţi din clasa Y, iar orice entitate din Y
poate fi asociată la n entităţi din X. Este inversa cardinalităţii de tip 1
la n.
- cardinalitatea de tip n la n, în care orice entitate din X
poate fi asociată mai multor entităţi din Y, iar o entitate din Y este
asociabilă mai multor entităţi din X.
42
1.3 Sisteme de gestiune a bazelor de date
SGBD-urile reprezintă un software complex care
realizează/asigură independenţa, relaţiile logice între date şi o
redundanţă minimă a acestora. Ele trebuie să permită dezvoltarea
rapidă şi la un cost avantajos a programelor de aplicaţii pentru
exploatarea datelor dintr-o structură complexă, precum şi accesul
rapid la date şi asigurarea securităţii lor.
SGBD-ul reprezintă un sistem de programe care permite
utilizatorului definirea, crearea şi întreţinerea bazei de date şi accesul
controlat la aceasta.
Sistemul SGBD constă în elemente de software care
interacţionează cu programele aplicaţie ale utilizatorului şi cu baza
de date. De obicei, un SGBD oferă următoarele facilităţi
1. Permite utilizatorilor să definească baza de date, de obicei printr-
un limbaj de definire a datelor (DDL). Limbajul DDL permite
utilizatorilor specificarea tipurilor de date şi a structurilor, în
timp ce constrângerile asupra datelor sunt stocate în baza de date
2. Permite utilizatorilor să insereze, să reactualizeze, să şteargă şi să
extragă date din baza de date, de obicei printr-un limbaj de
manipulare a datelor (DML). Faptul că există un depozit central
al tuturor datelor şi descrierilor acestora permite limbajului DML
să ofere o facilitate de interogare generală a acestor date,
denumită limbaj de interogare. Existenţa unui limbaj de
interogare elimină dificultăţile sistemelor bazate pe fişiere unde
utilizatorul este constrâns să lucreze cu un set fix de interogări
pentru a evita proliferarea de programe care creează probleme
majore privind gestionarea acestora. Există două tipuri de
limbaje DML - procedurale şi neprocedurale care se deosebesc în
funcţie de operaţiile de extragere. De obicei, cele procedurale
tratează baza de date înregistrare cu înregistrare, în timp ce cele
neprocedurale operează asupra unor seturi de înregistrări. În
consecinţă, limbajele procedurale specifică cum se obţine
43
rezultatul unei instrucţiuni DML, iar cele neprocedurale descriu
numai ce date vor fi obţinute. Cel mai obişnuit tip de limbaj
neprocedural este limbajul structurat de interogare (SQL) care
reprezintă acum atât limbajul standard, cât şi cel de facto pentru
SGBD relaţionale.
3. Oferă accesul controlat la baza de date. De exemplu, poate
furniza
- un sistem de securitate care previne accesarea bazei de date
de către utilizatori neautorizaţi
- un sistem de integritate care menţine concordanţa datelor
stocate
- un sistem de control al concurenţei care permite accesul
partajat la baza de date
- un sistem de control al refacerii care restaurează baza de date
într-o stare precedentă concordantă ca urmare a unei
defecţiuni în hardware sau software
- un catalog accesibil utilizatorilor care conţine descrieri ale
datelor din baza de date
SGBD-ul prezintă şi o facilitate cunoscută sub
denumirea de mecanism de vizualizare care permite fiecărui
utilizator să-şi definească propriul mod de vizualizare a bazei de
date. Limbajul DML permite definirea de moduri de vizualizare în
care acestea reprezintă un subset al bazei de date.
Avantajele SGBD
- controlul redundanţei datelor
- coerenţa datelor
- mai multe informaţii de la aceeaşi cantitate de date
- partajarea datelor
- integritatea crescută a datelor
- securitatea crescută
- aplicarea standardelor
- economia de scală
- echilibru între cerinţe aflate în conflict
- îmbunătăţirea accesibilităţii datelor şi capacităţii de răspuns
44
- productivitatea crescută
- capacitatea de întreţinere îmbunătăţită, prin independenţa de date
- concurenţa îmbunătăţită
- îmbunătăţirea serviciilor de salvare de siguranţă şi refacere
45
date. Utilitarele variază de la un sistem la altul şi depind de
complexitatea SGBD-ului. Acestea pot efectua următoarele operaţii:
crearea versiunii iniţiale a bazei de date şi încărcarea
acesteia folosindu-se fie o copie creată anterior, fie date
neorganizate;
crearea şi actualizarea jurnalelor tranzacţiilor realizate
asupra bazelor de date. Acest utilitar controlează fiecare
tranzacţie reţinând în jurnal următoarele informaţii:
identificatorii de program, de utilizator şi
terminalul folosit;
determinarea “timpului-maşină”;
structura şi conţinutul bazei înainte şi după
tranzacţie;
natura tranzacţiei (sistem sau aplicaţie);
înscrierea datelor transmise tampoanelor SGBD-
ului în jurnalul sistemului;
reorganizarea bazei de date pentru recuperarea spaţiului
vid;
reorganizarea structurii fizice şi logice după tranzacţie;
restructurarea bazei de date după un incident logic sau
fizic, cu refacerea stării existente anterior acestuia.
Restaurarea este determinată de existenta în cadrul
SGBD-urilor a aşa-numitelor puncte-de-reluare
(Checkpoint) [7] în cazul unor întreruperi în exploatarea
unei baze de date, reluarea exploatării se va face nu de la
începutul bazei de date, ci de la Checkpointul precedent;
diverse statistici ce permit cunoaşterea activităţii şi
utilizării bazei de date;
actualizarea schemei şi sub-schemei fără rescrierea şi
compilarea lor;
detectarea “spărgătorilor” regulilor de integritate
definite, fără a fi necesară intrarea în baza de date;
realizarea unei copii permanente a bazei de date în
scopuri de securitate.
Componentele de control
46
Acestea constituie mijloace de prevenire şi corectare a
anumitor erori ce pot să apară în condiţii “multi-utilizator”.
Administratorul
Utilizatori
BD
Programede
Structura BD aplica¡ii
LDD LMD
PGBD
Baza
de
date
47
Schematic structura unui SGBD pate fi prezentată ca în
figura 2.14 .
48
administratorul bazei de date care are responsabilitatea
definirii schemei interne a bazei de date şi a întreţinerii
acesteia. În acelaşi raport sunt prezentate trei categorii de
administratori:
administratorul întreprinderii care asigură gestionarea
globală a aplicaţiilor curente şi identificarea celor
viitoare;
administratorul aplicaţiilor care are rolul de a
dezvolta schemele externe (sub-schemele) pentru
aplicaţiile utilizator;
administratorul de date care operează la nivelul
schemei de date precizând necesarul şi disponibilitatea
datelor;
programatorii de aplicaţii şi utilizatorii finali care comunică
cu SGBD-ul prin intermediul limbajului de manipulare sau a
limbajului de interogare.
Într-o altă viziune utilizatorii pot fi structuraţi astfel:
1. utilizatorii liberi sau conversaţionali, reprezintă beneficiarii
(utilizatorii neinformaticieni) a informaţiilor care nu dispun de
cunoştinţe despre structura bazei de date şi nici despre sistemul
de calcul pe care este implementată baza de date. În schimb au la
dispoziţie limbaje de interogare a bazei de date într-o formă
simplistă;
2. utilizatori programatori care utilizează limbaje de manipulare
realizând proceduri complexe de exploatare a bazei de date.
Aceşti utilizatori cunosc atât structura bazei de date cât şi
particularităţile sistemului de operare, ceea ce le dă posibilitatea
să exploateze toate facilităţile oferite de baza de date;
3. administratorul bazei de date care are cel mai important rol în
funcţionarea şi exploatarea optimă a întregului sistem, asigurând
realizarea obiectivelor şi funcţiilor SGBD-ului.
O ultimă clasificare asupra căreia ne-am oprit grupează
utilizatorii în trei mari categorii [13] :
utilizatori finali – care interacţionează cu baza de date prin
intermediul unui limbaj de interogare sau care apelează
programe scrise de programatorii de aplicaţii;
49
programatorii de aplicaţii care au rolul de a crea programele de
aplicaţii ale bazei de date, utilizând limbajul de manipulare a
datelor;
administratorul bazei de date care este o persoană sau un grup de
persoane responsabil cu controlul general al sistemului.
Pe lângă aceste categorii de utilizatori, bazele de date pot fi
accesate fraudulos de persoane cu cunoştinţe de specialitate care
încearcă să sustragă sau să distrugă informaţii, provocând daune
proprietarilor băncilor de date. Aceşti utilizatori sunt cunoscuţi sub
numele de hacker-i.
50
2.4. Protecţia şi securitatea bazelor de date
Prin protecţia bazei de date se înţelege un ansamblu de
activităţi umane şi de facilităti oferite de SGBD prin care se
urmăreşte asigurarea integrităţii datelor (corectitudinii datelor
memorate în baza de date) şi securităţii datelor (restricţionarea
accesului la date). Cu cât aria de cuprindere a SGBD este mai vastă,
cu atât aceste două obiective sunt mai importante şi mai dificil de
realizat.
Cu privire la integritatea datelor, pot să apară trei situaţii
practice:
Asigurarea integrităţii semantice a datelor. Obiectivul
impune de fapt evitarea introducerii de date incorecte sau efectuarea
unor prelucrări incorecte. Erorile trebuie sesizate la un interval de
timp cât mai scurt după apariţia lor.
Controlul accesului concurent la date. Acesta implică
evitarea obţinerii de rezultate neverosimile ale prelucrărilor ca
urmare a execuţiei concurente a mai multor prelucrări în regim
multiutilizator.
Salvarea şi restaurarea bazei de date. În cazul funcţionării
anormale a sistemului, bazele de date trebuie să poată fi readuse la
starea avută înainte ca defecţiunea să survină.
51
Controlul accesului concurent la baza de date
În sistemele multiutilizator, sistemul de operare asigură
accesul programelor la resurse după o disciplină internă (uneori
"execuţie întreţesută"). Întreruperea accesului unui program la baza
de date pentru a permite accesul altuia poate avea consecinţe grave
asupra operaţiunii în curs, alterând datele.
Pentru controlul accesului concurent, SGBD multiutilizator
operează cu mecanismul tranzacţiilor. Tranzacţia este o secvenţă de
operatii care din punctul de vedere al SGBD se constituie ca un tot
unitar, acceptându-se fie derularea ei completă, fie anularea tuturor
modificărilor aduse bazei de date (derularea inversă). Orice
tranzacţie are un punct de început şi unul de sfârşit. Tranzacţiile sunt
de două tipuri:
* implicite, care au puncte de început şi de sfârşit automat
definite (de ex., comenzile INSERT, UPDATE, DELETE din SQL);
* explicite, adică acelea care prezintă clauze pentru stabilirea
punctelor de început şi de sfârşit (BEGIN TRANSACTION,
COMMIT/END TRANSACTION, ROLLBACK).
Tranzacţiile nu produc anomalii dacă au loc de o manieră
succesivă (execuţie serială). Cum din motive de performanţă
execuţia seriala nu este posibilă pe sisteme multiutilizator, se
apelează la tehnica blocării pentru a asigura o execuţie serializabilă a
tranzacţiilor. În cea mai simplă formă, blocarea constă în interzicerea
accesului altor procese la datele implicate într-o tranzacţie, până ce
aceasta nu se finalizează. Blocarea poate avea loc la nivel de bază de
date, fişier, grup de înregistrări, înregistrare sau chiar câmp. Totuşi,
blocarea nu este atât de restrictivă, în sensul că:
* se permite citirea de către un utilizator a datelor accesate
spre citire de alt utilizator (blocare partajabilă);
* nu se permite citirea de către alţi utilizatori a datelor
accesate în scopul actualizării de alt utilizator (blocare exclusivă).
Blocarea se realizează prin emiterea de către o tranzacţii a
unei cereri explicite de blocare.
52
Accesul concurent şi complexitatea mecanismului de blocare
sunt influenţate de granularitatea blocării. Se intuieşte uşor faptul că
blocarea întregii baze de date este mai neeconomicoasă decât alte
tipuri de blocare, dar blocarea unui singur câmp complică foarte mult
mecanismul de blocare. În practică, SGBD execută blocarea la nivel
de înregistrare, grup de înregistrări sau fişier.
O problemă specială o constituie interblocarea (deadlock), care
constă în blocarea de către două tranzacţii a anumitor resurse, apoi
fiecare solicită resursele blocate de cealaltă. Există două strategii de
rezolvare a interblocării:
* prevenirea interblocării: fiecare tranzacţie blochează de la
început toate resursele de care are nevoie, astfel că alte tranzacţii nu
le vor putea accesa; cum este imposibil de cunoscut dinainte ce
resurse sunt necesare, metoda are o slabă aplicabilitate practică;
* soluţionarea interblocării: se blochează resursele pe măsura
ce tranzacţia le solicită, deci interblocarea poate surveni, dar apoi se
folosesc metode pentru detectarea şi eliminarea sa. Pentru aceasta,
sistemul poate să ţină evidenţa tranzacţiilor în curs, deci a
înregistrărilor accesate. Dacă survine interblocarea, una dintre părţi
va fi victima, adică tranzacţia sa va fi abandonată. Toate resursele
vor fi deblocate iar utilizatorul va fi anunţat despre acest lucru.
Procesul întrerupt poate fi: cel cu cele mai multe resurse blocate; cel
cu cele mai putine resurse blocate; cel mai vechi; cel mai recent; cel
cu cea mai mică prioritate la execuţie; cel care nu a realizat încă
actualizarea BD etc.
Aceste precizări sunt valabile pentru calculatoarele mari,
SGBD micro având facilităţi mult mai modeste de control al
tranzacţiilor concurente.
53
O stare consistentă este una în care sunt reflectate rezultatele
finale ale execuţiei unor tranzacţii, nici o tranzacţie nu este în curs de
execuţie şi sunt satisfăcute restricţiile semantice necesare.
Există mai multe tehnici de restaurare. Una dintre ele constă
în terminarea tranzacţiilor active la momentul defecţiunii.
Informaţiile necesare restaurării pot îmbrăca forma unor copii de
siguranţă, jurnale ale tranzacţiilor (succesiunea cronologică a
prelucrărilor), puncte de control (checkpoints) şi jurnale ale
imaginilor (rezultatele prelucrărilor succesive). Restaurarea se poate
face automat sau manual.
55
1.5. Administrarea datelor şi a bazelor de date
În prezent este larg recunoscută importanţa critică a gestiunii
datelor în cadrul unei organizaţii economice. Datele şi informaţiile
asociate reprezintă o resursă mult prea valoroasă pentru a nu
beneficia de o atenţie sporită în ceea ce priveşte activitatea de
administrare a lor.
Administrarea ineficientă a datelor duce la o slabă
valorificare a acestora şi se poate caracteriza prin:
- definiţii multiple ale aceleiaşi entităţi de date şi/sau reprezentări
inconsistente ale unor aceleaşi elemente de date în baze de date
diferite, conducând la imposibilitatea integrării datelor
- lipsa unor elemente cheie ale datelor, fapt ce determină pierderea
valorii datelor pentru organizaţie
- nivele scăzute ale calităţii datelor datorate unor surse inadecvate
de date sau timpilor prohibitivi de transfer de la un sistem la altul
- lipsa unei familiarizări cu datele existente la dispoziţie, inclusiv
lipsa cunoaşterii locaţiilor şi semnificaţiilor datelor în procesele
de adoptare a deciziilor strategice sau de planificare.
Având în vedere aceste aspecte negative, majoritatea
organizaţiilor au creat două funcţii speciale: pentru administrarea
datelor, respectiv pentru administrarea bazei de date.
Administratorul datelor este custodele datelor organizaţiei,
fiind direct răspunzător de controlarea utilizării şi de protejarea
resurselor de date. De asemenea, administratorul datelor are ca
sarcini:
- determinarea cerinţelor organizaţiei privind datele, estimarea
volumului de date şi a creşterii probabile a acestuia
- dezvoltarea unui model de date general
- realizarea proiectării conceptuale şi logice a bazei de date
- gestionarea dicţionarului de date
- soluţionarea conflictelor cauzate de accesul concurent la o
aceeaşi resursă de date (partajarea unei resurse de date)
- adoptarea deciziilor privitoare la memorarea datelor
56
- impunerea şi menţinerea unor definiţii ale datelor şi a unor
standarde
- îmbunătăţirea performanţelor bazei de date
- asigurarea mijloacelor de instruire a utilizatorilor
- implicarea într-o gamă largă de activităţi ca planificarea, analiza,
proiectarea, implementarea şi asigurarea securităţii bazei de date
- asigurarea unei documentaţii complete care să includă modelul
întreprinderii, standardele, politicile, procedurile, utilizarea
dicţionarului de date şi controlul asupra utilizatorilor finali
- menţinerea contactului cu utilzatorii pentru a determina noile
cerinţe şi a rezolva dificultăţile privind accesul la date sau
performanţele
Administratorul bazei de date este implicat în proiectarea
fizică a bazei de date şi în implementarea efectivă a acesteia pe
suporturile fizice de memorare, în impunerea standardelor de
securitate şi protecţie, precum şi în activităţile de salvare şi restaurare
a bazei de date.
Funcţiile generale ale administrării datelor şi bazelor de date sunt
următoarele:
- stabilirea politicilor, procedurilor şi standardelor
organizaţiei în materie de date, ca măsuri de protecţie a datelor
şi a bazei de date
- politicile datelor sunt reprezentate de o serie de
specificaţii care explicitează scopurile administrării
datelor (de exemlu, "fiecare utilizator trebuie să posede o
parolă"
- procedurile asociate datelor sunt exprimări ale unor
acţiuni ce trebuie întreprinse pentru efectuarea unor
anumite activităţi; de exemplu, procedurile de salvare şi
restaurare a datelor ce trebuie cunoscute de către toţi
utilizatorii
- standardele asociate datelor sunt convenţii explicite ce
trebuie urmate pentru a facilita cunatificarea nivelului de
calitate a datelor şi a bazei de date; de exemplu,
convenţiile de notaţie pentru obiectele componente ale
unei baze de date trebuie standardizate, urmând a fi
57
respectate întocmai de către toţi programatorii de
aplicaţii.
- planificarea ce presupune administrarea eficientă a datelor şi a
bazei de date implică atât înţelegerea cu exactitate a nevoilor
reale ale organizaţiei, cât şi abilitatea de a contribui la
dezvoltarea unei arhitecturi informaţionale care să satisfacă
nevoile organizaţiei
- rezolvarea conflictelor de date. Bazele de date sunt utilizate cu
scopul de a fi partajate; mai mult, de regulă, bazele de date
implică date ce provin de la mai multe departamente din cadrul
organizaţiei. În acest context, administratorilor datelor şi a
bazelor de date le revine misiunea de a media conflictele
generate de asumarea dreptului de proprietate asupra datelor din
partea unor utilizatori
- gestionarea depozitului intern de date al cărui conţinut este
reprezentat de metadatele ce descriu datele şi resursele de
procesare a datelor unei organizaţii. În prezent depozitele de date
înlocuiesc dicţionarele de date în majoritatea organizaţiilor,
constituind instrumente esenţiale de sprijinire a activităţilor de
administrare a datelor şi a bazelor de date
- selectarea componentelor hadware şi software. Evaluarea şi
selectarea componentelor hardware şi software este un factor
cheie în administrarea eficientă a datelor unei organizaţii,
aspectul cel mai important fiind cel al asigurării permanente a
unei compatibilităţi depline între componentele hardware şi cele
software
- gestionarea aspectelor privind securitatea şi
confidenţialitatea datelor. Scopul asigurării protecţiei şi
securităţii datelor este de a preveni apariţia unor ameninţări
intenţionate sau accidentale la adresa integrităţii datelor şi a
accesului la date. Asigurarea protecţiei datelor se concretizează
în elaborarea şi implementarea unor planuri detaliate de
securitate a datelor ce includ:
- politici şi proceduri administrative
- protecţii ale datelor la nivel fizic
- protecţii ale sistemului de gestiune a bazei de date, ce
includ:
58
- perspective sau subscheme care restricţionează
accesul utilizatorilor
- reguli de autorizare care identifică utilizatorii şi
restricţionează acţiunile pe care aceştia le pot
efectua asupra bazei de date
- proceduri definite de utilizatori ce impun restricţii şi
limitări adiţionale asupra utilizării bazei de date
- proceduri de criptare ce conduc la criptarea datelor
din baza de date într-un format neinteligibil
- scheme de autentificare ce identifică fără
ambiguitate persoanele ce intenţionează să acceseze
baza de date
- facilităţi suplimentare de salvare, monitorizare şi
verificare care conduc la uşurarea activităţii de
restaurare.
- asigurarea procedurilor specifice de salvare şi restaurare
59
Capitolul II. Mediul integrat
de gestiune şi programare
Oracle
60
existente la nivelul unei organizaţii şi funcţionarea ca un sistem
integrat. Arhitectura GC evidentiază grafic diferitele componente şi
legăturile dintre ele. Structurarea se face pe patru nivele (aplicaţii,
server de aplicaţii, baze de date, echipamente) conectate prin
mecanisme de interfaţă de servicii şi monitorizare (control). Oracle
este prima companie care a promovat tehnologia GC, într-un sistem
de gestiune a bazelor de date – Oracle 10g – pentru intreprinderi.
Astfel, oferă o infrastructură software completă şi comercială,
proiectată special pentru GC lucrul cu baze de date. Oracle 10g
permite adaptarea sistemelor informatice la modelul EGC, care
foloseşte puterea de prelucrare a unui mare număr de calculatoare,
puţin costisitoare, care acţionează ca un tot unitar.
Utilizarea pe dispozitive de stocare şi servere standardizate a
devenit mai usoară şi la un preţ mai redus.
Scurt istoric: Oracle este produsul unei mari companii care a
avut parte de un succes enorm în cei mai bine de 30 de ani de când se
află pe piaţă. Totul a început în anii '60, când Codd, cercetător la
I.B.M., a studiat posibilitatea ameliorării modului de stocare a
datelor în fişiere, deoarece existenţa informaţiilor redundante
predispunea la erori greu de depistat. În 1970 el a publicat un articol,
"A Relaţional Model of Data for Large Shared Databanks" care a
schimbat complet concepţiile privind structura bazelor de date. Un
programator, Larry Ellison, sesizând importanţa practică a teoriei lui
Codd, a realizat un produs software, Oracle, şi o firmă pentru
promovarea acestuia, Oracle Coorporation. De-a lungul anilor,
produsul firmei Oracle a trecut prin multe schimbări de nume, de la
version 1 la version 6, apoi la Oracle 7, 8, 8i, 9i, 10g şi chiar 11g în
anul 2009 (fig.2.1). Începând cu Oracle 12c, sistemul de gestiune a
bazelor de date Oracle a trecut în Cloud.
Orice sistem de gestiune a bazelor de date are cel puţin un
limbaj de programare cu instrucţiuni pentru descrierea datelor - DDL
şi instrucţiuni pentru manipularea datelor – DML. Aceste limbaje
permit implementarea unui model logic de date pentru baze de date,
deci sunt specifice. Pe langă acestea, majoritatea sistemelor deţin sau
au interfeţe cu alte limbaje de diferite tipuri, scopul fiind acela de a
oferi toate facilitaţile de programare necesare pentru dezvoltatorul de
61
aplicaţii cu baze de date. Acest lucru este necesar deoarece
majoritatea problemelor din lumea reală implică, pentru
informatizare, utilizarea mai multor tipuri de limbaje de programare,
deoarece fiecare oferă anumite facilitaţi şi avantaje.
7
https://ittutorial.org/wp-
content/uploads/2019/06/Oracle_Database_Versions_History.png /
62
universale – Fortran, Cobol, Pascal, C etc. Rezultă asadar că Oracle
oferă dezvoltatorului posibilitatea de a scrie cod sursa în limbajele de
programare pe care le ştie sau de care are nevoie, practic în orice tip
de limbaj.
63
2.2 Instalarea sistemului Oracle 11g Express
Edition
Sistemul Oracle 11g Express edition este o versiune academică
a sistemului de gesttiune a bazelor de date Oracle 11g, având
posibilitatea gestiunii utilizatorilor şi a obiectelor bazei de date direct
dintr-un browser WEB. Kit-ul de instalare poate fi descarcat direct
de pe www.oracle.com.
Primii paşi sunt descrişi generic în Figura 2.3.
64
Kit-ul de instalare cere întâi să se accepte condiţoiile de
utilizare. Apoi să se introducă o parolă-mster pentru cele douăp
conturi de Administrare SYS, respectiv SYSTEM (Fig. 2.4)
65
Odata instalat, în primă etapă trebuie creată o bază de date;
pentru aceasta se porneşte modul APEX de administrare folosind
selecţie AllPrograms-> Oracle Database 11g ExpressEdition-> Get
Started (Fig. 2.6)
66
Ultima opţiune presupune autentificarea administratorului
general )cinturile SYSTEM sau SYS=, cu parola introdusă în etapa
de instalare. (Fig. 2.8 propune parola “acasa”)
s
tu
d
s
tud
69
Crearea unui utilizator nou presupune accesarea sectiunii
Administration din meniul grafig, a subsecţiunii Manage Users and
Groups (Fig 2.12). Pentru orice utilizator nou se cer introduse un
username, o adresă de e-mail, numele bazei de date pe care lucrează
implicit (Default Schema), statutul (Administator, Developer, Simple
user), alte drepturi (SQL workshop access este fundamental) şi o
parolă.
70
Fig. 2.14 Accesarea interfeţei de Comenzi SQL
71
submeniul SQL Commands (Fig. 2.14). Instrucţiunile SQL simple
pot fi rulate din fereastra SQL Commands folosind butonul Run.
DESCRIBE emp;
72
Fig. 2.16 Tabela emp
73
2.3. Oracle Forms Builder
Oracle Forms este un limbaj puternic, utilizat pentru
dezvoltarea aplicaţiilor interactive. Orice aplicaţie creată cu Oracle
Developer este prin natura ei o aplicaţie multi-utilizator, bazată pe
tehnologia client/server, independentă de platforma.
Oracle Forms constituie coloana vertebrală a pachetului de
programe Oracle Developer fiind utilizat pentru realizarea
interfeţelor interactive ale aplicaţiilor. Permite apelarea atât a altor
componente Oracle Developer cât şi a programelor scrise în C sau a
altor aplicaţii.
Oracle Forms este bazat pe programarea orientată pe
eveniment, fapt ce permite scrierea de cod PL/SQL ataşat unui
eveniment pentru a defini acţiunea care se va executa la apariţia
evenimentului respectiv. De asemenea Oracle Forms utilizează şi
conceptul de programare orientată pe obiect, permiţand mostenirea
de obiecte (moştenirea anumitor caracteristici) încapsularea
(definirea unor caracteristici proprii fiecărei clase de obiecte)
polimorfismul (rescriere unor funcţii).
În directorul destinat instrumentelor Oracle Developer sunt
create trei icoane pentru Oracle Forms: Forms Builder, Forms
Compiler şi Forms Runtime. Dezvoltarea unei aplicaţii se realizează
cu Form Builder, care poate apela pentru compilare şi execuţie
celelalte două componente, nefiind necesară apelarea separată a
acestora.
Forms Builder este mediul în care aplicaţiile sunt create,
testate şi depanate. El furnizează o serie de instrumente de design cu
ajutorul cărora se poate crea şi modifica funcţionalitatea sau aspectul
unei aplicaţii.
Object Navigator
Editorul de proprietăţi (Property Palette)
Editorul de Aranjare (Layout Editor)
Editorul PL/SQL (PL/SQL Editor)
Editorul de meniuri (Menu Editor)
74
Fig. 2.17 Mediul Oracle Forms Builder 6i
Toate aceste instrumente sunt disponibile în meniul Tools
(fig. 2.17).
Cea mai importantă componenta este Object Navigator.
Aceasta permite accesul la diverse componente pentru realizarea
formelor, meniurilor şi biblioteciilor, precum şi la obiectele bazei de
date cum ar fi declanşatoarele (triggers) şi procedurile stocate.
Object Navigator permite navigarea facilă între elementele
ce aparţin formelor. Un obiect poate fi editat, modificat sau creat în
întregime de către Object Navigator. Fereastra principală a Object
Navigator prezintă fiecare obiect (instanţă) sau tip de obiect, ce poate
fi precedat de unul de simbolurile + si -. Aceste semne apar atunci
75
când un obiect sau un tip de obiecte are elemente (copii) care îi
aparţin: semul – indică faptul că deja obiectul este expandat, iar
semnul + apare atunci când acesta este restrâns, adică elementele
copii sunt ascunse.
Object Navigator utilitează icoane pentru a indica un obiect
care are proprietăţi. O proprietate este un parametru care descrie un
obiect. Fiecare tip de obiect are o listă diferită de proprietăţi care
poate fi modificată utilizând Property Pallete. Obiectele sunt create
folosind opţiunea Navigator-Create din meniul principal. Obiectele
pot fi create şi şterse selectând opţiuni din meniul Navigator sau
utilizând bara de butoane din fereastra Navigator.
76
unei taste. Trigger-ele on- sunt de obicei numite declanşatoare de
tranzacţii (transaction triggers), multe dintre ele fiind generate
automat de către Oracle Forms. Exemplu: ON-CHECK-DELETE-
MASTER este generat în momentul creării unei relaţii între blocuri.
Trigger-e pre- si post- sunt activate înainte respectiv după un
eveniment. Trigger-ele when- sunt foarte utilizate (WHEN-
BUTTON-PRESSED, WHEN-VALIDATE-ITEM).
Blocul PL/SQL care defineşte declanşatorul poate fi executat
cu succes sau nu. Un declanşator eşuează când blocul PL/SQL
generează o excepţie specifică: form_trigger_failure.
78
un text lung într-un text_item. Un editor este definit prin
specificarea unor proprietăţi cum ar fi poziţia, mărimea, titlul si
fontul.
2.4.9. Parametrii (Parameters)
Un parametru este o variabilă utilizată pentru transmiterea
datelor între două forme sau între o formă şi un raport. Atunci când o
formă este apelată dintr-o altă formă parametrii sunt transmişi ca
parte a unei liste de parametri.
Prin definirea unor parametrii pentru o formă folosind Object
Navigator, forma se va aştepta să primescă o valoare pentru fiecare
dintre parametrii, iar în cazul în care valoarea nu va fi transmisă,
parametrul va primi o valoare implicită. Cu alte cuvinte parmetrii
reprezintă parametrii de intrare pentru o formă, ai căror valori sunt
transmise din forma apelantă.
2.4.10. Unităţi de program (Program Units)
Unităţiile de program sunt de 4 tipuri: proceduri
(procedures), funcţii (functions), specificaţii de pachete (package
specifications) şi corpuri de pachete (package bodies).
În momentul când se creează o unitate de program sunt
specificate numele şi tipul acesteia, iar apoi va apărea editorul
PL/SQL care va conţine un cadru pentru tipul de unitate de program
selectată (numele, tipul unităţii de program, cuvântul cheie BEGIN şi
cuvântul cheie END urmat de “;”).
Procedurile si funcţiile sunt definite de către utilizator, cu
parametrii opţionali de intrare si de ieşire care pot fi apelaţi din orice
alt bloc PL/SQL în cadrul aceluiaşi modul.
Apelarea unei proceduri: nume_procedura
(argumente)
iar o funcţie se apelează în felul următor: :variabilă
:= nume_funcţie(argumente).
79
2.4.11. Ferestre (Windows)
O fereastră este un element esenţial al unei interfeţe grafice.
Ferestrele sunt suprafeţe rectangulare care comunică informaţii
utilizatorului şi conţin informaţii ce pot fi manipulate.
80
Oracle11g Database aduce noi funcţionalităţi atât pentru
aplicaţiile de baze de date tradiţionale, cât şi pentru aplicaţiile
Internet:
gestionează orice tip de informaţii;
oferă scalabilitate complete atât pentru
sistemele cu un singur processor, cât şi pentru
sistemele complexe cu mai multe procesoare
sau configuraţiile cluster cu mai multe noduri;
întruneşte condiţiile de disponibilitate
permanenţă a datelor;
garantează securitatea informaţiilor;
oferă posibilităţi eficiente de analiză a datelor;
permite implementarea rapidă a soluţiilor
pentru afaceri etc.
Pentru a optimiza performanţele aplicaţiilor, Oracle11g
Database oferă o serie de componente care îmbunătăţesc
posibilităţile produselor: Application Server şi Developer Suite.
Bazele de date Oracle11g permit integrarea de cod Java în
aplicaţii. Avantajul utilizării Java, faţă de alte limbaje (de exemplu
,C), constă în faptul că acesta a fost dezvoltat astfel încât să poată
preveni accesul neautorizat în sistemul de operare pe care rezidă
codul Java. Un alt avantaj este faptul că permite gestiunea automată a
stocarii datelor. Astfel, nu mai este necesară alocarea sau dezalocarea
resurselor de stocare în mod explicit de către dezvoltatorii de
aplicaţii.
Instalarea sistemului Oracle11g cu opţiunea Oracle JVM
(Java Virtul Machine) permite executarea aplicaţiilor care utilizează
proceduri stocate Java, SQLJ, CORBA/EJB (Enterprise Java Beans),
Servlet, JSP şi interfaţă JDBC. Maşina vituală Java nu
interacţionează direct cu sitemul de operare, ci cu bibliotecile bazei
de date.
Oracle11g JVM foloseşte facilităţile server-ului de baze de
date cu scopul de a planifica execuţiile java pentru un număr
considerabil de utilizatori, în sistem concurenţial. În acest sens, se
permite mai multor utilizatori conectaţi la server să execute simultan
81
acelaşi cod Java, ca şi când ar rula propriul cod pe propria maşină
virtual Java.
82
Componentele permit editarea, testarea şi dezvoltarea, într-
un singur mediu, a aplicaţiilor
Java şi a celor care implică servicii Web. Suportul pentru
serviciile Web permite publicarea ca servicii Web atât a claselor
Java, cât şi a procedurilor stocate Java sau PL/SQL .
Oracle11gAS suportă toate tipurile de clienti de reţea şi este
punct central de acces către baza de date. Acesta include două
extensii: Oracle Call Interface (OCI), pentru accesul nativ la bazele
Oracle, şi Oracle Database Conectivity (ODBC) , pentru accesul la
alte tipuri de baze.
Prin Oracle11gAS Portal se pot crea portaluri web pentru a
centraliza toate informaţiile din sistemele companiei şi a le
redistribui către anumite categorii de utilizatori. Acest mediu oferă,
pentru site-urile de tip portal, un punct comun ce permite accesul cu
uşurinţă la date, integrarea cu aplicaţiile şi conţinutul multimedia din
baza de date. Portalul asigură utilizatorilor acces la mai multe
aplicaţii, autentificarea acestora realizându-se o singură data, pentru
toate aplicaţiile în desfăşurare.
Oracle11gAS oferă servicii de tip director pentru
monitorizarea, gestiunea şi securizarea sistemelor distribuite. După
realizarea autentificării iniţiale, utilizatorul este validat automat
pentru alte aplicaţii pe care le accesează, fără a fi necesară
reintroducereea informaţiei de conectare.
83
oferă posibilitatea modelării UML integrate. Acest standard perminte
construirea de modele vizuale, conform cărora se poate genera cod
util în implementarea aplicaţiilor şi a serviciilor Web.
Componentele Oracle11g Developer pot fi folosite pentru:
generarea de servicii Web şi aplicaţii performante care
pot rula pe diferite tipuri de dispozitive;
extinderea aplicaţiilor tranzacţionale cu funcţionalităţi
de tip business intelligence (interogări ad-hoc,
rapoarte Web complexe), de publicare şi analiză a
datelor
dezvoltarea rapidă de aplicaţii folosind tehnologia
Rapid Application Development
crearea de aplicaţii de tip e-business integrate, bazate
în totalitate pe mediul Internet etc.
84
implementează servicii Web şi se asigură publicarea, rularea şi
accesrea acestora direct dintr-o diagramă de clase UML.
Oracle11g Designer este pachetul de utilitare cu generator
integrat pentru proiectarea şi dezvoltarea de aplicaţii complexe.
Componentele sale permit descrierea şi analiza modelului,
proiectarea diagramei entitate/relaţie şi de aplicaţii orientate pe
obiecte.
Oracle11g Forms Developer este utilitar ce foloseşte
tehnologia RAD, cu ajutorul căruia se construiesc uşor şi rapid
aplicaţii ce interacţionează cu informaţiile bazei de date (forme
interactive şi grafice). Utilitarul este orientat pe evenimente,
permiţând definirea prin PL/SQL a acţiunii ce se va executa la
apariţia unui anumit eveniment. Utilizând tehnologia Java, aplicaţiile
pot include legături web şi butoane cu funcţionalităţi complexe.
Pentru dezvoltarea de aplicaţii complexe, sistemul oferă
precompilatoarele Pro* ( C/C++, PL/l, COBOL, ADĂ, FORTRAN şi
Pascal) care permit încorporarea de instrucţiuni SQL sau blocuri
PL/SQL în module scrise utilizând alte limbaje de programe.
Precompilarea citeşte codul sursă şi generează un fişier ce poate fi
procesat de către compilatorul limbajului respectiv.
Folosirea precompilatoarelor Oracle permite:
Dezvolatrea aplicaţiilor de baze de date în
limbajul de nivel înalt;
Utilizarea tehnicilor de programare avansată;
Dezvoltarea de aplicaţii cu un grad înalt de
personalizare;
Verificarea sintactică şi semantica a
comenzilor SQL şi a blocurilor PL/SQL;
Precompilare separata a mai multor module de
cod şi apoi înglobarea acestora într-un singur
program executabil;
Specificarea optiunilor de precompilare;
Accesul concurent la baze de date Oracle din
locaţii diferite etc.
85
CapitoluI IV. LIMBAJUL DE
DEFINIRE, INTEROGARE ŞI
MANIPULARE A BAZELOR
DE DATE SQL
3.1. Evoluţie şi performanţe
SQL reprezintă cel mai important limbaj actual în domeniul
bazelor de date prin gama comenzilor şi opţiunilor de care dispune,
dar mai ales datorită faptului că s-a reuşit standardizarea lui şi
portarea pe toate sistemele de gestiune a bazelor de date
semnificative.
Încă din anul 1970, E.F.Codd a sugerat "adoptarea unui
model relaţional pentru organizarea datelor [...] care să permită
punerea la punct a unui sub-limbaj universal pentru gestiunea
acestora, sub-limbaj care să fie, în fapt, o formă aplicată de calcul
asupra predicatelor".
După mulţi autori, momentul decisiv în naşterea SQL ca
limbaj îl constituie lansarea proiectului System/R de către firma IBM,
eveniment ce a avut loc în 1974. Tot în 1974 Chamberlin şi Boyce au
publicat un articol în care este prezentat un limbaj structurat de
interogare, denumit SEQUEL (Structured English as QUEry
Language). În 1975 Chamberlin, Boyce, King şi Hammer redactează
o lucrare dedicată sub-limbajului SQUARE, asemănător SEQUEL-
ului, dar care utiliza expresii matematice şi nu cuvinte din limba
engleză. Autorii celor două studii au demonstrat că limbajele
SEQUEL şi SQUARE sunt complete din punct de vedere relaţional.
În 1976 un colectiv de autori condus de Chamberlin
elaborează o nouă lucrare în care se face referire la SEQUEL 2,
acesta fiind declarat limbaj de interogare al SGBD-ului System/R al
firmei IBM.
86
În 1980 Chamberlin schimbă denumirea SEQUEL în SQL -
Structured Query Language (Limbaj Structurat de Interogare), din
motive legale (s-a descoperit că acronimul SEQUEL fusese utilizat
anterior de altcineva), dar şi astăzi mulţi specialişti pronunţă SQL ca
pe predecesorul său.
Anii următori au înregistrat apariţia a o serie întreagă de
lucrări dedicate SQL care l-au perfecţionat şi consacrat ca pe cel mai
răspândit limbaj de interogare a bazelor de date relaţionale, fiind
prezent în numeroase "dialecte" specifice tuturor SGBDR-urilor
actuale, de la DB2 la Microsoft SQL Server, de la Oracle la FoxPro
şi Access.
Încercând să răspundă solicitărilor pentru standardizarea
unui limbaj de lucru cu bazele de date, Institutul Naţional American
pentru Standarde (American National Standard Institute - ANSI) a
început să realizeze în 1982 un limbaj relaţional pentru bazele de
date, bazat pe un articol conceptual al firmei IBM. În 1986 ANSI
publică standardul SQL ANSI X3.135-1986, standard care se
bazează, într-o mare măsură, pe "dialectul" SQL al produsului DB2
de la IBM. Organizaţia Internaţională pentru Standarde (ISO) a
adoptat propriul document, aproape identic cu ANSI SQL-86, pe
care l-a publicat în 1987 ca ISO 9075-1987 Database Language SQL.
SQL-86 defineşte comenzile de bază ale SQL, inclusiv pentru
crearea de tabele şi tabele virtuale (CREATE TABLE, CREATE
VIEW), însă nu conţine opţiuni de modificare a structurii sau
ştergere (ALTER…/DROP…) şi nici comenzi pentru acordare şi
revocare a drepturilor utilizatorilor.
În 1989 are loc revizuirea şi extinderea acestui standard,
"născându-se" SQL-89, care mai este denumit şi SQL-1.
Deşi recunoscut ca bază a multor SGBDR-uri comerciale,
SQL-1 şi-a atras numeroase critici. În plus, variantele comercializate
de diferiţii producători, deşi asemănătoare în esenţă, erau (şi sunt)
incompatibile la nivel de detaliu. Pentru a umple golurile SQL-1,
ANSI şi ISO au elaborat în 1992 versiunea SQL-2, specificaţiile
fiind prezentate la un nivel mult mai detaliat (dacă SQL-1 se întindea
pe numai 100 de pagini, SQL-2 a fost publicat în aproape 600).
Dintre numeroasele facilităţi aduse de SQL-92 amintim: joncţiunea
externă (OUTER JOIN), atribute zi-oră şi de alte tipuri, raportare
standardizată a erorilor, modificarea schemei bazei de date (DROP,
87
ALTER, REVOKE, GRANT), SQL dinamic, modificări şi ştergeri
referenţiale în cascadă, amânarea verificării restricţiilor, niveluri de
consistenţă a tranzacţiilor etc.
Pe lângă ANSI, ale cărui standarde au cea mai largă
audienţă, mai există şi alte organisme de standardizare SQL. X/Open
este un grup de firme vest-europene care a adoptat SQL ca nucleu al
unei întregi serii de standarde menite să asigure realizarea unui
mediu general pentru aplicaţii portabile, grefat pe sistemul de operare
UNIX.
IBM a avut un aport incontestabil la apariţia şi maturizarea
SQL, fiind un producător cu mare influenţă în lumea SGBD-urilor,
iar produsul său, DB2, este unul din standardele de facto ale SQL.
În 1989 un grup de producători de instrumente dedicate
bazelor de date au format SQL Access Group, în vederea realizării
conexiunilor dintre SGBDR-urile fiecăruia, pe baza unor specificaţii
comune, din care un prim set a fost publicat în 1991 sub titulatura
RDA (Remote Database Access). Specificaţiile RDA n-au reuşit să
se impună pe piaţa SGBD-urilor.
La insistenţele firmei Microsoft, SQL Access Group şi-a
concentrat eforturile pentru elaborarea unei interfeţe-standard pentru
SQL. Pe baza unui set de propuneri înaintat de Microsoft, în 1992 au
rezultat specificaţiile CLI (Call Level Interface). Acestea reprezintă
un ansamblu de funcţii şi proceduri pentru conectarea bazelor de date
prin SQL în medii multi-utilizator şi multi-platformă. Având drept
reper CLI, Microsoft elaborează şi implementează în acelaşi an un
set propriu, ODBC (Open DataBase Conectivity), care a devenit
standard în materie de interfaţă SQL pentru microcalculatoare
compatibile IBM PC în vederea accesării bazelor de date relaţionale.
Standardul SQL:1999, denumit iniţial SQL3, are ca
principale orientări: transformarea acestuia într-un limbaj complet, în
vederea definirii şi gestionării obiectelor complexe şi persistente.
Aceasta include: generalizare şi specializare, moşteniri multiple,
polimorfism, încapsulare, tipuri de date definite de utilizator, triggere
şi proceduri stocate, suport pentru sisteme bazate pe gestiunea
cunoştinţelor, expresii privind interogări recursive şi instrumente
adecvate de administrare a datelor.
88
Standardul SQL:2003 are drept caracteristici majore:
caracteristici legate de XML, funcţii window, secvenţe standardizate
şi coloane cu valori auto-generate (incluzând coloane-identitate).
Standardul SQL:2006 defineşte căi prin care SQL poate fi
utilizat împreună cu XML, căi de a importa şi stoca date XML într-o
bază de date SQL, de a le manipula în cadrul acelei baze de date şi de
a le publica.
Din punctul de vedere al utilizatorului final, obiectivul
principal al SQL constă în a oferi utilizatorului mijloacele necesare
formulării unei consultări numai prin descrierea rezultatului dorit, cu
ajutorul unei expresii logice, fără a fi necesară şi explicitarea
modului efectiv în care se face căutarea în baza de date. Altfel spus,
utilizatorul specifică rezultatul, iar sistemul se ocupă de procedura
de căutare.
Deşi este considerat, în primul rând, un limbaj de interogare,
SQL este mult mai mult decât un instrument de consultare a bazelor
de date, deoarece permite, în egală măsură:
definirea datelor;
consultarea bazei de date;
manipularea datelor din bază;
controlul accesului;
partajarea bazei între mai mulţi utilizatori ai acesteia;
menţinerea integrităţii bazei de date.
După Groff şi Weinberg, principalele atuuri ale SQL sunt:
Independenţa de producător, nefiind o tehnologie
proprietară;
Portabilitate între diferite sisteme de operare;
Este standardizat;
"Filosofia" sa se bazează pe modelul relaţional de
organizare a datelor;
Este un limbaj de nivel înalt, cu o structură care se apropie
de limba engleză;
Furnizează răspunsuri la numeroase interogări simple, ad-
hoc, neprevăzute iniţial;
Constituie suportul programatic pentru accesul la baza de
date;
Permite multiple imagini asupra datelor bazei;
89
Este un limbaj relaţional complet;
Permite definirea dinamică a datelor, în sensul modificării
structurii bazei chiar în timp ce o parte din utilizatori sunt
conectaţi la baza de date;
Constituie un excelent suport pentru implementarea
arhitecturilor client-server.
Limbajul SQL constituie un exemplu de limbaj orientat spre
tansformări sau limbaj proiectat să utilizeze relaţiile pentru a
transforma intrările în ieşirile cerute. Ca limbaj, SQL are două
componente principale:
- un limbaj de definire a datelor pentru definirea structurii
bazei de date (DDL)
- un limbaj de manipulare a datelor (DML) pentru regăsirea şi
reactualizarea datelor.
Limbajul SQL conţine numai comenzi de definire şi manipulare
şi nu conţine comenzi de flux de control. Cu alte cuvinte nu există
comenzi IF…THEN…ELSE, GO TO, DO…WHILE sau alte
comenzi care să ofere un flux de control. Acestea trebuie
implementate prin utilizarea unui limbaj de programare sau de
control al lucrărilor sau interactiv prin decizii ale utilizatorului.
Datorită acestui fapt, limbajul SQL poate fi utilizat în două moduri.
Prima modalitate este de a folosi limbajul SQL interactiv, prin
introducerea instrucţiunilor de la un terminal. A doua este de a
integra instrucţiunile SQL într-un limbaj procedural.
SQL este un limbaj relativ uşor de învăţat:
Este un limbaj neprocedural - se specifică ce informaţii sunt
cerute şi nu cum sunt obţinute (limbajul SQL nu necesită
specificarea metodelor de acces la date).
SQL este un limbaj modern, cu format liber, ceea ce înseamnă că
nu este necesar ca fragmentele de comenzi să fie scrise în
anumite locuri de pe ecran. Totuşi o comandă (sau un set de
comenzi SQL) este mai lizibilă dacă se foloseşte indentarea şi
alinierea. De exemplu:
- fiecare clauză din cadrul unei comenzi trebuie să înceapă pe
o linie nouă;
- începutul fiecărei clauze trebuie să fie aliniat cu începutul
celorlalte;
90
- dacă o clauză are mai multe părţi, fiecare dintre ele trebuie să
apară pe câte o linie separată şi trebuie să fie indentată faţă
de începutul clauzei pentru a indica relaţia.
Structura comenzilor constă în cuvinte standard din limba
engleză, cum ar fi CREATE TABLE, INSERT; SELECT.
Limbajul SQL poate fi folosit de o gamă largă de utilizatori,
inclusiv administratorii de baze de date, programatorii de
aplicaţii şi alte tipuri de utilizatori.
SQL este primul şi deocamdată singurul limbaj de baze de date
standardizat care se bucură de o acceptare largă.
Cele mai multe "dialecte" SQL admit următoarele tipuri de date:
SMALLINT: întregi - scurte (4 poziţii, reprezentate pe 16
biţi),
INTEGER sau INT: întregi - lungi (9 poziţii, 32 biţi),
NUMERIC(m,n) sau DECIMAL(m,n) sau DEC(m,n) -
reale, cu un total de m poziţii, din care n la partea
fracţionară,
FLOAT: reale, virgulă mobilă (20 poziţii pentru mantisă),
REAL : real, virgulă mobilă
DOUBLE PRECISION: reale, virgulă mobilă, dublă
precizie (30 poziţii pentru mantisă),
CHAR(n) sau CHARACTER(n): şir de caractere de
lungime n (max. 240),
VARCHAR(n) sau CHAR VARYING(n) sau
CHARACTER VARYING(n): şir de caractere de lungime
variabilă (max. 254),
DATE: dată calendaristică
TIME: ora
TIMESTAMP: an, lună, zi, ora, minutul, secunda, plus o
fracţiune zecimală dintr-o secundă.
Principalele comenzi ale SQL, care se regăsesc, într-o formă
sau alta, în multe dintre SGBDR-urile actuale sunt următoarele:
91
Tabelul nr. 3.1. Clase de comenzi SQL
Comandă Scop
Pentru manipularea datelor
SELECT Extragerea datelor din baza de date
INSERT Adăugarea de noi linii într-o tabelă
DELETE Ştegerea de linii dintr-o tabelă
UPDATE Modificarea valorilor unor atribute
92
3.2. Comenzi pentru descrierea datelor. Limbajul
DDL (Data Description Language)
Comanda SQL utilizată pentru crearea unei tabele este
CREATE TABLE. Aceasta creează o tabelă vidă (fără linii), cu o
anumită structură.
CLIENŢI
C NumeCli Adres Localitate
odClie ent a
nt
1001 TEXTILA SA Bld. Copou, Iaşi
87
1002 MODERN SRL Bld. Gării, 22 Focşani
1003 OCCO SRL NULL Iaşi
1004 FILATURA SA Bld. Unirii, Focşani
145
1005 INTEGRATA I.V.Viteazu, Paşcani
SA 115
1006 AMI SRL Galaţiului, 72 Bacău
1007 AXON SRL Silvestru, 2 Iaşi
1008 ALFA SRL Prosperităţii, Paşcani
15
FACTURIEMISE
Nr C Data Valoa TVA
Factură odClien Factură reTotală Colectată
t
111111 1003 17.06. 2017 1700 271.42
111112 1001 17.06.2017 285 45.5
93
111113 1004 18.06.2007 585 93.4
111114 1003 18.06.2007 2850 455.04
111115 1008 18.06.2007 3570 570
111116 1008 19.06.2007 870 138.9
111117 1006 20.06.2007 1100 175.63
111118 1007 23.06.2007 1500 239.49
111119 1005 24.06.2007 4725 754.41
111120 1003 24.06.2007 300 47.89
111121 1001 24.06.2007 425 67.85
111122 1007 24.06.2007 875 139.7
111123 1006 25.06.2007 660 105.3
111124 1004 25.06.2007 3850 614.7
111125 1003 30.06.2007 1280 204.37
111126 1002 01.07.2007 5425 866.17
Fig. nr. 3.1. Baza de date utilizată în exemple
95
3.3. Comenzi pentru interogarea bazelor de date.
Fraza Select
96
relaţiile specificate în clauza FROM. De asemenea, în tabela-rezultat,
nu este obligatoriu ca atributele să prezinte nume identic cu cel din
tabela enumerată în clauza FROM. Schimbarea numelui se realizează
prin opţiunea AS .
Rezultatul unei fraze SELECT îl vom considera ca fiind sub
forma unei tabele oarecare. Trebuie avute în vedere, însă, că
rezultatul interogării poate fi obţinut şi sub forma unei tabele
temporare sau chiar a unei variabile-tablou (matrice). În unele
SGBD-uri, cum ar fi FoxPro, formatul general al frazei SELECT
conţine şi clauza INTO.
SELECT …
FROM …
INTO destinaţie
WHERE…
În destinaţie poate fi specificată o tabelă "normală", o tabelă
temporară (tabelă care se şterge automat la închiderea sa) sau o
variabilă-tablou. Dacă clauza INTO nu este utilizată, atunci în urma
interogării se obţine o tabelă temporară cu numele predeterminat
(Query).
Uneori, tabela rezultat ("normală" sau temporară) "încalcă"
poruncile modelului relaţional. Conform restricţiei de entitate, într-o
relaţie nu pot exista două linii identice. Or, în SQL, tabela obţinută
dintr-o consultare poate conţine două sau mai multe tupluri identice.
Spre deosebire de algebra relaţională, în SQL nu se elimină
automat tuplurile identice (dublurile) din tabela-rezultat. Pentru
aceasta este necesară utilizarea opţiunii DISTINCT:
SELECT DISTINCT C1, C2, ..., Cn
FROM R1, R2, ..., Rm
WHERE P
În concluzie, o frază SELECT, în forma în care a fost
prezentată, corespunde:
unei selecţii algebrice (clauza WHERE - P)
unei proiecţii (SELECT - Ci)
unui produs cartezian (FROM - R1 R2 ... Rm)
şi conduce la obţinerea unei noi relaţii (tabele-rezultat) cu n
coloane, fiecare coloană fiind:
un atribut din R1, R2, ..., Rm sau
97
o expresie calculată pe baza unor atribute din R1, R2, ...,
Rm.
Exemplu
98
3.3.1 Interogări care utilizează operatorii asamblişti din
algebra relaţională
Reuniunea
SELECT *
FROM R1
UNION
SELECT *
FROM R2
Operatorul pentru reuniune este deci UNION. De remarcat că, la
reuniune, SQL elimină automat dublurile, deci nu este necesară
utilizarea clauzei DISTINCT. Operatorul UNION este prezent în
toate SGBD-urile importante.
Intersecţia
Pentru realizarea intersecţiei a două tabele, R1 şi R2 se
utilizează operatorul INTERSECT:
SELECT *
FROM R1
INTERSECT
SELECT *
FROM R2
Dacă în produsele profesionale, precum DB2 sau Oracle,
operatorul este prezent, în altele, precum Visual FoxPro,
INTERSECT rămâne un deziderat, funcţionalitatea sa realizându-se
prin subconsultări (operatorii IN şi EXISTS) sau, uneori, prin
joncţiune.
Diferenţa
Diferenţa dintre tabelele R1 şi R2 se realizează utilizând
operatorul MINUS sau EXCEPT. Fraza SELECT următoare
funcţionează în Oracle.
SELECT *
99
FROM R1
MINUS
SELECT *
FROM R2
Produsul cartezian
În SQL nu există operator explicit pentru efectuarea produsului
cartezian. Dacă în clauza FROM apar două relaţii, R1 şi R2, atunci,
în lipsa unei condiţii de joncţiune formulată în clauza WHERE,
tabela rezultat va conţine liniile obţinute din produsul cartezian R1
R2.
SELECT *
FROM R1, R2
a. Selecţia
Exemplul 1
Care dintre facturile emise după 23.06.2007 prezintă valoarea
mai mare de 3000 lei ?
SELECT *
FROM FACTURIEMISE
WHERE DataFactură > {23.06.2007} AND
ValoareTotala > 3000
Rezultat:
NrFactu CodCli DataFactur ValoareTot TVAColec
ră ent ă ală tată
111119 1005 24.06.2007 4725 754.41
111124 1004 25.06.2007 3850 614.7
111126 1002 01.07.2007 5425 866.17
100
Operatorul AND a fost utilizat pentru a introduce un "ŞI" logic,
după cum OR se utilizează pentru “SAU” logic. În SQL, pentru
comparare, în afara "clasicilor": >, >=, <, <=, =, (<>), mai pot fi
utilizaţi şi alţi operatori, dintre care în acest paragraf ne vom opri la:
BETWEEN (între, cuprins între),
LIKE (ca şi, la fel ca),
IN (în) şi
IS NULL.
Operatorul BETWEEN
Acest operator permite specificarea unui interval de valori în
care trebuie să se încadreze câmpul sau expresia testată. Intervalul se
referă la valori numerice sau la date calendaristice.
Exemplul 2
Care sunt facturile emise după 23.06.2007 şi care au valoarea
cuprinsă între 3000 şi 4000 lei ?
Fără operatorul BETWEEN fraza SELECT se scrie:
SELECT *
FROM FACTURIEMISE
WHERE DataFactură > {23.06.2007} AND
ValoareTotala >= 3000 AND ValoareTotala <=
4000
Utilizând operatorul BETWEEN se poate scrie:
SELECT *
FROM FACTURIEMISE
WHERE DataFactură > {23.06.2007} AND
ValoareTotala BETWEEN 3000 AND 4000
Operatorul LIKE
Acest operator se foloseşte pentru a compara un atribut de tip şir
de caractere (de exemplu NumeClient, Adresa, Localitate) cu un
literal (constantă de tip şir de caractere). Astfel, dacă se doreşte
obţinerea unei tabele-rezultat care să conţină numai clienţii ai căror
nume începe cu litera M, putem scrie predicatul din clauza WHERE
sub forma: NumeClient LIKE "M%". Deoarece după litera M apare
semnul "%", se vor extrage din tabela CLIENŢI toate tuplurile
pentru care valoarea atributului NumeClient începe cu litera M,
indiferent de lungimea acestuia (ex. MELCRET, MIGAS, MITA,
101
MATSUSHITA etc.). Despre semnul "%" se spune că este un
specificator multiplu, joker sau mască.
Un alt specificator multiplu utilizat în multe versiuni SQL este
liniuţa de subliniere ("_"). Spre deosebire de "%", "_" substituie un
singur caracter. Diferenţa dintre cei doi specificatori multipli este
pusă în evidenţă în exemplele următoare.
Exemplul 3
Care sunt clienţii ai căror nume este format din şapte caractere,
începe cu litera A şi sunt societăţi cu răspundere limitată (SRL-uri) ?
SELECT *
FROM CLIENŢI
WHERE NumeClient LIKE "A__ SRL"
Rezultat:
CodC NumeClient Adresa Localitate
lient
1006 AMI SRL Galaţiului, 72 Bacău
Exemplul 4
Dacă în exemplu 3 s-ar fi utilizat simbolul "%":
SELECT *
FROM CLIENŢI
WHERE NumeClient LIKE "A%SRL",
am fi obţinut:
Rezultat:
CodCli NumeClient Adresa Localitat
ent e
1006 AMI SRL Galaţiului, 72 Bacău
1007 AXON SRL Silvestru, 2 Iaşi
1008 ALFA SRL Prosperităţii, 15 Paşcani
În concluzie, "_" înlocuieşte (substituie) un singur caracter, în
timp ce "%" înlocuieşte un şir de caractere de lungime variabilă
(între 0 şi n caractere). Cei doi specificatori multipli pot fi utilizaţi
împreună.
102
Operatorul IN
Format general:
expresie1 IN (expresie2, expresie3, ...)
Rezultatul evaluării unui predicat ce conţine acest operator va fi
"adevărat" dacă valoarea expresiei1 este egală cu (cel puţin) una din
valorile: expresie2, expresie3, ... Este util atunci când condiţiile de
selecţie sunt mai complexe.
Exemplul 5
Care sunt clienţii din Iaşi şi Bacău ?
Fără utilizarea operatorului IN se scrie:
SELECT *
FROM CLIENTI
WHERE Localitate= "Iaşi" OR Localitate=
"Bacău”
Utilizând operatorul IN:
SELECT *
FROM CLIENTI
WHERE Localitate IN ("Iaşi", "Bacău)
Rezultat
C Nume Adresa Localitate
odClie Client
nt
1001 TEXTILA Bld. Copou, 87 Iaşi
SA
1003 OCCO SRL NULL Iaşi
1006 AMI SRL Galaţiului, 72 Bacău
1007 AXON SRL Silvestru, 2 Iaşi
Operatorul IS NULL
O valoare nulă este o valoare nedefinită. Este posibil ca la
adăugarea unei linii într-o tabelă valorile unor atribute să fie
necunoscute. În aceste cazuri valoarea atributului pentru tuplul
103
respectiv este nulă. Reamintim că, prin definiţie, nu se admit valori
nule pentru grupul atributelor care constituie cheia primară a relaţiei.
Exemplul 6
Dacă se doreşte aflarea clienţilor pentru care nu s-a introdus
adresa, se poate scrie:
SELECT *
FROM CLIENTI
WHERE Adresa IS NULL
Rezultat:
CodCli NumeClient Adresa Localitate
ent
1003 OCCO SRL NULL Iaşi
Observaţii
Valoarea NULL nu se confundă cu valoarea zero (pentru
atributele numerice) sau cu valoarea "spaţiu" (pentru atributele
de tip şir de caractere)
Operatorul NULL se utilizează cu IS şi nu cu semnul "=". Dacă
s-ar utiliza forma expresie = NULL şi nu expresie IS NULL,
rezultatul evaluării va fi întotdeauna fals, chiar dacă expresia nu
este nulă.
Exemplul 1
Care sunt localităţile în care firma are clienţi ?
Este necesară parcurgerea relaţiei CLIENTI, singurul atribut
care interesează fiind Localitate. Deoarece SQL nu elimină dublurile
automat, dacă se doreşte ca în tabela-rezultat o localitate să figureze
o singură dată, se utilizează opţiunea DISTINCT:
SELECT DISTINCT Localitate
104
FROM CLIENTI
Rezultat:
Localitate
Iaşi
Focşani
Bacău
Paşcani
c. Joncţiunea
SQL nu prezintă clauze sau operatori speciali pentru realizarea
theta-joncţiunii, echi-joncţiunii sau joncţiunii naturale. Dar, aşa cum
am văzut, o joncţiune este o combinaţie de produs cartezian şi
selecţie.
Exemplu:
Care sunt facurile emise clienţilor din municipiul Iaşi ?
SELECT NrFactura, NumeClient, Localitate
FROM FACTURIEMISE, CLIENŢI
105
WHERE FACTURIEMISE.CodClient =
CLIENŢI.CodClient
AND Localitate=”Iaşi”
sau
SELECT NrFactura, NumeClient, Localitate
FROM FACTURIEMISE INNER JOIN CLIENŢI
ON WHERE FACTURIEMISE.CodClient =
CLIENŢI.CodClient
WHERE Localitate=”Iaşi”
Rezultat:
NrFactură NumeClient Localitate
111111 OCCO SRL Iaşi
111112 TEXTILA SA Iaşi
111114 OCCO SRL Iaşi
111118 AXON SRL Iaşi
111120 OCCO SRL Iaşi
111121 TEXTILA SA Iaşi
111122 AXON SRL Iaşi
111125 OCCO SRL Iaşi
d. Sub-consultări. Operatorul IN
O altă facilitate deosebit de importantă a limbajului SQL o
constituie posibilitatea includerii (imbricării) a două sau mai multe
fraze SELECT, astfel încât pot fi formulate interogări cu mare grad
de complexitate.
Operatorul IN poate fi utilizat şi pentru includerea unei fraze
SELECT într-o altă frază SELECT.
Exemplul 1
Care sunt facturile emise în aceeaşi zi în care a fost întocmită
factura 111114 ?
SELECT *
FROM FACTURIEMISE
WHERE DataFactură IN
(SELECT DataFactură
106
FROM FACTURIEMISE
WHERE NrFactură=111114)
Observaţie
Sub-consultarea
SELECT DataFactură
FROM FACTURIEMISE
WHERE NrFactură=111114
are ca rezultat o tabelă alcătuită dintr-o singură coloană
(DataFactură) şi o singură linie ce conţine valoarea atributului
DataFactură pentru factura 111114:
DataFactură
18.06.2007
Clauza WHERE DataFactură IN determină căutarea în tabela
FACTURIEMISE a tuturor tuplurilor (liniilor) care au valoarea
atributului DataFactură egală cu una din valorile tuplurilor (în cazul
nostru, egală cu valoarea tuplului) din tabela obţinută prin "sub-
consultare". Cu alte cuvinte, în acest caz WHERE Data IN va
selecta toate facturile pentru care data emiterii este 18.06.2007.
Rezultat:
NrFactură CodClient DataFactură Valoare TVA
Totală Colectată
111113 1004 18.06.2017 585 93.4
111114 1003 18.06.2017 2850 455.04
111115 1008 18.06.2017 3570 570
Exemplul 2
Care sunt facturile emise în alte zile decât cea în care a fost
întocmită factura 111114 ?
SELECT *
FROM FACTURIEMISE
WHERE DataFactură NOT IN
(SELECT DataFactură
FROM FACTURIEMISE
WHERE
NrFactură=111114)
107
S-a utilizat negaţia, testându-se non-apartenenţa la o relaţie
creată printr-o sub-frază SELECT.
Exemplul 3
Care sunt clienţii cărora li s-au trimis facturi întocmite în
aceeaşi zi cu factura 111114 ?
SELECT DISTINCT NumeClient
FROM CLIENŢI
WHERE CodClient IN
(SELECT CodClient
FROM FACTURIEMISE
WHERE DataFactură IN
(SELECT DataFactură
FROM FACTURIEMISE
WHERE
NrFactură=111114))
108
e. Funcţii de agregare (statistice): COUNT, SUM, AVG,
MAX, MIN
Formatul general al unei fraze SELECT ce conţine funcţii
predefinite este:
SELECT funcţia-predefinită1, ... , funcţia-
predefinităN
FROM listă-tabele
WHERE condiţii.
Rezultatul oricărei fraze SELECT este o nouă relaţie (tabelă). În
lipsa opţiunii GROUP BY, dacă în clauza SELECT este prezentă o
funcţie predefinită, tabela rezultat va conţine o singură linie.
Exemplul 1
Câţi clienţi are firma ?
SELECT COUNT (CodClient) AS Nr_Clienti
FROM CLIENTI
Rezultat:
Nr_Clienti
8
Exemplul 2
La câţi clienţi s-au trimis facturi ?
SELECT COUNT(*)
FROM CLIENTI
WHERE CodClient IN
(SELECT CodClient
FROM
FACTURIEMISE)
109
Rezultatul corect poate fi însă obţinut şi prin utilizarea clauzei
DISTINCT astfel:
SELECT COUNT (DISTINCT CodClient)
FROM FACTURIEMISE
Exemplul 3
Care este valoarea totală a facturilor emise ?
SELECT SUM (ValoareTotala) AS Total_FE
FROM FACTURIEMISE
Rezultat:
Total_FE
30000
Exemplul 4
Care este totalul valorii facturilor trimise clientului AXON SRL
?
SELECT SUM (ValoareTotala) AS
Total_FE_AXON
FROM FACTURIEMISE, CLIENTI
WHERE FACTURIEMISE.CodClient =
CLIENTI.CodClient
AND NumeClient = "AXON SRL"
Exemplul 5
Care este cea mai mică valoare a unei facturi emise ?
SELECT MIN(ValoareTotala) AS ValMinima
FROM FACTURIEMISE
Rezultat
ValMinima
285
110
Exemplul 6
Care este factura emisă ce are cea mai mare valoare ?
SELECT NrFactură, ValoareTotala
FROM FACTURIEMISE
WHERE ValoareTotala = (SELECT MAX
(ValoareTotala)
FROM FACTURIEMISE)
Rezultat:
NrFactura ValoareTotala
111126 5425
Exemplu 1
Care este totalul zilnic al valorii facturilor emise ?
SELECT DataFactură, SUM (ValoareTotala)
FROM FACTURIEMISE
111
GROUP BY DataFactură
În acest caz tabela-rezultat va avea un număr de linii egal cu
numărul de date calendaristice distincte din tabela FACTURIEMISE.
Pentru toate facturile aferente unei zile se va calcula suma valorilor,
datorită utilizării funcţiei SUM(ValoareTotala).
Succesiunea paşilor este următoarea:
1. Se ordonează liniile tabelei FACTURIEMISE în funcţie
de valoarea atributului DataFactură:
113
111123 1006 25.06.20 660 105.37
07
111124 1004 25.06.20 3850 614.7
07
111125 1003 30.06.20 1280 204.36
07
111126 1002 01.07.20 5425 866.17
07
Observaţie
Până la standardul SQL99 şi publicarea Amendamentului OLAP
la acest standard, în SQL nu puteau fi calculate, prin GROUP BY,
114
subtotaluri pe mai multe niveluri, pentru aceasta fiind necesară
scrierea de programe în SGBD-ul respectiv.
Exemplul 3
Pentru facturile emise interesează valoarea zilnică a acestora
(în funcţie de data la care au fost întocmite, dar numai dacă aceasta
(valoarea zilnică) este de mai mare de cinci mii lei.
SELECT DataFactură, SUM(ValoareTotala)
FROM FACTURIEMISE
GROUP BY DataFactură
HAVING SUM(ValoareTotala) > 5000
La execuţia acestei fraze, se parcurg cei trei paşi prezentaţi
la exemplul 1, apoi, din cele nouă tupluri obţinute prin grupare,
sunt extrase numai cele care îndeplinesc condiţia
SUM(ValoareTotala) > 5000.
Rezultat:
Data SUM(ValoareTotala)
18.06.2007 7005
24.06.2007 6325
01.07.2007 5425
Exemplul 4
Să se afişeze ziua în care s-au întocmit cele mai multe facturi.
SELECT DataFactură
115
FROM FACTURIEMISE
GROUP BY DataFactură
HAVING COUNT(*) >= ALL
(SELECT COUNT(*)
FROM FACTURIEMISE
GROUP BY DataFactură)
Exemplul 5
Care sunt clienţii pentru care s-au întocmit numai două
facturi?
SELECT NumeClient
FROM CLIENTI INNER JOIN FACTURIEMISE
ON
CLIENTI.CODCLIENT=FACTURIEMISE.CODCLIENT
GROUP BY NumeClient
HAVING COUNT(NrFactura)=2
sau
SELECT NumeClient
FROM CLIENTI
WHERE CodClient IN
(SELECT CodClient
FROM FACTURIEMISE
GROUP BY CodClient
HAVING COUNT(NrFactura)=2)
Exemplu 6
Care sunt zilele în care s-au întocmit cel puţin trei facturi?
SELECT DataFact , Count(*) as Nr
FROM FacturiEmise
GROUP BY DataFact
HAVING COUNT(*)>=3
116
5.4. Comenzi pentru actualizarea bazelor de date
117
3.4. Comenzi pentru manipularea datelor. Limbajul
DML (Data Manipulation Language)
118
În noua linie a tabelei CLIENŢI valoarea atributului Adresa va
fi NULL.
Se putea folosi şi forma:
INSERT
INTO CLIENŢI
VALUES (1009, "RODEX SRL", " ", "Iaşi")
În urma execuţiei acestei comenzi, valoarea atributului Adresa
va fi " " (un spaţiu), deci diferită de NULL.
119
Standardul SQL92 permite la crearea unei tabele descrierea
acţiunii care se va derula la ştergerea unei linii părinte în cazul în
care există linii copil. Spre exemplu, se poate refuza ştergerea de linii
din tabela CLIENŢI, dacă la crearea tabelei FACTURIEMISE se
specifică:
Exemplul 4
Noua adresă a clientului Modern SRL este “Bulevardul
Victoriei nr. 21”. Să se opereze modificarea în baza de date.
Se actualizează atributul Adresa din tabela Clienţi.
UPDATE CLIENŢI
120
SET Adresa=“Bulevardul Victoriei nr. 21”
WHERE NumeClient=”Modern SRL”
121
Cand navigati prin menu-ul SQL veti descoperi urmatoarele
instrumente (submenuri):
SQL Commands: cu ajutorul caruia puteti introduce
comenzi cum sunt cele de tipul SELECT
SQL Scripts: cu ajutorul caruia puteti sa executati scripturi
(fisiere) care contin comenzi SQL
Query Builder: poseda un instrument cu ajutorul caruia
puteti sa construiti interogari
3 La folosirea instrumentului SQL Commands
trebuie sa scriem comenzile SQL
4 La folosirea instrumentului Query Builder vom
construi interogari intr-o interfata grafica
Exemplu : creare de interogari care sa afiseza
informatii din tabelele Departamente si Employees.
5 In SQL Commands vom tipari urmatorul script
pentru a afisa informatiile din tabelul Departamente,
apoi veti apasa pe butonul de Run pentru a executa
scriptul; vem putea seta si numarul de inregistrari
afisate in pagina.
SELECT * FROM Departamente;
6 In SQL > Query Builder urmati pasii:
Dati click pe Create
Selectam tabelul pe care doriti sa-l afisam
(in cazul nostru Employees)
Selectam coloanele pe care dorim sa le
afisam
Coloanele selectate sunt afisate in josul
paginii
De asemenea veti putea vizualiza scriptul
SQL generat facand click pe optiunea SQL
122
Pentru a vedea rezultatul interogarii faceti
click pe optiunea Results sau pe butonul
Run
123
CapitoluI IV. LIMBAJUL
PL/SQL
4.1. Introducere
Limbajul SQL (Structured Query Language) este un limbaj
declarativ orientat pe obţinerea de mulţimi de selecţie într-o aplicaţie
în arhitectura client-server. Eficienţa sa este remarcabilă, dar în cazul
în care elementele unei mulţimi de selecţie trebuie accesate pe rând,
nu în grup, utilizarea sa nu mai este posibilă. Pe de alta parte, SQL
nu oferă nici suportul necesar realizării interfeţei unei aplicaţii. În
contrast cu SQL, limbajele procedurale pot manipula linii individuale
dintr-o mulţime de selecţie. Ele dispun de funcţii care permit trecerea
de la o linie la alta şi ramificarea codului în functie de rezultatul
testării valorilor preluate din tabelele bazei de date.
124
pot fi realizate de regulă şi în cadrul aplicaţiilor client care accesează
datele din baza, dar în cazul modificării unei metode de calcul
trebuie refăcute aplicaţiile client afectate şi suportate toate costurile
pe care le implică redistribuirea unor noi versiuni ale aplicaţiilor
client.
Având în vedere faptul că de multe ori aplicaţiile din
domeniul bazelor de date sunt în arhitectura client-server şi aplicaţia
client accesează aplicaţia server prin intermediul unei reţele,
utilizarea pe cât posibil a procedurilor scrise în PL/SQL poate
ameliora semnificativ viteza de prelucrare. În cazul unei proceduri
care ar implica transferul spre aplicaţia client a unui volum mare de
date (rezultatul unei interogări de exemplu), întârzierile cauzate de
reţeaua prin care se accesează serverul de baze de date pot fi mari.
Dacă prelucrarea datelor nu presupune afişarea acestora în aplicaţia
client, mult mai eficientă este soluţia prelucrării datelor pe server,
într-o procedură scrisă în PL/SQL.
PL/SQL este bazat pe limbajul ADA, o parte dintre
construcţiile sale sintactice provenind din Pascal.
Avantaje ale PL/SQL:
stuctura de bloc (programele pot fi împărţite în
blocuri logice, fiecare conţinând resursele
necesare în acel bloc. Variabilele pot fi declarate
local în cadrul unui bloc în care vor fi folosite,
iar tratarea erorilor (sau Exceptiile) se poate face
în blocul în care apar);
controlul execuţiei (deciziile, buclele şi salturile
pot fi folosite pentru a controla execuţia
programelor, decizând dacă şi când SQL şi alte
acţiuni să fie executate);
portabilitatea (deoarece PL/SQL derivă din
ORACLE, programele pot fi puse pe toate
maşinile care suportă ORACLE şi PL/SQL);
performanţele (utilizarea PL/SQL poate ajuta la
îmbunătăţirea performanţelor aplicaţiilor).
125
PL/SQL ofera constructii procedurale cum ar fi variabile, constante
si tipuri. Limbajul ofera constructii selective si iterative
constructiilor SQL.
DECLARE
/* Sectiunea de declarare: variabile, tipuri de date,
subprograme locale */
BEGIN
/* Secţiunea executabilă: declaraţii SQL sau
proceduri*/
/* Este singura secţiune din bloc care trebuie să
apară */
EXCEPTION
/* Secţiunea de lucru cu excepţiile: declaraţii de lucru
cu erorile */
END;
126
Sectiune Descriere
127
Tipuri de blocuri
Anonime Procedură Funcţie
FUNCTION nume
[DECLARE] PROCEDURE nume RETURN tip data
IS IS
BEGIN
BEGIN BEGIN --instr.
--instr. --instr. RETURN
valoare;
[EXCEPTION] [EXCEPTION] [EXCEPTION]
a . Operatori simpli
+ operatorul de adunare
- operatorul de scadere/negare
* operatorul de multiplecare
/ operatorul de impartire
= operator relational
> operator relational
< operator relational
128
b. Operatori multicaracter
** exponential
<> relational
!= diferit
<= , >= mai mic sau egal, mai mare sau egal
:= asignare
=> asociere (la pointeri)
.. rang
|| concatenare
129
BINARY_INTEGER, se foloseste tipul de data INTEGER sau
NUMBER.
DECLARE
No_art NUMBER(6);
Nume_art VARCHAR2(20);
in_stoc BOOLEAN;
pret_art NUMBER(6,2);
desc_art VARCHAR2(30);
DECLARE
Salariu_sapt NUMBER;
Ore_lucr NUMBER := 40;
Salariu_ NUMBER := 22.50;
bonus NUMBER := 150;
130
Tara country VARCHAR2(128);
Suma NUMBER := 0;
dat done BOOLEAN;
id_validare BOOLEAN;
sal_rec1 salariati%ROWTYPE;
sal_rec2 salariati %ROWTYPE;
BEGIN
Salariu_sapt:= (Ore_lucr * Salariu_ora) + bonus;
Tara:= 'Canada';
Canada' := UPPER('Canada');
done := (suma > 100);
id_validare := TRUE;
sal_rec1. nume := 'Lupu';
sal_rec1. prenume := 'Dan';
sal_rec1 := sal _rec2;
END;
131
4.2.4. Declararea Constantelor
Exemplu:
DECLARE
V1 NUMBER(5) := 16;
V2 NUMBER(5);
V3 NUMBER(5);
BEGIN
V3:= sqrt(V1+ &V2); -- valoarea variabilei V2 este citita de la
tastatura
DBMS_OUTPUT.PUT_LINE('V3= ' || TO_CHAR(V3);
END;
132
O alternativă simplă de citire a unei variabile de la tastatură este
V1:= &V1;
b. Atributul %ROWTYPE
DECLARE
dept_rec dept%ROWTYPE; -- declararea variabilei inregistrare
133
Se foloseste notatia cu punct pentru a referi un camp din
inregistrare, ca in exemplu urmator:
v_deptid := dept_rec.department_id;
134
4.3. Instrucţiuni în PL/SQL
Variabila:= Expresie;
A nu se confunda atribuirea prin asignare ci operatorii logici
sau aritmetici.
OPERATORII
Operator Descriere
+-/* aritmetici
= egalitate
!= or <> inegalitate
|| concatenare string
:= asignare
135
variabilele, pentru fiecare atribut din SELECT câte o variabilă
asociată. Instrucţiunea dă eroare dacă există mai multe valori
selectate pentru un atribut, de unde clauza WHERE devine
obligatorie
136
SELECT * FROM T1;
Alt exemplu:
DECLARE
v_nr1 NUMBER;
v_nr2 NUMBER;
BEGIN
/* daca primul numar este mai mare ca 1, se inverseaza
insereaza o
inregistrare noua in care numerele sunt inversate*/
SELECT nr1,nr2 INTO v_nr1,v_nr2 FROM T2 WHERE
nr1>1;
INSERT INTO T2 VALUES (v_nr2,v_nr1);
END;
137
4.3.2 Structuri de control
a. Instrucţiunea IF
138
IF v_salar=700 THEN
DELETE FROM T1 WHERE SALAR=700;
INSERT INTO T1
VALUES(v_nume,v_salar+100);
END IF;
END;
Alt exemplu:
BEGIN
/* Celor care au salarul=700, li se va mari salarul cu
100 lei */
SELECT nume,salar INTO v_nume,v_salar FROM
T1 WHERE salar=700;
IF v_salar=700 THEN
DELETE FROM T1 WHERE SALAR=700;
INSERT INTO T1
VALUES(v_nume,v_salar+100);
END IF;
END;
139
.
run;
b. Instructiunea IF-THEN-ELSIF
Instrucţiunea combină două sau mai multe IF-uri pe remura ELSE.
Ca structura schematică avem
IF-THEN-ELSIF :
Schema generală
IF Condition
TRUE FALSE
ELSIF
Condition
THEN Actions
TRUE FALSE
ELSE
THEN Actions
Actions
Exemplu
IF v_start > 100 THEN
RETURN (2 * v_start);
ELSIF v_start >= 50 THEN
140
RETURN (.5 * v_start);
ELSE
RETURN (.1 * v_start);
END IF;
...
c. Instructiunea CASE
Exemplu:
141
DECLARE
grade CHAR(1);
BEGIN
grade := 'B';
CASE
WHEN grade = 'A' THEN
DBMS_OUTPUT.PUT_LINE('Excellent');
WHEN grade = 'B' THEN DBMS_OUTPUT.PUT_LINE('Very
Good');
WHEN grade = 'C' THEN DBMS_OUTPUT.PUT_LINE('Good');
WHEN grade = 'D' THEN DBMS_OUTPUT.PUT_LINE('Fair');
WHEN grade = 'F' THEN DBMS_OUTPUT.PUT_LINE('Poor');
ELSE DBMS_OUTPUT.PUT_LINE('No such grade');
END CASE;
END;
-- in loc de folosi ELSE in CASE se poate folosi
-- EXCEPTION
-- WHEN CASE_NOT_FOUND THEN
-- DBMS_OUTPUT.PUT_LINE('No such grade');
142
4.3.3 Structuri de ciclare
a. LOOP
LOOP
WHILE-LOOP
FOR-LOOP
Exemplu
LOOP
instr1;
instr2; …
END LOOP;
Pentru a ieşi dintr+o buclp de ciclare, PL/SQL propune două
alternative: comanda EXIT, sau condiţia de ieşire EXIT WHEN.
Exemplu
DECLARE
credit_rating NUMBER := 0;
BEGIN
LOOP
credit_rating := credit_rating + 1;
IF credit_rating > 3 THEN
EXIT; -- iesirea din blucla
143
END IF;
END LOOP;
-- DBMS_OUTPUT.PUT_LINE ('Credit rating: ' ||
TO_CHAR(credit_rating));
IF credit_rating > 3 THEN
RETURN; --se foloseste RETURN si nu EXIT cand suntem in
afara LOOP
END IF;
DBMS_OUTPUT.PUT_LINE ('Credit rating: ' ||
TO_CHAR(credit_rating));
END;
c. Comanda EXIT-WHEN
Exemplu
IF count > 100 THEN EXIT; ENDIF;
sau
EXIT WHEN count > 100;
144
d. Etichetarea unei blucle PL/SQL
Exemplu
DECLARE
s PLS_INTEGER := 0;
i PLS_INTEGER := 0;
j PLS_INTEGER;
BEGIN
<<outer_loop>>
LOOP
i := i + 1;
j := 0;
<<inner_loop>>
LOOP
j := j + 1;
s := s + i * j;
EXIT inner_loop WHEN (j > 5);
EXIT outer_loop WHEN ((i * j) > 15);
END LOOP inner_loop;
END LOOP outer_loop;
DBMS_OUTPUT.PUT_LINE ('The sum of products equals: ' ||
TO_CHAR(s));
END;
e. Bucla WHILE-LOOP
LOOP
sequence_of_statements
EXIT WHEN boolean_expression;
END LOOP;
Exemplu:
DECLARE
p NUMBER := 0;
BEGIN
FOR k IN 1..500 LOOP – calcularea lui pi cu 500 termeni
p := p + ( ( (-1) ** (k + 1) ) / ((2 * k) - 1) );
END LOOP;
p := 4 * p;
DBMS_OUTPUT.PUT_LINE( 'pi is approximately : ' || p ); -- print
result
END;
Exemplu:
BEGIN
FOR i IN REVERSE 1..3 LOOP
146
DBMS_OUTPUT.PUT_LINE (TO_CHAR(i));
END LOOP;
END;
BEGIN
FOR i IN 1..3 LOOP -- assign the values 1,2,3 to i
IF i < 3 THEN
DBMS_OUTPUT.PUT_LINE (TO_CHAR(i));
ELSE
i := 2; -- nu este permisă, produce o eroare
END IF;
END LOOP;
END;
147
4.3.4 Folosirea excepţiilor
Tipuri de excepţii
Sunt trei tipuri de excepţii:
1. Excepţii pre-definite asociate erorilor care apar cel
mai frecvent în blocurile PL/SQL (de exemplu
NO_DATA_ FOUND, TOO_MANY_ROWS,
148
INVALID_CURSOR, ZERO_DIVIDE). Aceste
excepţii nu trebuie declarate, serverul Oracle le invocă
în mod automat, dar trebuie tratate în secţiune
EXCEPTION
2. Excepţii non-predefine recunoscute de Oracle dar
tratate de utilizator cu ajutorul codului de eroare
returnat (de exemplu ORA- 01400). Trebuie declarate
în secţiunea declarativă. Serverul Oracle le invocă în
mod automat, dar trebuie tratate în secţiune
EXCEPTION
3. Excepţii definite de utilizator, asociate unor condiţii
specifice de prelucrare (de exemplu cazul în care
valoarea stocului unui anumit produs este zero).
Trebuie declarate în secţiunea declarativă, invocate de
către utilizator şi tratate în secţiunea EXCEPTION
EXCEPTION
WHEN exception1 [OR exception2 …]
THEN
statement1 ;
statement2 ;
…
[WHEN exception3 [OR exception4 …]
THEN
statement1 ;
statement2 ;
149
…]
[WHEN OTHERS THEN
statement1 ;
statement2 ;
…]
150
Exemple:
DECLARE
v_nume VARCHAR2(20);
BEGIN
SELECT nume INTO v_nume
FROM angajati
WHERE id_angajat=10;
dbms_output.put_line(v_nume);
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Nu exista angajatul cu acest ID!');
END;
/
Să se afişeze salariul angajatului cu prenumele John. Să se trateze
eroare apărută în cazul în care există mai mulţi angajaţi cu acelaşi
nume (interogarea SQL din bloc întoarce mai multe înregistrări).
SET SERVEROUTPUT ON
DECLARE
sal angajati.salariul%type;
BEGIN
select salariul into sal from angajati where prenume='John';
DBMS_OUTPUT.PUT_LINE('John are salariul de: '||sal);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Exista mai multi salariati cu
numele John! Utilizati un cursor pentru selectie!');
END;
/
151
b. Tratarea excepţiilor non-predefinite Oracle Server
PRAGMA EXCEPTION_INIT(NUME_EXCEPTIE,
COD_EROARE);
unde COD_EROARE este un cod de eroare standard Oracle;
152
Exemplu:
SET SERVEROUTPUT ON
DECLARE
-- se asociază un nume codului de eroare apărut
INSERT_EXCEPT EXCEPTION;
PRAGMA EXCEPTION_INIT(INSERT_EXCEPT, -01400);
BEGIN
insert into departments (department_id, department_name) values
(200, NULL);
EXCEPTION
--se tratează eroarea prin numele său
WHEN insert_except THEN
DBMS_OUTPUT.PUT_LINE('Nu ati precizat informatii suficiente
pentru departament');
--se afişează mesajul erorii
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/
Etape:
1. Se declara excepţia în secţiunea declarativă:
nume_exceptie EXCEPTION;
153
2. Prin instrucţiunea RAISE se invocă în mod explicit, în cadrul
secţiunii executabile: RAISE nume_exceptie;
3. Se tratează în rutina corespunzătoare din secţiunea de tratare
a excepţiilor:
WHEN nume_exceptie THEN......
Exemplu:
Să se invoce o eroare în cazul în care utilizatorul încearcă să
execute blocul PL/SQL după ora 17.
DECLARE
e_exc1 EXCEPTION;
BEGIN
IF TO_NUMBER(TO_CHAR(SYSDATE,
'HH24'))>=17 THEN
RAISE e_exc1;
END IF;
EXCEPTION
WHEN e_exc1 THEN
dbms_output.put_line('Este ora
'||TO_CHAR(SYSDATE, 'HH24'));
dbms_output.put_line('Operatiune permisa
doar '||' in timpul programului');
END;
/
154
Capitolul V. POCEDURI ŞI
FUNCŢII ÎN PL/SQL
Un subprogram PL/SQL este un bloc ne-anonim PL/SQL care
se apeleaza folosind un set de parametrii. PL/SQL are doua tipuri de
subprograme clasice: Proceduri stocate si Funcţii, precum şi două
tipuri de subprograme specifice: Declanşatoarele (triggers) şi
Cursoarele
155
Parametrii sunt folositi pentru a transfera valorilor datelor
intre apel si procedura. Parametrii sunt cunoscuti ca argumete.
Parametrii pot avea unul din cele 3 moduri: IN, OUT si IN OUT.
parametrul IN transmite o valoare constanta
procedurii (parametrul de intrare)
parametrul OUT transmite o valoare de la
procedura unei variabile (parametru de iesire)
parametrul IN OUT transmite o valoare
procedurii si o valoare posibil diferita de la
procedura la o variabila, folosind acelasi
parametru
Exemplu:
CREATE OR REPLACE PROCEDURE mareste_salariu1
(p_id IN emp.empno%Type,
p_percent IN NUMBER)
IS
BEGIN
UPDATE empSET sal= sal*(1+p_percent/100)
Where empno= p_id;
END mareste_salariu1;
--blocul in care se executa procedura :
BEGIN
mareste_salariu1 (176,10);
END
156
O funcţie este un bloc PL/SQL cu nume care acceptă
parametric de intrare, poate fi apelată şi returnează întotdeauna o
valoare.
In general, se foloseste o functie pentru a calcula o valoare
numerică. Functia se creeaza folosind comanda CREATE
FUNCTION care declara o lista de parametrii si defineste actiunile
care trebuie efectuate de blocul PL/SQL standard.
Sintaxa declaraţiei de funcţii:
157
DECLARE
nr number(4):=10;
FUNCTION half_of_square(original NUMBER) RETURN
NUMBER IS
BEGIN
RETURN mod((2*original + original/2),original);
END half_of_square;
BEGIN
DBMS_OUTPUT.PUT_LINE('functia a returnat valoarea:
'||to_char(half_of_square(nr)));
END;
158
5.2. Pachete de proceduri în PL/SQL
Pachetele PL/SQL permit gruparea tipurilor PL/SQL,
variabilelor , structurilor de date, exceptiilor si subprogramelor intr-
un singur container.
Pachetul se crează în 2 părti:
– · Specificarea pachetului este interfaţa pentru
aplicatie. Aici se declară tipurile publice, variabile,
constante, exceptii, cursoare si subprograme.
– · Corpul pachetului defineste propriul subprogram.
Corpul pachetului poate defini de asemenea obiecte
PL/SQL, cum ar fi variabile, constante, exceptii şi
cursoare.
Corpul pachetului trebuie sa completeze implementarea pentru
toate procedurile si functiile declarate in definita pachetului. Forma
sintactica a celor două componente:
-Pentru interfaţa packetului
159
instrucţiuni de iniţializare si descrierea explicită a
procedurilor şi funcţiilor incluse in pachet
....
END [package_name];
şi corpul acestuia
CREATE OR REPLACE PACKAGE BODY emp_admin AS
PROCEDURE fire_employee (emp_id NUMBER) IS
BEGIN
DELETE FROM employees WHERE employee_id = emp_id;
END fire_employee;
PROCEDURE fire_employee (emp_email VARCHAR2) IS
BEGIN
DELETE FROM employees WHERE email = emp_email;
END fire_employee;
END emp_admin;
160
Fig. 5.1 Componentele unui pachet de proceduri şi funcţii
161
5.3. Triggere în PL/SQL
162
ROW-LEVEL trigger: Un declanşator executat de fiecare data
pentru fiecare înregistrare din baza de date afectată de un eveniment.
Să presupinem că o tabelă de cărţi conţine 1000 de înregistrări.
Atunci comanda următoare UPDATE va modifica 1,000 de rânduri:
UPDATE books SET title = UPPER (title);
Un declanţator row-level (ce conţine clauza FOR EACH ROW) va fi
executat de 1000 de ori.
NEW pseudo-record: O structură de date NEW care arată ca o
înregistrare PL/SQL. Acestă pseudo-înregistrare este activă doar
pentru declanşatoare DML after UPDATE sau INSERT şi conţine
valorile datelor noi care au fost introduce în tabele.
OLD pseudo-record: O structură de date OLD care arată ca o
înregistrare PL/SQL, activă doar pentru declanşatoare DML before
UPDATE sau DELETE şi conţine valorile datelor noi care au fost
introduce în tabele..
Clauza WHEN : determină în ce condiţii se execută declanşatorul.
to_table from_table
EXEMPLUL 1. COL1 COL1
Declanşatoare STATEMENT-LEVEL şi 1
ROW-LEVEL: 2
-- se consider 2 tabele identice, una cu 3
date, una fără 4
CREATE TABLE from_table(col1 NUMBER); 5
- 6
- 7
c 8
r 9
e
10
a
Fig 5.2 Două tabele
-coloană identice
CREATE TABLE to_table (col1 NUMBER);
163
BEGIN - - populare prin generare
FOR counter IN 1..10 LOOP
INSERT INTO from_table VALUES(counter);
END LOOP;
END;
164
>
10 rows inserted. to_table from_table
165
• Datele din structura OLD nu se pot modifica, cele din structura
NEW se pot modifica;
• Înregistrările NEW sau OLD nu pot fi folosite ca parametrii la o
funcţie sau procedură, chiar dacă este declarată inăuntru
declanşatorului.
• Datele din structurile NEW şi OLD se referenţiază ca şi RECORD
extern, folosind simbolul “:”, cum ar fi:
IF :NEW.salary > 10000 THEN...
• Clauza FOR EACH ROW este obligatorie
166
FOR EACH ROW
BEGIN
:new.value_incremented := :new.value_incremented + 1;
DBMS_OUTPUT.PUT_LINE(' TRIGGER update1');
END;
After running the script, execute these commands and view the
results:
SET SERVEROUTPUT ON;
INSERT INTO incremented_values VALUES(1,1);
1 rows inserted.
TRIGGER increment_by_one
INSERT INTO incremented_values VALUES(2,2);
1 rows inserted.
TRIGGER increment_by_two
TRIGGER increment_by_one
value_inserted value_incremented
10 11
10 11
167
BEGIN
:new.value_incremented := :old.value_incremented + 5;
DBMS_OUTPUT.PUT_LINE(' TRIGGER update2');
END;
168
value_incremented = :new.value_incremented;
--sterge inregistrarea
DBMS_OUTPUT.PUT_LINE(' Eroare de introducere');
END IF;
END;
169
5.4. Cursoare în PL/SQL
Serverul Oracle utilizează o zonă de memorie de lucru (numită
zonă privată SQL) pentru a executa instrucţiunile SQL şi pentru a
stoca informaţiile procesate. Se poate utiliza un cursor explicit pentru
a eticheta zona privată de memorie şi a avea acces la informaţiile
stocate.
Cursoarele pot fi:
• Implicite – declarate de către PL/SQL pentru toate
instrucţiunile DML.
• Explicite – declarate de către programator pentru interogările
care returnează mai mult de o înregistrare. Pot fi gestionate prin
câteva unelte specifice. În acest fel fiecare înregistrare poate fi
prelucrată individual.
%FOUND
170
TRUE daca o comanda de tipul INSERT, UPDATE sau
DELETE afecteaza una sau mai mult inregistrari din baza de
date sau SELECT INTO returneaza una sau multe
inregistrari.
%ISOPEN
171
%NOTFOUND
%ROWCOUNT
172
DECLARE
mgr_no NUMBER(4) := 7698;
BEGIN
DELETE FROM emp_temp WHERE mgr = mgr_no;
DBMS_OUTPUT.PUT_LINE('Number of employees deleted: ' ||
TO_CHAR(SQL%ROWCOUNT));
END;
173
5.4.2. Cursoare explicite
No
Yes
DECLARE OPEN FETCH EMPTY? CLOSE
174
În figura 5.4 sunt prezentate etapele de lucru cu un cursor
explicit.
Declararea unui cursor. La declarare, cursorul primeste un
nume si este asociat cu o interogare. Optional se poate
declara tipul pe care il returneaza cursorul, de exemplu
table_name%ROWTYPE.
Exemplu: Declararea unui cursor
DECLARE
my_emp NUMBER(4); -- variabila pentru campul empno
my_job VARCHAR2(9); -- variabila pentru campul job
my_sal NUMBER(7,2); -- variabila pentru campul sal
CURSOR c1 IS SELECT empno, job, sal FROM emp
WHERE sal> 2000;
my_dept dept%ROWTYPE; --
variabila pentru inregistrarea dn tabelul dept
CURSOR c2 RETURN dept%ROWTYPE IS SELECT *
FROM dept WHERE deptno = 10;
DECLARE
CURSOR c1 (low NUMBER DEFAULT 10, high
NUMBER DEFAULT 30) IS
SELECT * FROM dept WHERE
deptno>low AND deptno<high;
175
Observaţie: Instrucţiunea OPEN execută interogarea
asociată cursorului, identifică setul activ şi poziţionează cursorul
pe primul rând. Instrucţiunea FETCH returnează rândul curent şi
poziţionează cursorul pe rândul următor. Ea se poate repeta până
când nu mai sunt rânduri sau o condiţie specificată este atinsă.
Instrucţiunea CLOSE eliberează cursorul şi resursele cerute
de acesta.
Deschiderea cursorului
Cand se deschide un cursor, se executa interogarea care
returneaza multimea de inregistrari care indeplinesc conditiile de
cautare.
DECLARE
CURSOR c1 IS SELECT employee_id, last_name, job_id,
salary FROM employees
WHERE salary > 2000;
BEGIN
OPEN C1;
...
Deschiderea unui cursor presupune următoarele operaţii:
1. Alocă memorie de dimensiune potrivită.
2. Analizează şi descompune instrucţiunea SELECT.
3. Face legătura între variabilele de memorie şi înregistrare.
4. Identifică setul activ (înregistrările returnate de SELECT)
5. Poziţionează pointerul pe primul rând din setul activ.
176
Citirea cursorului
Pentru prelucrarea datelor din cursor se poate folosi comanda
FETCH pentru a citi câte o înregistrare la un moment dat, în
interiorul unei bucle LOOP, cu condiţia de ieşire
EXIT WHEN nume_cursor%NOTFOUND;
Formatul instrucţiunii FETCH este
FETCH nume_cursor INTO lista_variabile;
în care lista variabile trebuie să acopere lista câmpurilor din
SELECT-ul care defineşte cursorul.
Exemplu:
DECLARE
v_job emp.job%TYPE; -- variabila pentru job
v_ename emp.ename%TYPE; -- variabila pentru ename
CURSOR c1 IS SELECT ename, job FROM emp
WHERE job='CLERK';
177
FETCH c2 INTO v_emp; -- citirea intregii inregistrari in variabila
inregistrare v_emp
EXIT WHEN c2%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(RPAD(v_emp.ename, 25, '
')||v_emp.job);
END LOOP;
CLOSE c2;
END;
La execuţie se afişează:
SMITH CLERK
ADAMS CLERK
JAMES CLERK
MILLER CLERK
-------------------------------------
BLAKE MANAGER
CLARK MANAGER
JONES MANAGER
Exemplu:
DECLARE
my_sal emp.sal%TYPE;
my_ename emp.ename%TYPE;
factor INTEGER := 2;
CURSOR c1 IS
SELECT factor*sal,ename FROM emp WHERE job = 'CLERK';
BEGIN
DBMS_OUTPUT.PUT_LINE(RPAD('NUME',10,'-
')||RPAD('SALARIU MARIT', 28, '-')||'factor');
OPEN c1; -- initial factor este 2
178
LOOP
FETCH c1 INTO my_sal, my_ename;
EXIT WHEN c1%NOTFOUND;
factor := factor + 1; -- nu afecteaza cu nimic
DBMS_OUTPUT.PUT_LINE(RPAD(my_ename,15,'
')||RPAD(my_sal, 25, ' ')||factor);
END LOOP;
CLOSE c1;
END;
La execuţie apare:
anonymous block completed
NUME------SALARIU MARIT---------------factor
SMITH 1600 3
ADAMS 2200 4
JAMES 1900 5
MILLER 2600 6
Inchiderea Cursorului
Comanda CLOSE închide cursorul făcându-l nedisponibil. O data
închis, cursorul mai poate fi redeschis şi altă dată.
179
my_ename emp.ename%TYPE;
my_sal emp.sal%TYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO my_ename, my_sal;
IF c1%FOUND THEN -- citire cu succes
DBMS_OUTPUT.PUT_LINE('Name = ' || my_ename || ', salary
= ' || my_sal);
ELSE -- iesire din bucla
EXIT;
END IF;
END LOOP;
END;
La execuţie;
anonymous block completed
Name = KING, salary = 5000
Name = BLAKE, salary = 2850
Name = CLARK, salary = 2450
Name = JONES, salary = 2975
Name = SCOTT, salary = 3000
Name = FORD, salary = 3000
Name = SMITH, salary = 800
Name = ALLEN, salary = 1600
Name = WARD, salary = 1250
Name = MARTIN, salary = 1250
180
Exemplu pentru %ROWCOUNT:
DECLARE
CURSOR c1 IS SELECT ename FROM emp WHERE ROWNUM
< 11;
name emp.ename%TYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO name;
EXIT WHEN c1%NOTFOUND OR c1%NOTFOUND IS
NULL;
DBMS_OUTPUT.PUT_LINE(c1%ROWCOUNT || '. ' || name);
IF c1%ROWCOUNT = 5 THEN
DBMS_OUTPUT.PUT_LINE('--- Fetched 5th record ---');
END IF;
END LOOP;
CLOSE c1;
END;
anonymous block completed
1. KING
2. BLAKE
3. CLARK
4. JONES
5. SCOTT
--- Fetched 5th record ---
6. FORD
7. SMITH
8. ALLEN
9. WARD
10. MARTIN
181
Forma generală:
Exemplu 1:
(item_record.price *
item_record.quantity);
i := i + 1;
prodid_table (i) := item_record.prodid;
ordertotal_table (i) := v_ordertotal;
END LOOP; -- implicit close
182
Exemplu 2
DECLARE
my_dept departments.department_id%TYPE:=10;
BEGIN
my_dept:=20;
FOR emp_record IN (SELECT * FROM employees
WHERE department_id=my_dept) LOOP
DBMS_OUTPUT.PUT_LINE(emp_record.employee_id||
' '||emp_record.first_name||' '||emp_record.last_name||
' '||emp_record.salary);
END LOOP;
END;
Exemplu:
SET SERVEROUTPUT ON
183
DECLARE
CURSOR emp_cursor (deptno NUMBER) IS
SELECT employee_id, last_name
FROM employees
WHERE department_id = deptno;
dept_id NUMBER;
lname VARCHAR2(15);
BEGIN
OPEN emp_cursor (10);
...
CLOSE emp_cursor;
...
OPEN emp_cursor (300);
...
CLOSE emp_cursor;
...
END;
184
Capitolul VI. PROIECTAREA
FIZICĂ A BAZELOR DE
DATE RELAŢIONALE
185
Utilizatorul trebuie să poată cere liniile din PROFESOR cu o
valoare oarecare a lui NUME_PROFESOR , sau a lui MARCA# sau
a oricărui atribut si nu trebuie să fie restricţionat în aceasta la
atributele ce identifică unic cheia.
Suportă operatorii relaţionali . Structura de date fizică trebuie
să fie capabilă a suporta operaţiile din SELECT, PROJECT şi JOIN,
fără a cere utilizatorului poziţionări în structura de date prin pointeri
si adrese. Managerul bazei de date trebuie să fie in stare sa
regăsească o submulţime a liniilor tabelei care satisfac criteriul de
calificare bazat pe valori de atribute, să regasescă o submultime
specifică de coloane ale tabelei, precum si să combine tabele
potrivind valorile atributelor de legatura.
Operatorii relaţionali de bază trebuie să fie suportaţi fără ca
utilizatorul să trebuiască să specifice căi de acces prin structura de
date fizică si utilizatorul nu trebuie să ştie care inregistrări pointează
la care sau cum se obţine un tuplu din altul.
SGBD-urile relaţionale oferă diferite limbaje pentru a
manipula tabele. Oparatorii specifici SELECT, PROJECT şi JOIN
nu trebuie sa apară neapărat, funcţiile lor trebuie insă oferite.
186
6.2 Transformări logico-fizice de bază
Există mai multe abordări legate de maparea relaţiilor logice în
relaţiile fizice. Cea mai directă transformare logico-fizică este de a
implementa fiecare tabelă a schemei conceptuale ca o singura relaţie
de bază. Însa, pentru a îmbunătăţi performanţa sistemului,
proiectantul bazei de date fizice trebuie să determine dacă una din
următoarele transformări logico-fizice ar fi mai potrivită :
partiţionarea verticală a unei tabele : spargerea tabelei în mai
multe relaţii de bază , fiecare cu o parte din atributele relaţiei iniţiale
Dupa cum apare în tabelă :
187
reuniunea tabelelor : combinarea tabelelor într-o singură
relaţie de bază
188
Partiţionarea verticală poate fi potrivită dacă anumite coloane
ale tabelei sunt accesate mai frecvent dacât celelalte. Separând
coloanele accesate mai rar de cele accesate mai des se reduce
volumul de date care trebuie copiate de pe memoria secundară ca
răspuns la o cerere. Astfel tranzacţiile care cer date numai din partiţia
frecvent accesată nu trebuie să transfere şi coloanele de care nu au de
fapt nevoie.
Partiţionarea verticală poate fi de asemenea potrivită atunci
când anumite coloane ale tabelei sunt accesate în primul rând de un
alt grup. Această formă de partiţionare este în special utilă atunci
când aceste grupuri de utilizatori sunt separate geografic. Rezultatul
este o bază de date distribuită , cu anumite relaţii bazate pe un
calculator şi altele pe altul.
189
costurile de comunicare cu alte calculatoare si alte partiţii ale bazei
de date distribuite.
O altă aplicaţie a partiţionării verticale este de a forţa
restricţiile de bază. Un utilizator are acces fie la o relaţie de bază în
intregul ei, fie nu are acces de loc. Dacă anumite coloane ale tabelei
sunt necesare utilizatorilor cu un nivel de autorizare , iar celelalte
utilizatorilor cu un alt nivel de autorizare, atunci punând coloanele in
relaţii de bază diferite vom putea permite managerului bazei de date
să impună restricţiile de securitate.
190
Partiţionarea orizontală poate fi potrivită dacă anumite linii ale
tabelei sunt accesate mult mai frecvent dacât celelalte linii. Separând
liniile frecvent accesate de cele accesate mai rar reducem volumul de
date care trebuie copiate pe/de pe memoria secundară ca răspuns la
cerere. Astfel, tranzacţiile care cer date numai din partiţia frecvent
accesată nu trebuie să tragă dupa ele datele din cealaltă partiţie.
Partiţionarea orizontala poate fi de asemenea utilă atunci când
anumite linii ale tabelei sunt accesate de un anumit grup de utilizatori
iar celelalte de către un alt grup. Ca şi în cazul partiţionării verticale,
dacă cele două grupuri sunt separate geografic, rezultatul va fi o bază
de date distribuită. De exemplu, liniile din tabela CONT ar putea fi
memorate in Timişoara pentru Banatul de Sud şi în Arad pentru
Banatul de Nord.
6.2.3 Reuniunea
191
Uzual, acest atribut este atributul de cheie primară al unei
tabele şi atributul de cheie straină a celeilalte tabele.
Reuniunea este potrivită atunci când cele doua tabele sunt
aproape întotdeauna accesate împreună, cu o operaţie de JOIN pe
atributul comun.
De exemplu, să considerăm modelul de date :
192
Pentru APTITUDINI_JOB avem:
COD_JOB APTITUDINE# DESC_APTITUDINE
60 463 Tehnoredactare
60 231 Editare
70 231 Editare
70 801 C
60 333 Procesare date
Tabel 6.2 Conţinutul datelor tabelei APTITUDINI_JOB
193
6.2.4 Aplicabilitatea transformărilor
194
6.2.5 Scheme virtuale (vederi utilizator)
195
6.3. Optimizarea performanţei
Fiecare din aceste transformări între tabele şi relaţii de bază
incearcă să îmbunătăţescă performanţa bazei de date, reducâd
volumul datelor transferate la/de la memoria secundară şi reducând
cerinţele de comunicaţii într-o reţea de calculatoare.
Atunci când se dezvoltă o structură eficientă a bazei de date
fizice mai trebuiesc luate şi alte decizii :
Accesul la atribut :care atribute trebuie să aibă căi de acces
rapide preconstrite
Reuniuni preconstruite : care reuniuni între relaţiile de bază
trebuie să aibă căi de acces rapide preconstruite
Buffere :cât de mare trebuie să fie spaţiul buffer pentru a
transfera relaţiile de bază între memoria principală şi cea secundară
Gruparea relaţiilor fizice : ce relaţii de bază ar trebui memorate
împreună în acelaşi fişier
196
WHERE nume atribut1=valoare1
AND nume atribut2=valoare2
AND……
197
acea cale de acces este întotdeauna implementată pe atributul de
cheie primară.
Dacă cheia primară este compusă, atunci calea de acces rapid
este construită pe mulţimea de atribute care alcătuiesc cheia primară.
De exemplu, daca cheia primară este COD_DIVIZIE,
ID_DEPARTAMENT atunci hashingul sau indexarea se face pe
combinaţia celor doua atribute. Calea de acces cheie primară nu ar fi
complementată corect cu un index pe COD_DIVIZIE şi un alt index
pe ID_DEPARTAMENT.
Atributele de cheie alternată pot avea căi de acces rapide, dacă
ele sunt folosite în comun în loc de cheie primară pentru accesul la
tabelă. De exemplu, ANGAJAT# este cheie primară a tabelei
ANGAJAT, dar cheia alternată SSN# este mai folosită pentru a
califica liniile, atunci poate exista o cale de acces la ANGAJAT# si
una la SSN#. Utilizatorii pot astfel accesa usor datele din ANGAJAT
bazându-se pe oricare din cele două atribute.
Atributele de cheie straină pot avea căi de acces rapid
preconstruite dacă valorile lor sunt folosite uzual pentru a califica
liniile tabelei şi/sau dacă tabela este reunită frecvent cu tabela în care
atributul de cheie straină apare ca şi cheie primară. Cele două tabele
pot fi reunite mai eficient daca există indecşi pentru atributele de
reuniune.
Alte atribute pot avea căi de acces rapide dacă îndeplinesc
toate condiţiile următoare :
valorile lor sunt folosite în mod obişnuit pentru a califica linii
valorile lor nu sunt actualizate frecvent
valorile lor sunt discriminatorii
Menţinerea unei căi de acces rapid pentru un atribut ale cărui
valori se actualizează des este costisitoare. Dacă un atribut este
indexat, atunci de fiecare dată când valoarea lui se schimbă pentru
linie, structura de index trebuie modificată. Dacă liniile sunt in
hashing, atunci schimbând valoarea atributului hash aproape
întotdeauna apare necesară şi o mutare a înregistrării liniei.
198
Un atribut discriminator este unul pentru care un procent
relativ mic deţin liniile tabelei au o valoare particulara a acelui
atribut. De exemplu, in relaţia ABGAJAT, atributul COD_SEX nu
este un atribut discriminator, căci există doar două valori posibile
pentru acest atribut. Astfel construind un index dupa COD_SEX ar fi
costisitor şi nu va reduce numărul de inregistrări analizate ca răspuns
la o cerere utilizator. Pe de altă parte, COD_JOB probabil că este un
atribut discriminator. Dacă exista 100 de valori posibile pentru
COD_JOB, atunci un index care suportă accesul direct pe COD_JOB
reduce o căutare 1% din inregistrare.
199
b. liste înlănţuite, cu un lanţ de pointeri de la fiecare
linie dintr-o tabelă la liniile potrivite din cealaltă
tabelă
B D E Primul R cu
valoarea B
b1 d1 e1 1
b2 d2 e2 3
b3 d3 e3 4
b4 d4 e4 0
b5 d5 e5 0
Tabel 6.4 Conţinutul lui S
A B C Urmatorul R cu
valoarea B
a1 b1 c1 2
a2 b2 c2 0
a3 b3 c3 0
a4 b4 c4 5
a5 b5 c5 0
Tabel 6.5 Conţinutul lui R
200
Nu toate SGBD-urile relaţionale suportă reuniuni
preconstruite. Proiectantul bazei de date fizice trebuie să determine
care reuniuni ar pute fi preconstruite, pe baza beneficiilor prezise.
DIRECTOR
Valoare B Pointer R Pointer S
b1 1 1
b1 2 1
b2 3 2
b3 4 3
b3 5 3
b4 0 4
b5 0 5
Tabel 6.6 Conţinutul listei de pointeri
6.3.3 Buffere
201
6.3.4 Gruparea relaţiilor de bază
202
Daca tuplele din două relaţii de bază sunt mai rar accesate
împreună, atunci ele trebuie memorate în fişiere separate. Obiectivul
este de a grupa pe o pagină tuplele care par a fi accesate împreună. O
altă posibilitate pentru gruparea fizică este de a plasa pe o aceeaşi
pagină liniile care par a fi accesate împreună. Aceste linii pot fi de la
aceeşi relaţie sau de la relaţii diferite, presupunând că un fişier poate
memora mai multe de o relaţie.
203
6.4 Baze de date relaţionale distribuite
Baza de date descrisă de un singur model de date logice poate
fi implementată fizic pe mai multe calculatoare, conectate printr-o
reţea de comunicaţii. Rezultatul este o bază de date distribuită. Nu
toate datele rezidă într-o bază de date fizică, dar exista un model
logic care leagă datele împreună.
Datele pot fi distribuite în mai multe moduri, incluzând :
partiţii întregi, în care o relaţie este memorată în întregime
într-o bază de date fizică
partiţii orizontale, în care anumite linii ale unei relaţii sunt
memorate într-o bază de date fizică si celelalte într-alta.
Partiţii verticale, în care anumite coloane ale unei relaţii sunt
memorate într-o bază de date fizică iar altele într-alta.
Partiţii cu acoperiri, în care o parte sau tot conţinutul unei
partiţii este replicat într-o altă partiţie.
Raţiunea primară pentru o bază de date distribuită este ca o
întreprindere descentralizată care trebuie să partajeze informaţii între
diferitele părţi distribuite. Operaţiile distribuite pot conduce la
următoarele situaţii :
Datele pot fi generate în mai multe părţi, cerând acces local
rapid şi rezumate de date dincolo de local.
Datele pot fi generate central, cerând acces rapid la distanţă.
Atât central cât şi parţiile trebuie să actualizeze datele.
Datele pot fi generate în multe părţi, cerând acces rapid atât
la datele locale cât şi la cele memorate la distanţă.
În toate aceste situaţii, distribuirea bazei de date poate conduce
la o mai buna performanţă decât centralizarea ei într-o locaţie.
Aceasta are loc deoarece distribuirea reduce volumele de comunicaţii
de date, majoritatea acceselor fiind locale şi reduce volumul de date
204
memorate pe orice maşină dată, reducând cerinţele de capacitate şi
îmbunătăţind responsabilităţile locale.
205
Capitolul VII. TRANZACŢII
ÎN BAZE DE DATE
DISTRIBUITE
7.1 Introducere
Mecanismele tranzacţionale nu sunt o noutate în lumea bazelor
de date. În anii 70, la doar câteva sute de kilometri distanţă,
laboratoarele IBM de la San Jose şi Universitatea Berkeley dezvoltau
în paralel primele sisteme relaţionale, System R şi Ingres, ambele
cuprinzând anumite forme de procesare tranzacţională. Începând de
atunci, toate SGBD-urile importante încorporează mecanisme
tranzacţionale.
Procesarea tranzacţiilor are ca scop păstrarea integrităţii bazei
de date. Trebuie însă precizat că mecanismele tranzacţionale nu sunt
singurele care se ocupă de păstrarea integrităţii. Mai precis,
procesarea tranzacţiilor se referă doar la două aspecte:
Recuperarea bazei de date după un incident (database
recovery) – se bazează pe includerea unui anumit nivel de
redundanţă prin memorarea istoriei tranzacţiilor într-un aşa-numit
“jurnal” (log). Deşi acest aspect nu face subiectul articolului de faţă,
anumite elemente tehnice privind jurnalizarea vor fi utilizate în
continuare.
Controlul interferenţelor care pot avea loc între tranzacţiile
care se execută in mod concurent (concurrency control) – este un
aspect critic în sistemele de aplicaţii OLTP (On-Line Transaction
Processing). Este vorba despre “controlul” (şi nu neapărat
“evitarea”) interferenţelor deoarece, deşi întotdeauna nedorite, aceste
interferenţe pot fi permise – în anumite forme bine precizate – pentru
206
a creşte performenţele sistemului. Vom vedea în continuare cum se
realizează acest lucru.
207
7.2 Tranzacţii
7.2.1 Definiţie
208
acesteia prin refacerea stării bazei de date dinaintea începerii
tranzacţiei.
E de remarcat faptul că operaţia ROLLBACK poate fi
explicită (specificată ca atare în program) sau implicită (deci
declanşată automat de sistem în cazul în care programul client nu
reuşeşte, dintr-un motiv sau altul, să se termine normal).
7.2.4 Izolare
209
tranzacţie va genera o stare inconsistentă. Cum pe timpul
execuţiei unei tranzacţii este posibil ca baza de date să fie
inconsistentă, rezultată că o tranzacţie nu are voie să acţioneze
asupra rezultatelor intermediare ale altei tranzacţii sau, altfel
spus, tranzacţiile trebuie să se execute ca şi cum ar fi izolate.
7.2.5 Durabilitatea
210
t1 – R1: Read Z
t2 – R2: Read Z
t3 – R1: Write z
t4 – R2: Write Z
...
Citirile efectuate de cele doua tranzacţii vor găsi linia în
aceeaşi stare. Să presupunem că valoarea câmpului VANDUT
este 25. Ambele tranzacţii vor seta variabilele lor locale vândut
la valoarea 25. Actualizarea efectuată de tranzacţia R1 la
momentul t3 va modifica valoarea câmpului la 26. La momentul
t4, tranzacţia R2 actualizează şi ea linia Z, plasând însă câmpului
VANDUT aceeaşi valoare. Se realizează două rezervări, dar
numărul locurilor vândute creşte cu o unitate. Dacă numărul
solicitărilor este mare, este foarte probabil că va fi vândut un loc
în plus la cursa respectivă.
Anomalia, numită “modificarea pierdută” (the lost
update) a survenit datorită faptului că tranzacţia R2 şi-a bazat
actualizarea de la momentul t4 pe o valoare citită la momentul
t2, care însă a fost între timp (la momentul t3) modificată de
tranzacţia R1. Practic, efectul actualizării realizate de tranzacţia
R1 la momentul t3 s-a pierdut. Dacă tranzacţia R2 ar fi citit linia
Z după ce ea a fost modificată de R1, atunci R2 ar fi plasat în
câmpul VANDUT valoarea 27, ceea ce ar fi fost corect.
O altă situaţie posibila este cea în care una dintre
tranzacţii este anulată. Să consideram scenariul următor:
t1 – R2: Read Z
t2 – R2: Write Z
t3 – R1: Read Z
t4 – R2: ROLLBACK
t5 – R1: Write Z
211
...
În această situaţie, tranzacţia R1 va avea în variabilele
locale rezultatul scris de tranzacţia R2 la momentul t2. Anularea
tranzacţiei poate surveni din motive diverse (să presupunem că
adăugarea liniei corespunzătoare rezervării în tabela REZ
eşuează din lipsa de spaţiu pe disc) şi va provoca revenirea liniei
Z la valorile dinainte de momentul t2. În acest caz, tranzacţia R1
îşi va baza acţiunile viitoare pe nişte valori care, practic, nu au
existat niciodată în baza de date! Să presupunem că la momentul
t1 câmpul VANDUT al liniei Z conţinea valoarea 25. La
momentul t2 această valoare este incrementată, astfel încât
tranzacţia R1 va citi la momentul t3 valoarea 26. La momentul
t4, tranzacţia R2 este anulată şi în consecinţă, valoarea câmpului
VANDUT al liniei Z va fi adusă la valoarea pe care o avea
înainte de începerea tranzacţiei R2, deci 25. La momentul t5,
tranzacţia va scrie în linia Z valoarea 27. Ceea ce este, evident,
greşit. Anomalia (numită uncomitted dependency) provine din
faptul că tranzacţia R1 a citit rezultate intermediare ale
tranzacţiei R2.
Pentru a exemplifica o a treia anomalie, numită “analiza
inconsistentă” (inconsistent analysis) vom considera tabela
CLIENT, asupra căreia se execută în mod concurent doua
tranzacţii. Tranzacţia T1 calculează suma totala încasată de la
pasagerii cursei Z, în timp ce tranzacţia T2 transferă o anumită
sumă x din contul unui client C3 în contul unui client C1 (care s-
a întâmplat că au zburat împreună). În mod normal suma totală
ar trebui să fie aceeaşi indiferent în care cont se afla suma x. Să
presupunem că soldurile clienţilor C1,C2 si C3 sunt 200, 100 şi
respectiv 300, iar x este 20.
Dar iată ce se poate întâmplă:
212
t4-T2: Write C3 (sold=280)
t7-T2: Commit
213
“mărci de timp” (timestamping) asupra tranzacţiilor şi a
obiectelor implicate în tranzacţii. Ambele procedee (precum si
procedeele “hibride”) pornesc de la premiza pesimistă că
interfeţele nedorite sunt oricând posibile şi chiar probabile, deci
se bazează pe prevenirea lor. Există însă şi o abordare optimistă,
care pleacă de la “prezumţia de nevinovăţie” şi care încearcă
doar să depisteze şi să rezolve conflictele în cazul în care acestea
apar. Toate metodele au avantaje si dezavantaje, fiecare dintre
ele se pretează la anumite aplicaţii şi sunt inacceptabile în cazul
altora.
214
OBS – Cerinţe speciale.
begin_transaction Rezervare
begin
input (nr_zbor, data, nume_client);
EXEC SQL SELECT VANDUT, CAP
INTO vândut,cap
FROM ZBOR
WHERE NR=nr_zbor
AND DATA=data;
if vândut=cap then
begin
output (“nu mai sunt locuri”);
Abort
end
else
begin
EXEC SQL UPDATE ZBOR
SET VANDUT=vândut + 1
215
WHERE NR=nr_zbor AND DATA=data;
EXEC SQL INSERT
INTO REZ (NR, DATA, NUME, OBS)
VALUES (nr_zbor, data, nume_client,
null);
Commit;
Output (“OK”)
end
end-if
end.
begin_transaction Taxare
begin
input(nume_client, adr, suma);
EXEC SQL SELECT SOLD
INTO sold
FROM CLIENT
WHERE NUME = nume_client:
if SQLSTATE = “02000” then
begin (*client nou*)
EXEC SQL INSERT
216
INTO CLIENT (NUME, ADR, SOLD)
VALUES (nume_client, adr,0);
end
end – if;
EXEC SQL UPDATE CLIENT
SET SOLD = sold + suma
WHERE NUME = nume_client;
Commit;
Ouput (“OK”)
end.
217
7.3 Blocare (Lock)
Ideea pe care se bazează tehnica blocării este foarte simplă: o
tranzacţie care a început să opereze asupra unor date trebuie să
interzică accesul altor tranzacţii la datele respective până în
momentul în care operaţia se încheie. În acest timp, datele sunt
“ţinute sub cheie” (to lock – a încuia ). Controlul blocării datelor este
asigurat de o componentă a SGBD – ului numită Lock Manager
(LM). În momentul în care o tranzacţie T doreşte să acceseze un
anumit obiect al bazei de date (piesa de date), va cere componentei
LM blocarea obiectului. Dacă obiectul este blocat de o altă
tranzacţie, tranzacţia T va fi pusă în stare de aşteptare (wait) până
când obiectul este eliberat.
Să reanalizăm a doua anomalie prezentată în secţiunea
precedentă (uncommited dependency). La momentul t1 tranzacţia R2
blochează linia Z. La momentul t3, tranzacţia t3, tranzacţia R1 cere
la rândul ei blocarea liniei Z dar, linia fiind deja blocată de R2 , este
pusă în stare de aşteptare. La momentul t4, tranzacţia R2 se termină
(prin ROLLBACK) şi eliberează linia Z. Abia acum R1 obţine
blocarea liniei Z şi poate să o acceseze. Datele asupra căruia
acţionează acum R1 sunt “curate” (efectele tranzacţiei R2 au fost
anulate ), deci anomalia a fost evitată.
Se poate observa cu uşurinţă că această modalitate de
blocare este prea restrictivă. Anomaliile apar doar în cazul
actualizărilor datelor, ceea ce sugerează ca rafinare a tehnicii implica
folosirea a doua tipuri de blocări:
Blocare partajata (share lock sau Slock) – Permite citirea
obiectului dar interzice modificarea acestuia, motiv pentru care mai
este numită “blocare pentru citire” (read lock). Mai multe tranzacţii
pot bloca simultan pentru citire un anumit obiect.
Blocare exclusivă (exclusive lock sau x lock) – Interzice
accesul altor tranzacţii la obiectul blocat, fie pentru citire, fie pentru
modificare. Blocarea exclusivă este mai “tare” decât blocarea
218
partajata, fiind folosită doar pentru actualizări, motiv pentru care mai
este numită “blocare pentru scriere” (write lock).
Se poate observa că anumite cereri de blocare asupra unui
obiect pot fi compatibile sau nu, în funcţie de tipul blocării.
Compatibilitatea cererilor de blocare poate fi exprimată sintetic
printr-o matrice de compatibilitate.
O situaţie specială este cea în care o tranzacţie blochează
pentru citire un obiect şi doreşte să obţină o blocare exclusivă. Dacă
obiectul respectiv nu este blocat partajat şi de către alte tranzacţii,
blocarea exclusivă este obţinută de tranzacţia în cauză. Procedeul se
numeşte “promovarea blocării” (lock promotion).
În cazul celor mai multe SGBD-uri, blocarea este implicită:
orice operaţie asupra datelor este automat precedată de cererea
pentru obţinerea blocării datelor respective (S lock pentru citire, X
lock pentru actualizare – adică: UPDATE, INSERT şi DELETE).
Încheierea tranzacţiei (cu sau fără succes) eliberează în mod automat
blocările pe care aceasta le deţinea. Anumite sisteme (ex. Adabas D)
permit “înlănţuirea tranzacţiilor” (transaction chaining) cu păstrarea
anumitor blocări (prin clauza KEEP LOCK a instrucţiunii
COMMIT).
Standardul SQL nu face nici o prezumţie legată de modul de
implementare a mecanismelor de control al accesului concurent (prin
blocare, prin mărci de timp sau alte metode) şi, în consecinţă, nu
prevede instrucţiuni explicite de blocare. Cu toate acestea,
majoritatea SGBD-urilor relaţionale oferă în propriile dialecte SQL
instrucţiuni de blocare explicită (LOCK). Anumite sisteme non-
relaţionale (Raima, de exemplu) folosesc doar blocări explicite. De
obicei aceste sisteme prevăd şi instrucţiuni de deblocare explicită
(UNLOCK).
Deşi sunt cele mai uzuale, blocările partajate şi exclusive nu
sunt singurele posibile. Unele SGBD-uri (IBM DB2, Sybase SQL
Server, Raima db_VISTA ) folosesc o aşa-numita “blocare pentru
actualizare” (update lock), care este un nivel intermediar între
blocarea partajată şi cea exclusivă. Dacă mai multe tranzacţii
blochează partajat (pentru citire) un anumit obiect, una dintre ele
219
(doar una) poate obţine o blocare pentru actualizare (remarcaţi că o
blocare exclusivă nu poate fi obţinută în aceste codiţii). De obicei
utilizarea blocării pentru actualizare este posibilă doar în situaţia
unui mecanism de control special (bazat în general pe versiuni
multiple ale datelor) care să avertizeze o altă tranzacţie care solicită o
blocare pentru actualizare că datele au fost modificate.
O tabelă de date poate fi la un moment dat blocată în mod
exclusiv (x), blocată în mod parţial (S) sau poate să nu fie blocată (-).
În funcţie de aceasta stare, o altă cerere de blocare poate fi
compatibilă (Y – caz în care Lock Managerul o rezolvă favorabil)
sau conflictuală (N – caz în care este refuzată, tranzacţia care a emis-
o fiind pusă în stare de aşteptare).
Matricea de compatibilitate pentru blocări exclusive şi
partajate este:
X S -
X N N Y
S N Y Y
- Y Y Y
220
X SIX IX S IS -
X N N N N N Y
SIX N N N N Y Y
IX N N Y N Y Y
S N N N Y Y Y
IS N Y Y Y Y Y
- Y Y Y Y Y Y
221
7.4 Interblocare (Deadlock)
Să revedem acum problema “actualizării pierdute”,
folosind blocările partajate şi exclusive. La momentul t1
tranzacţia R1 solicită o blocare partajată a liniei Z şi
(presupunând că linia nu era blocată pentru scriere de o altă
tranzacţie) o obţine. La momentul t2, tranzacţia R2 solicită şi
ea o blocare partajată a liniei Z, pentru a face o actualizare. Nu
obţine blocarea, deoarece linia este blocată pentru citire de
tranzacţia R2,deci este pusă în stare de aşteptare. Tranzacţia R2
cere şi ea blocarea exclusivă şi, evident, nu o obţine din motive
similare. Nici una dintre tranzacţii nu poate continua, deoarece
fiecare aşteaptă ca cealaltă să elibereze linia Z.
Această situaţie se numeşte deadlock sau
“interblocare”. Este uşor de verificat că şi în situaţia “analizei
inconsistente” se va ajunge la o interblocare. Rezultatul este că
am rezolvat problema anomaliilor dar am obţinut o altă
problemă, cea a interblocărilor. Rezolvarea noii probleme
cuprinde două aspecte:
1) Prevenirea interblocării.
222
întotdeauna, deoarece este posibil ca o tranzacţie să nu
cunoască de la început toate datele de care are nevoie.
2) Detectarea interblocării.
7.5 Serializare
Problema care se pune este: cum putem ştii dacă
execuţia concurentă a unui grup de tranzacţii este corectă sau
nu ?
Să începem cu o definiţie: Se numeşte planificare
(schedule) oricare ordine posibilă de executare a operaţiilor
grupului de tranzacţii considerat.
O primă constatare este că, dacă presupunem că fiecare
tranzacţie în parte din grup este corectă, atunci orice planificare
serială a tranzacţiilor (una după alta indiferent de ordine) este
corectă. Deşi afirmaţia este intuitivă, se poate justifica uşor
prin faptul că orice program execută o secvenţă de tranzacţii
(deci niciodată două tranzacţii simultan). Aşadar tranzacţiile
din grupul considerat sunt executate de programe diferite (sunt
deci independente), ordinea execuţiei lor fiind irelevantă (de
regulă FIFO: first in first out).
În cazul în care se execută operaţii ale unei tranzacţii în
timp ce execuţia altor tranzacţii nu a fost încă încheiată avem
de-a face cu o planificare intercalată (interleaved), caz în care
este posibil ca execuţia să nu fie corectă (cum a fost cazul celor
trei exemple prezentate la început).
Două planificări ale unui grup de tranzacţii sunt
echivalente dacă vor produce mereu acelaşi rezultat, oricare ar
224
fi starea iniţială a bazei de date (aceasta înseamnă de fapt, că
operaţiile conflictuale sunt în aceeaşi ordine).
O planificare este serializabilă dacă este echivalentă cu
o planificare serială. Orice planificare serială fiind corectă,
înseamnă că am găsit criteriul de corectitudine căutat. Execuţia
unui grup de tranzacţii este corectă dacă s-a făcut conform unei
planificări serializabile. Să remarcăm că nici una dintre
planificările utilizate ca exemple pentru cele trei anomali nu
este serializabilă.
O caracterizare mai puţin riguroasă, dar mult nai
intuitivă a serializabilităţii este următoarea: Oricare ar fi două
tranzacţii A şi B dintr-o planificare a unui grup de tranzacţii
concurente, fie A precede logic pe B, fie B precede logic pe A.
Faptul că “A precede logic pe B” înseamnă că B poate vedea
rezultatele execuţiei tranzacţiei B. Deci, dacă consideram toate
obiectele de tranzacţia A, atunci B vede toate aceste obiecte fie
modificate deja de A, fie în forma în care erau înainte ca
modificările să se producă, dar niciodată ca un amestec de
obiecte modificate sau nemodificate.
Teoria este, desigur, mult mai bogata şi specifică mai
mulţi algoritmi de verificare a criteriului pe care l-am enunţat.
Rezultatul cel mai important din perspectiva practică a acestei
teorii este aşa – numita “teorema a seriabilităţii” (sau “a
blocării în două faze”):
Dacă toate tranzacţiile unui grup de tranzacţii
concurente sunt bine formate şi respectă protocolul de blocare
în doua faze, atunci orice planificare legală este serializabilă.
Demonstraţia nu este dificilă. Importante sunt
condiţiile:
O tranzacţie este “bine formată” dacă orice operaţie a
tranzacţiei este acoperită de o blocare şi toate blocările sunt
eliberate. O operaţie (citire sau scriere) este “acoperită de o
225
blocare” dacă tranzacţia deţine o blocare suficient de puternică
a obiectului asupra căruia se desfăşoară operaţia.
O planificare este “legală” dacă nu se desfăşoară în
condiţiile unor blocări conflictuale.
Un “protocol de blocare” constă dintr-un set de restricţii
impuse ordinii în care tranzacţiile concurente blochează şi
deblochează obiectele bazei de date. Protocolul de blocare în
două faze (two – phase locking) impune următoarele două
restricţii:
Înainte de a opera asupra oricărui obiect al bazei de
date, o tranzacţie trebuie să obţină blocarea respectivului
obiect.
După ce a eliberat o blocare, o tranzacţie nu va mai
încerca niciodată să obţină noi blocări. Se observă cu uşurinţă
explicaţia denumirii “în două faze” (care n-are nimic în comun
cu comiterea în doua faze): conform acestui protocol orice
tranzacţie trece mai întâi printr-o fază de eliberare a blocărilor.
O scurtă discuţie asupra acestui protocol se impune. În
primul rând trebuie spus că sarcina asigurării respectării acestui
protocol revine Lock Manager-ului (desigur, dacă sistemul
lucrează pe baza acestui protocol). Mai observăm că protocolul
prevede “eliberarea blocărilor”. O regulă de “bun simţ” spune
că un obiect trebuie blocat cât mai puţin timp cu putinţă, pentru
a permite şi accesul altor tranzacţii la acesta. Din păcate,
implementarea acestui protocol în forma sa cea mai eficientă
din acest punct de vedere este extrem de dificilă: LM trebuie
să “ştie” când o tranzacţie a obţinut toate blocările şi nu va mai
avea nevoie de altele (pentru a identifica faza în care se află);
LM trebuie să ştie dacă tranzacţia va mai avea nevoie de un
obiect asupra căruia a efectuat o operaţie, deci dacă poate sau
nu să o elibereze (din acelaşi motiv al identificării fazelor); în
fine, apare problema extrem de dificilă a “anularii în cascadă”
226
a tranzacţiilor: în cazul în care o tranzacţie o fost anulată în
faza a doua, este posibil ca unele date eliberate de aceasta au
fost apoi blocate de alte tranzacţii, caz în care aceste tranzacţii
trebuie la rândul lor anulate. Din cauza acestor dificultăţi,
majoritatea sistemelor implementează o variantă mai restrictivă
a protocolului, în care toate eliberările blocărilor unei tranzacţii
sunt amânate până la terminarea tranzacţiei (fie prin COMMIT
fie prin ROLLBACK). Este deci rezonabil să considerăm că
blocările obţinute de o tranzacţie sunt păstrate până la
terminarea acesteia, cu toate că în felul acesta intervalul de
timp în care un obiect este blocat este de regulă mai lung decât
minimul necesar. Compromisul este si aici prezent:
simplificarea mecanismelor implementate în Lock Manager
compensează scăderea nivelului de concurenţă prin blocări de
mai lungă durata. Există însă situaţii în care se poate admite un
grad oarecare de interferenţă, caz în care nivelul concurenţei
poate fi crescut prin “relaxarea” protocolului de blocare (în
speţă prin admiterea unor condiţii în care anumite blocări pot fi
eliberate înaintea terminării tranzacţiei).
Observaţie: După cum se ştie, toate sistemele
relaţionale majore implementează diverse forme ale
protocolului de blocare în două faze. Sistemele care utilizează
doar blocări şi deblocări explicite lasă implementarea acestui
mecanism în seama proiectanţilor. În orice situaţie, proiectanţii
sunt sfătuiţi să nu lase controlul blocării nici o clipă în seama
utilizatorilor finali, din motive lesne de înţeles (sindromul
“blocării peste pauza de masa”).
Se remarcă cu siguranţă că am evitat sistematic să
precizez ce anume este “obiectul” asupra căreia se aplică
blocarea, iar în exemple am considerat că blocarea se face la
nivelul liniei de tabela (care în sistemele non-relaţionale se
poate chema “articol” sau “înregistrare” - record). Nivelul la
care se face blocarea se numeşte de obicei granulaţie (locking
granularity). Cu cât granulaţia este mai fina, blocarea se face la
227
nivele inferioare (poate să ajungă la nivelul unui câmp al unui
articol). O granulaţie mai grosieră (coarse) se referă la blocarea
unei volume mari de date, care pot să meargă până la nivelul
întregii baze de date.
Granulaţia mai poate fi analizată şi prin prisma
orientării ei logice sau fizice. De pilda unele sisteme aplică
(sau pot aplica) blocarea la nivel de fişier sau “spaţiu de date”.
La majoritatea SGBD-urilor, un fişier poate să conţină mai
multe tipuri de articole (linii din mai multe tabele, în limbaj
relaţional) sau, dimpotrivă, doar o parte din ocurenţele unui tip
de articole (o parte din liniile unei tabele). Un alt caz tipic de
blocare la nivel fizic este cel care se referă la un “bloc de date”,
adică la unitatea de transfer între disc şi memorie. Blocarea la
nivel de “pagina” (page) poate fi logică (cel mai adesea) sau
fizică, în funcţie de accepţiunea care i se dă de către SGBD-ul
în cauză.
Cele mai multe sisteme moderne utilizează blocarea la
nivel logic, cea mai comună fiind actualmente blocarea la nivel
de articol (linie dintr-o tabela). Blocarea unei întregi tabele este
tot o blocare logică, dar mai grosiera. Există şi posibilitatea de
a bloca o submulţime precizată de linii dintr-o tabelă (singurul
sistem care dispune de această abilitate este Tandem NonStop
SQL/NP).
Esenţial este faptul că o granulaţie mai fină a blocării
permite o mai mare concurenţă, şansele ca tranzacţiile
concurente să blocheze aceleaşi date scăzând. Pe de altă parte
nu trebuie uitat că blocarea în sine este o operaţie complexă şi
consumatoare de resurse. O cerere de blocare la nivelul unei
linii dintr-o tabelă implică testarea existenţei unor blocări
conflictuale. Dacă blocarea se face la nivel de tabelă,
încărcarea adusă de mecanismul de blocare este mult mai mică.
Dezavantajul este că doar o singură tranzacţie va avea acces la
datele acesteia la un moment dat.
228
Pentru a permite o echilibrare optimă a acestor avantaje
şi dezavantaje, multe sisteme permit utilizarea simultană a mai
multor granulaţii. Ca exemplu, Oracle suportă blocarea la nivel
de linie şi tabelă, IMB DB2 la nivel de linie, pagină şi fişier
tablespace iar Sybase la nivel de pagină şi tabelă.
229
7.6 Blocare ierarhică
Dacă până acum am folosit în exemple doar blocări la
nivel de articol, în cele ce urmează vom considera şi blocări
aplicate unor porţiuni mai mari (pentru a nu complica
expunerea, ne putem limita la nivel de tabela). Tehnica blocării
ierarhice se referă la sistemele care admit mai multe granulaţii
ale blocării şi a fost introdusă de Jim Gray şi colaboratorii săi
încă din 1975. O descriere mai “didactică“ poate fi consultată
în [GRAY93].
Ideea de la care se pleacă este că pentru a obţine o
blocare la nivel de articol (linie din tabelă), o tranzacţie trebuie
să-şi manifeste această intenţie, cerând mai întâi o blocare la
nivel de tabelă. În felul acesta se simplifică procesul de
detectare a unor cereri conflictuale de blocare la nivel de linie,
deoarece ele trebuie întâi să se manifeste la nivel de tabelă.
Protocolul bazat pe “intenţii de blocare” (intent locking)
introduce trei noi tipuri de blocare (la nivel de tabelă), alături
de cele doua tipuri de blocări uzuale (S-lock si X-lock) care,
aşa cum am arătat deja, au sens şi la nivel de tabelă. Avem
astfel cinci tipuri de blocări pe care o tranzacţie T le poate
solicita la nivelul întregii tabele R, prezentate în ordinea
crescătoare “tăriei” lor relative:
IS – intent shared. Tranzacţia T intenţionează să
blocheze pentru citire (Slock) anumite linii ale tabelei R, pentru
a garanta stabilirea acestora în timpul procesărilor pe care le va
efectua.
IX – intent exclusiv. La fel ca IS, dar T s-ar putea să
vrea să modifice anumite articole şi deci să solicite blocarea
exclusivă a acestora.
230
S – shared. Este obişnuita blocare partajată. T admite
citiri concurente ale tabelei R, dar nu şi scrieri. T nu va face
nici o scriere la nivelul liniilor tabelei.
SIX – shared intent exclusiv. Combină S şi IX. În plus
faţă de S, T s-ar să vrea să modifice anumite linii din R şi, în
consecinţă, să solicite blocarea exclusivă a acestora.
X – exclusive. T nu admite citiri concurente în tabela R.
T ar putea să actualizeze anumite linii ale tabelei R.
Observaţii
Noţiunea de “tărie“ a blocării se referă la faptul că o
cerere de blocare de un anumit tip care eşuează, va eşua cu
siguranţă pentru orice tip mai “tare”.
Tipurile IX şi S sunt egale din punct de vedere a
“tăriei”.
Şi aceste tipuri de blocări sunt în mod obişnuit cerute în
mod implicit. Cu toate acestea, sistemele care implementează
aceste tipuri de blocare (DB2, OpenIngres) oferă de obicei şi o
instrucţiune de blocare explicită pentru aceste tipuri.
Varianta pe care am prezentat-o este mult simplificata.
De fapt blocările se pot referi la orice granulaţii şi orice obiecte
ale bazei de date (inclusiv indecşi).
În fine, protocolul bazat pe intenţii de blocare (intent
locking protocol), impune două reguli care îmbină blocările
nivel de tabelă şi de articol într-o combinaţie care adesea s-a
dovedit mai eficientă în aplicaţii:
Înainte de a obţine o blocare partajată (S) la nivel de
linie, tranzacţia trebuie să obţină o blocare de tip IS (sau mai
tare) la nivelul întregii tabele.
231
Înainte de a obţine o blocare de tip exclusiv (X) la nivel
de linie, o tranzacţie trebuie să obţină o blocare de tip IX sau
mai tare la nivelul întregii tabele.
232
Capitolul VIII. ANOMALII DE
COMPORTAMENT ŞI
ALGORITMI DE CONTROL A
CONCURENŢEI ÎN SGBD
DISTRIBUITE
233
multe ori. Acest lucru este posibil deoarece în intervalul de timp de
la acceptarea unei anumite cereri de rezervare pe un loc anume şi
până la rezolvarea acesteia (eliminarea locului cu pricina din lista de
locuri libere) ar putea fi acceptate şi rezolvate alte cereri de rezervare
pentru acelaşi loc. Deci două procese care citesc şi modifică valoarea
aceluiaşi obiect ar putea interacţiona în mod nedorit atunci câând
sunt executate simultan. Pentru a evita interactiunile nedorite este
necesară impunerea unor restricţii asupra execuţiei concurente a
proceselor care execută operaţii de citire şi de modificare a datelor.
Calea cea mai simplă de evitare a interacţiunilor este de a
executa tranzacţiile în mod independent, una după cealaltă. Este clar
că o asemenea alternativă prezintă interes doar din punct de vedere
teoretic şi este practic inacceptabilă, deoarece minimizează eficienţa
sistemului. De fapt, nivelul de concurenţă, măsurat prin numărul de
tranzacţii executate concurent, este unul dintre cei mai importanţi
parametrii pentru caracterizarea unui asemenea sistem.
Din acest motiv, mecanismele de control al concurenţei
urmăresc realizarea unui compromis între menţinerea consistenţei
bazei de date şi obţinerea unui nivel de concurenţă cât mai ridicat.
Din punctul de vedere al tranzacţiilor, controlul concurenţei asigură
proprietăţile de izolare şi consistenţă ale acestora, chiar şi în
condiţiile executării concurente a mai multor tranzacţii.
În cele ce urmează vom presupune că sistemul în discuţie este
absolut sigur, deci ne aflăm în situaţia ideală în care nu sunt posibile
nici un fel de defecte (hardware sau software). Deşi ipoteza este total
nerealistă, ea constituie o simplificare necesară deoarece permite
izolarea aspectelor legate de controlul concurenţei fată de cele
relative la rezistenţa la defecte. Vom renunţa la această ipoteză
atunci când vom trece la prezentarea aspectelor legate de rezistenţa la
defecte a sistemelor, unde vom analiza modificările care trebuie
fâăcute algoritmilor de control al concurenţei pentru a asigura fie
funcţionarea fără întreruperi a sistemului; fie posibilitatea de
recuperare a acestuia la apariţia diverselor defecte.
234
8.1. Anomalii de interferenţă în BD distribuite
Interacţiunea necontrolată a două sau mai multe tranzacţii
poate conduce la apariţia unor stări inconsistente ale bazei de date şi
la producerea unor rezultate eronate. Două tranzacţii T i şi Tj sunt
susceptibile de interferenţă dacă rezultatul
execuţiei concurente a acestora poate fi diferit de rezultatul
execuţiei seriale. Între două tranzacţii poate să apară o interferenţă
dacă acestea efectuează operaţii asupra unor date comune. În plus,
dacă aceste tranzacţii sunt executate în mod concurent, atunci
spunem că sunt conflictuale. Deci două tranzacţii Ti şi Tj sunt
conflictuale dacă sunt concurente şi susceptibile de interterenţă.
În funcţie de natura operaţiilor pe care le efectuează asupra
datelor comune, între două tranzacţii pot să apară mai multe tipuri de
interferenţă. Aceste interferenţe sunt cauza a mai multor anomalii de
interferenţă:
Exemplu:
T1 T2
READ A;
READ A;
235
A=A+5;
WRITE A;
A=A+10;
WRITE A;
în urma căreia valoarea lui A apare mărită cu 10, în loc de 15
aşa cum ar fi de aşteptat. Este ca şi cum tranzacţia T1 nu s-ar fi
executat de loc.
T1 T2
READ A;
A=A-10;
WRITE A;
READ A;
READ B;
C=A+B;
WRITE C;
READ B;
B=B+10;
WRITE B;
236
unde se remarcă faptul că valoarea sumei A+B este aceeaşi
înainte şi după execuţia de mai sus. Intenţia este de a reţine în C
valoarea acestei sume, dar datorită interferenţei valoarea din C este
cu 10 mai mică decât cea reală.
237
8.2. Introducerea restricţiilor de comportamet
concurent: primitivele LOCK şi UNLOCK
238
este blocată. În acest caz valoarea returnată de funcţia LOCK() este
TRUE. Orice tentativă de a executa primitiva LOCK() asupra unei
valori blocate va eşua, valoarea returnată fiind FALSE. Acesta este
cel mai simplu mecanism de a asigura excluderea mutuală. De
remarcat că problema excluderii mutuale nu este specifică numai
bazelor de date, ci caracterizează orice sistem concurent, limbaje
concurente, sisteme de operare, hardware-uri paralele etc.
239
WHILE NOT(LOCK(A));
READ A;
A=A+1;
WRITE A;
UNLOCK(A);
Observăm că dacă una dintre tranzacţii, să zicem T 1, obţine
accesul exclusiv la valoarea A, atunci tranzacţia T 2 va trebui să
aştepte terminarea completă a lui T1 pentru a obţine accesul la
valoarea A. La terminarea tranzacţiei T1 valoarea lui A este mărită
cu 1, iar la terminarea lui T2 valoarea va fi mărită cu 2.
În această ultimă variantă rezultatul este corect, dar execuţia
este pur secvenţială, nu este posibil nici un fel de paraâlelism în
executarea celor două tranzacţii. Din punctul de vedere al timpului
de execuţie această situaţie este inacceptabilă şi de aceea se folosesc
algoritmi care să realizeze ordonări secvenţiale legafe cu un grad de
concurenţă al execuţiei cât mai ridicat, dar şi cu garanţia obţinerii de
rezultate corecte.
Lock Manager
O bază de date este partiţionată în mai multe unităţi de acces
(items). Acestea sunt porţiuni ale bazei de date care pot constitui
obiectul unei. operaţii de blocare (lock). Prin blocarea unei unităţi de
acces o tranzacţie poate împiedica accesul altor tranzacţii la unitatea
blocată pâână în momentul deblocării acestei unităţi de către
tranzacţia care a efectuat blocarea. Gestiunea operaţiilor de blocare,
precum şi arbitrarea cererilor de blocare venite din partea
tranzacţiilor este realizată de către o componentă specială a SGBD
numită lock manager.
Natura şi dimensiunea unităţilor de acces este stabilită de
proiectantul sistemului. De exemplu, în cazul modelului de date
relaţional unităţile de acces pot fi de dimensiuni mari cuprinzând
relaţii întregi ale bazei de date, pot fi grupuri de tuple sau pot fi tuple
individuale sau chiar componente ale tuplelor. Prin alegerea unor
240
unităţi de acces de mari dimensiuni se reduce numărul operaţiilor de
blocare ceea ce înseamnă reducerea excesului de timp consumat de
sistem pentru gestiunea acestor operaţii, precum şi reducerea
spaţiului de memorie necesar înregistrării blocajelor. În schimb
folosind unităţi de acces de mici dimensiuni creşte gradul de
concurenţă suportat de sistem deoarece vor putea fi executate în
paralel un număr mai mare de tranzacţii care operează în unităţi de
acces diferite. În practică dimensiunea potrivită a unităţilor de acces
este dată de extinderea operaţiilor efectuate de tranzacţiile cu cea mai
mare frecvenţă. Astfel dacă tranzacţia tipică presupune efectuarea
unor operaţii de cuplare, atunci unitatea de acces va fi relaţia.
Dacă însă majoritatea tranzacţiilor efectuează operaţii asupra
unor tuple individuale, atunci va fi convenabil să se aleagă tupla ca
unitate de acces.
241
8.3. Serializabilitate: definire şi exemplu
Serializabilitatea este o problemă de concurenţă care prezintă
un interes deosebit în cazul bazelor de date. Aşa cum s-a constatat şi
din exemplele de până acum, prin execuţia concurentă a mai multor
tranzacţii se pot obţine rezultate diferite faţă de situaţia în care
fiecare tranzacţie este executată independent. Dar rezultatele
execuţiilor concurente pot să difere şi între ele şi sunt în general
inconsistente. În mod firesc se consideră corect rezultatul obţinut
prin execuţia independentă a tranzacţiilor. Numim o astfel de
execuţie execuţie serială. Execuţia concurentă a mai multor
tranzacţii este considerată corectă dacă şi numai dacă efectul acesteia
este echivalent cu cel al unei execuţii seriale a aceloraşi tranzactii.
Definiţii
Numim planificare a unui set de tranzacţii o ordine de
execuţie a paşilor elementari (LOCK, READ, WRITE, etc.) ai
tranzacţiilor setului. Ordonarea se referă la paşi din tranzacţii
diferite, ordinea relativă a paşilor aceleiaşi tranzacţii nefiind afectată.
O planificare se numeşte serială dacă toţi paşii oricărei tranzacţii
apar în poziţii consecutive ale planificării. O asemenea planificare
determină o execuţie serială, fâră interferenţe a tranzacţiilor.
O planificare se numeşte serializabilă dacă şi numai dacă
efectul ei este echivalent cu cel al unei planificări seriale.
Exemplu:
Fie două tranzacţii T1 şi T2 definite prin secvenţele:
T1: READ A; A=A-10; WRITE A; READ B; B=B+10;
WRITE B;
T2: READ B; B=B-20; WRITE B; READ C; C=C+20; WRITE
C;
Orice planificare serială a tranzacţiilor T1 şi T2 are proprietatea
că suma A+B+C rămâne nemodificată.
În figurile 8.2 şi 8.3 sunt prezentate două planificări diferite ale
tranzacţiilor T1 şi T2: una serializabilă şi alta neserializabilă.
242
T1 T2
243
T1 T2
244
8.4. Formalizarea conceptului de serializabilitate.
Planificarea operaţiilor concurente în SGBDD
1. T i 1,n i ;
T i 1,n i ;
2.
3. Pentru oricare două operaţii conflictuale
Oij , Ok1 T
,
avem fie
Oij T Ok 1
fie
Ok1 T Oij
.
245
Prima condiţie defineşte domeniul planificării ca fiind
reuniunea domeniilor tranzacţiilor individuale. Condiţia a doua arată
că relaţia de ordine asociată planificării este un superset al relaţiilor
de ordine ale tuturor tranzactiilor individuale. În sfâârşit, condiţia a
treia precizează faptul că între oricare două operaţii conflictuale din
domeniul planificării trebuie să existe o ordine relativă bine definită.
Exemplu:
Fie tranzacţiile:
T1: READ(x) T2: READ(x)
x<-x+1 x<-x+1
WRITE(x) WRITE(x)
COMMIT COMMIT
R ,W , C , R ,W , C ,
T 1 1 1 2 2 2 T
,
{ (R1,R2),(R1,W1),(R1,C1),(R1,W2),(R1,C2),
(R2,W1),(R2,C1),(R2,W2),(R2,C2),
(W1,C1),(W1,W2),(W1,C2),(C1,W2),(C1,C2),(W2,C2)}.
(Pentru simplificarea notaţiei s-a omis specificarea explicită a
argumentului operaţiilor, acesta rezultând fără echivoc din contextul
exemplului prezentat.)
Graful aciclic corespunzător acestei planificări este prezentat
în figura 2.3. (de menţionat faptul că s-au omis din reprezentare
arcele corespunzătoare acelor relaţii care sunt implicate prin
tranzitivitate de către celelalte relaţii.)
246
Ca şi în cazul tranzacţiilor individuale este uzuală folosirea
unei convenţii care simplifică notaţia unei planificări. Conform
acestei convenţii, o planificare este reprezentată sub forma unei liste
l. '
;
ei , e j ' ei ' e j
2. , avem: dacă şi numai dacă
ei e j
;
ei ' e j e j ei ej '
3. , dacă şi , atunci .
Primele două condiţii de mai sus definesc prefixul P' ca fiind o
din '
, toţi predecesorii săi din trebuie să fie incluşi şi în
'
.
Conceptul de planificare, definit ca un prefix al unei planificări
complete, oferă posibilitatea de a raţiona asupra planificărilor
incomplete. Acest lucru este util din punctul de vedere al teoriei
serializabilită ii deoarece permite luarea în considerare doar a
operaţiilor conflictuale din cadrul tranzacţiilor, neglijând restul
247
operaţiilor care oricum nu au efect asupra serializabilităţii. De
asemenea, capacitatea de a trata planificări incomplete devine
absolut necesară atunci câând se ia în considerare posibilitatea
apariţiei defectelor în sistem.
Exemplu:
Fie tranzacţiile:
T1: READ(x) T2: WRITE(x) T3: READ(x)
WRITE(x) WRITE(y) READ(y)
COMMIT READ(z) READ(z)
COMMIT COMMIT
c
O posibilă planificare completă, P , a celor trei tranzacţii este
dată prin graful aciclic din figura 2.4: O posibilă planificare P, prefix
c
al lui P , este dată prin graful aciclic din figura 2.5.
Aşa cum s-a arătat, o planificare P este serială dacă paşii
tranzacţiilor componente nu sunt intercalaţi. O planificare serială
menţine consistenţa bazei de date deoarece, conform proprietăţii de
consistenţă a tranzacţiilor, orice tranzacţie executată independent pe
o bază de date consistentă va produce o bază de date tot consistentă.
Deci o planificare serială în care tranzacţiile sunt executate pe rând,
una cââte una, va lăsa baza de date într-o stare consistentă dacă,
bineînţeles, starea initială a bazei de date a fost una consistentă.
Pornind de la relaţia de precedenţă, introdusă prin relaţia de
ordine parţială, este posibilă definirea echivalenţei planificărilor pe
baza efectelor acestora asupra bazei de date. Intuitiv, două planificări
P1 şi P2, definite peste acelaşi set de tranzacţii T, sunt echivalente
dacă au acelaşi efect asupra bazei de date. Formal, două planificări
P1 şi P2, definite peste acelaşi set de tranzacţii T, sunt echivalente
dacă pentru orice pereche de operaţii planifcare a conflictuale Oij şi
Ok1 (i≠k), avem:
Oij 1 Ok1 Oij 2 Ok1
,
248
Această formă de echivalenţă poartă numele de echivalenţă la
conflict fiind definită pe baza ordinii relative de execuţie a
operaţiilor conftictuale.
Exemplu:
Fie tranzacţiile T1, T2 şi T3 din exemplul precedent, atunci
planificările P1, şi P2, definite prin:
P1={W2(x),W2(y), R2(z),C2,R1(x),
W1(x),C1,R3(x),R3(y),R3(z),C3),
P2={W2(x),R1(x),W1(x),R2(x),C2,W2(y),R3(v),R2(z),C1,R3(z),C3)
sunt echivalente la conflict, deoarece pentru fiecare pereche de
operaţii conflictuale ordinea relativă de execuţie este aceeaşi în
ambele planificări.
Într-adevăr perechile de operaţii conflictuale sunt:
(W2(x), R1(x), (W2(y), R3(y)) , (W2(x), W1(x)), (R1(x),
W2(x))
iar ordinea relativă de execuţie este cea care apare în aceste
perechi, atât pentru planificarea P1 cât şi pentru P2. Echivalenţa la
conflict permite definirea formală a conceptului de serializabilitate.
O planificare P este serializabilă dacă şi numai dacă este
echivalentă la conflict cu o planificare serială. Aceasta formă de
serializabilitate poarta numele de serializabilitate bazată pe
conflict. Planificarea P1, din exemplul de mai sus este serială
deoarece constă din execuţia pe rând a tranzacţiilor componente, în
ordinea: T2 T1 T3.
Planificarea P2 este serializabilă datorită faptului că este
echivalentă la conflict cu planificarea P1. Conceptul de
serializabilitate permite definirea mai clară a obiectivelor urmărite
prin controlul concurenţei. Funcţia principală a oricărui mecanism
de control al concurenţei este de a genera o planificare serializabilă
pentru execuţia tranzacţiilor active din sistem. Problema principală
care se pune în domeniul controlului concurenţei este de a dezvolta
algoritmi care garantează faptul că orice planificare pe care o produc
este serializabilă.
249
Principalii algoritmi de control al concurenţei cunoscuţi se
clasifică în
· algoritmi de control al concurenţei prin blocare,
care se bazează pe accesul mutual exclusiv al
tranzacţiilor la datele partajate; excluderea mutuală
este asigurată prin primitive de tip LOCK şi
UNLOCK.
· algoritmi de control al concurenţei prin mărci de
timp , care încearcă să ordoneze execuţia tranzacţiilor
conform unui set de reguli; ordonarea tranzacţiilor este
asigurată prin mărci de timp asociate atât tranzacţiilor,
cât şi datelor pe care le accesează.
250
8.5 Algoritmi de control al concurenţei şi testare a
seriabilităţii
251
Din punctul de vedere al algoritmilor de control al
concurenţei prin blocare prezintă interes acei paşi din cadrul
tranzacţiilor care corespund operaţiilor de tip blocare şi deblocare. În
consecinţă tranzacţiile vor fi privite ca secvenţe de operaţii LOCK şi
UNLOCK. De asemenea presupunem că sunt respectate următoarele
reguli:
252
T1 T2
LOCK A;
LOCK B;
LOCK A;
UNLOCK A;
UNLOCK A;
UNLOCK B;
Această planificare este ilegală deoarece este unposibil ca
tranzacţia T2 să obţină blocarea valorii A atâta timp cât aceasta este
blocată de către tranzacţia T1, deci operaţia LOCK A din T2 nu
poate fi situată în timp între operaţiile LOCK A şi UNLOCK A din
T1. De asemenea T2 nu poate debloca valoarea A atâta timp cât
aceasta este blocată de către T1.
253
Algoritmul de testare a serializabilităţii se poate expriina
ca o problemă de găsire a ciclurilor dintr-un graf orientat numit
graful de precedenţă.
Fiind dată o planificare P a unei mulţimi de tranzacţii M se
construieşte graful de precedenţă asociat astfel:
1. Nodurile grafului sunt tranzacţiile din M.
2. Arcul orientat de la nodul Ti la nodul Tj, TiTj, are
semnificaţia că există o unitate de acces pentru care tranzacţia Ti
obţine blocarea (pereche LOCK-UNLOCK) înaintea tranzacţiei Tj,
iar între Ti şi Tj nici o altă tranzacţie nu blochează această
unitate de acces.
T1 T2 T3
LOCK A;
LOCK B;
UNLOCK B;
LOCK B;
UNLOCK A;
LOCK A;
UNLOCK A;
LOCK A;
UNLOCK B;
UNLOCK A;
255
planificare serială echivalentă ar trebui să execute tranzacţia T1,
înainte de T2, dar şi pe T2 înainte de T1 ceea ce este imposibil.
T1, T2, T3
LOCK A;
UNLOCK A;
LOCK A;
UNLOCK A;
LOCK B;
UNLOCK B;
LOCK B;
UNLOCK B;
256
Algoritmul de testare a serializabilităţii bazat pe detectarea
ciclurilor din graful de precedenţă poate fi folosit, cel puţin teoretic,
pentru elaborarea unui mecanism general de control a concurenţei.
Aceasta ar presupune construirea dinamică a grafului de precedenţă
şi verificarea la fiecare pas a ciclicităţii sale. În cazul apariţiei unui
ciclu ar urma abortarea a cel puţin uneia dintre tranzacţiile vinovate
de apariţia ciclului în graful de precedenţă. Metoda aceasta s-a
dovedit a fi însă neviabilă în practică datorită costurilor mari pe care
le implică. Ori nu este permis ca metoda de control a concurenţei să
implice costuri suplimentare care să depăşească câştigul obţinut
datorită execuţiei concurente. Execuţia concurentă a tranzacţiilor,
împreună cu costurile suplimentare implicate de controlul
concurenţei, trebuie să fie, în orice situaţie, cel puţin la fel de
eficientă ca şi execuţia serială a aceloraşi tranzacţii.
Din acest motiv este preferată o altă abordare a problemei
controlului concurenţei şi anume aceea de a impune asupra
tranzacţiilor suficiente restricţii astfel încât nici o planificare posibilă
a acestora să nu violeze condiţia de serializabilitate. Aceste restricţii,
numite protocoale, reduc nivelul de concurenţă al sistemului, prin
faptul că admit doar un subset al planificărilor serializabile posibile
pentru o mulţime dată de tranzacţii.
257
urmează apoi operaţiile propriu-zise specifice fiecărei tranzacţii, iar
în final se execută operaţiile de deblocare.
Distingem deci două faze de execuţie care sunt comune tuturor
tranzactiilor din această categorie:
1. faza de acaparare a tuturor resurselor
necesare (blocările)
2. şi faza de eliberare a acestora
(deblocările).
Aceste tranzacţii poartă numele de tranzacţii în două faze. Se
poate enunţa următoarea teoremă:
TEOREMA 1 Orice planificare legală a unei mulţimi de
tranzactii în două faze este serializabilă.
Demonstratie: Prin reducere la absurd. Presupunem că există o
planificare a unui set de tranzacţii în două faze care nu este
serializabilă. Atunci graful de precedenţă corespunzător acestei
planificări conţine un ciclu:
TiTjTk...Ti.
Înseamnă că există o operaţie de blocare în Tj care este situată
după o operaţie de deblocare din Ti; în Tk există o blocare care
urmează unei deblocări din Tj ş.a.m.d. În final rezultă că Ti conţine o
operaţie de blocare situată după o operaţie de deblocare din cadrul ei,
ceea ce contrazice ipoteza că Ti este în două faze.
258
şi următoarea planificare:
T1 T2
_____________________________________
LOCK A;
UNLOCK A;
LOCK A;
LOCK B;
UNLOCK A;
UNLOCK B;
LOCK B;
UNLOCK B;
259
8.6. Tranzacţii cu accese de tip read-only şi read-
write
În cele de mai sus s-a considerat în mod implicit că o
tranzacţie care blochează o unitate de acces modifcă una sau mai
multe valori din cadrul acestei unităţi, cu alte cuvinte s-a considerat
că accesele sunt de tipul read-write. Înpractică însă, sunt foarte
frecvente tranzacţiile care fac acces la date doar pentru consultarea
acestora; este cazul tuturor tranzacţiilor care compun interogările
adresate bazelor de date. Despre aceste tranzacţii se ştie dinainte că
vor accesa datele doar în citire fâră a face modificări asupra lor. Dar
pentru efectuarea operaţiilor de citire nu este obligatorie excluderea
mutuală, aceeaşi dată poate fi citită de către mai multe tranzactii în
mod concurent fără ca acestea să se influenţeze reciproc, ordinea
citirilor find arbitrară. Este, deci, util să se facă distincţie între
accesele numai pentru citire (read-only) şi cele pentru citire-scriere
(read-write), deoarece astfel se pot formula protocoale care permit
un grad mai ridicat de concurenţă a operaţiilor. Într-un sistem care
face această distineţie se folosesc două primitive de blocare:
260
primitiva LOCK discutată în paragrafele precedente. Dacă o
tranzacţie blochează în citire-scriere o unitate de acces, atunci nici o
altă tranzacţie nu poate obţine blocarea acestei unităţi nici pentru
citire, nici pentru citire-scriere. Atât blocările pentru citire, cât şi
cele pentru citire-scriere sunt anulate prin executarea primitivei
UNLOCK.
O planificare a paşilor unei mulţimi de tranzacţii care conţin
primitiveRLOCK şi WLOCK este legală, dacă sunt respectate
următoarele reguli:
1. Orice unitate de acces blocată de o tranzactie trebuie să
fie deblocată de aceeaşi tranzacţie înainte de terminarea acesteia.
2. Nici o tranzacţie nu încearcă deblocarea unei unităţi de
acces pe care nu o blochează în citire sau citire-scriere.
3. Nici o tranzacţie nu încearcă blocarea pentru citire a
unei unităţi de acces pe care o blochează (fie în citire, fie în citire-
scriere).
4. Nici o tranzacţie nu încearcă blocarea pentru citire-
scriere a une unităţi de acces pe care o blochează în citire-scriere.
5. O tranzacţie poate cere şi obţine blocarea pentru citire-
scriere a unei unităţi de acces pe care o blochează deja în citire.
Această situaţie este posibilă deoarece blocarea în citire-scriere
este mai restrictivă decât blocarea doar pentru citire.
261
Algoritmul de testare a serializabilităţii pentru o planificare a
unui set de tranzacţii care efectuează asupra datelor accese de tip
read-only sau read-write este asemănător cu algoritmul prezentat
pentru cazul acceselor de tip read-write. Deosebirea provine din
faptul că, spre deosebire de accesele de tip read-write a căror ordine
de execuţie nu este indiferentă, operaţiile de tip read-only sunt
permutabile, deci ordinea lor de execuţie nu influenţează rezultatele.
262
Capitolul IX. PROCESAREA
TRANZACTIILOR ÎN PL/SQL
263
UPDATE accounts SET balance = balance - transfer
WHERE account_id = 7715;
UPDATE accounts SET balance = balance + transfer
WHERE account_id = 7720;
COMMIT COMMENT 'Transfer From 7715 to 7720'
END;
264
9.2 Folosirea comenzii ROLLBACK in PL/SQL
Comanda ROLLBACK termina tranzactia curenta si
anuleaza toate schimbarile facute in timpul tranzactiei. Daca s-a sters
din greseala o inregistrare din tabela, aceasta oparatie anuleaza
efectul stergerii. Daca nu se doreste terminarea unei tranzactii in
momentul in care apare o eroare, operatia rollback permite actiunea
de anulare.
DECLARE
emp_id NUMBER(6);
emp_lastname VARCHAR2(25);
emp_salary NUMBER(8,2);
emp_jobid VARCHAR2(10);
BEGIN
SELECT employee_id, last_name, salary, job_id INTO
emp_id, emp_lastname,emp_salary, emp_jobid FROM
employees WHERE employee_id = 120;
265
INSERT INTO emp_name VALUES (emp_id,
emp_lastname);
INSERT INTO emp_sal VALUES (emp_id, emp_salary);
INSERT INTO emp_job VALUES (emp_id, emp_jobid);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE('Inserts have been rolled
back');
END;
266
9.3 Fosirea comenzii SAVEPOINT in PL/SQL
SAVEPOINT denumeste si marcheaza punctul curent din
procesarea tranzactiei. Punctele de salvare permit sa nu se anuleaza
efectele intregii tranzactii ci numai o parte din ele sa fie anulate.
Numarul de puncte de salavare dintr-o sesiune este nelimitat.
DECLARE
emp_id employees.employee_id%TYPE;
emp_lastname employees.last_name%TYPE;
emp_salary employees.salary%TYPE;
BEGIN
SELECT employee_id, last_name, salary INTO emp_id,
emp_lastname,
emp_salary FROM employees WHERE employee_id = 120;
UPDATE emp_name SET salary = salary * 1.1 WHERE
employee_id = emp_id;
DELETE FROM emp_name WHERE employee_id = 130;
SAVEPOINT do_insert;
INSERT INTO emp_name VALUES (emp_id, emp_lastname,
emp_salary);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
ROLLBACK TO do_insert;
DBMS_OUTPUT.PUT_LINE('Insert has been rolled
back');
END;
DECLARE
emp_id employees.employee_id%TYPE;
emp_lastname employees.last_name%TYPE;
emp_salary employees.salary%TYPE;
BEGIN
SELECT employee_id, last_name, salary INTO emp_id,
emp_lastname,
emp_salary FROM employees WHERE employee_id = 120;
SAVEPOINT my_savepoint;
UPDATE emp_name SET salary = salary * 1.1 WHERE
employee_id = emp_id;
DELETE FROM emp_name WHERE employee_id = 130;
SAVEPOINT my_savepoint; -- move my_savepoint to
current poin
INSERT INTO emp_name VALUES (emp_id, emp_lastname,
emp_salary);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
ROLLBACK TO my_savepoint;
DBMS_OUTPUT.PUT_LINE('Transaction rolled back.');
END;
268
9.4 Setarea proprietăţilor tranzacţiilor cu comanda
SET TRANSACTION
DECLARE
daily_order_total NUMBER(12,2);
weekly_order_total NUMBER(12,2);
monthly_order_total NUMBER(12,2);
BEGIN
COMMIT; -- ends previous transaction
SET TRANSACTION READ ONLY NAME 'Calculate Order
Totals';
SELECT SUM (order_total) INTO daily_order_total FROM
orders
WHERE order_date = SYSDATE;
SELECT SUM (order_total) INTO weekly_order_total FROM
orders
WHERE order_date = SYSDATE - 7;
SELECT SUM (order_total) INTO monthly_order_total
FROM orders
WHERE order_date = SYSDATE - 30;
COMMIT; -- ends read-only transaction
END;
269
Daca o tranzactie este setata READ ONLY, toate interogarile
din tranzactie vor vedea numai schimbarile efectuate inainte de a
incepe tranzactia. Folosirea unei tranzactii READ ONLY nu
afecteaza alti utilizatori sau alte tranzactii.
270
9.5 Blocări explicite
Implicit, Oracle blocheaza structurile de date - o
caracteristica importanta pentru Oracle.
DECLARE
CURSOR c1 IS SELECT employee_id, salary FROM employees
WHERE job_id = 'SA_REP' AND commission_pct > .10
FOR UPDATE NOWAIT;
271
trebuie asigurat că nu se efectuează modificări asupra rândului de
către alt utilizator înainte de update.
DECLARE
CURSOR c1 IS SELECT last_name, department_name FROM
employees, departments
WHERE employees.department_id = departments.department_id
AND job_id = 'SA_MAN'
FOR UPDATE OF salary;
DECLARE
my_emp_id NUMBER(6);
my_job_id VARCHAR2(10);
my_sal NUMBER(8,2);
CURSOR c1 IS SELECT employee_id, job_id, salary FROM
employees FOR UPDATE;
BEGIN
OPEN c1;
LOOP
272
FETCH c1 INTO my_emp_id, my_job_id, my_sal;
IF my_job_id = 'SA_REP' THEN
UPDATE employees SET salary = salary * 1.02 WHERE
CURRENT OF c1;
END IF;
EXIT WHEN c1%NOTFOUND;
END LOOP;
END;
Sesiunea I
Sesiunea II
Sesiunea I
SQL> SELECT Salary
FROM employees
WHERE employee_id = 100
FOR UPDATE OF salary;
273
SQL> rollback;
Rollback complete.
Sesiunea II
SQL> update employees
set salary=20000
where employee_id=100;
274
BIBLIOGRAFIE
275
14. Stepan A., Petov G. şi V. Iordan, Fundamentele Proiectării şi
Realizării Sistemelor Informatice, Ed. Mirton, Timişoara,
1995.
276
Anexă: Funcţii predefinite
în PL/SQL
a. Funcţii pentru date:
277
TRUNC(d[,’fmt’])- returnează data d trunchiată la
formatul specificat prin fmt . Dacă fmt e omis, data d e
trunchiată la cea mai apropiată valoare.
278
c. Fucţii numerice
279
280