Sunteți pe pagina 1din 82

Programarea n SQL ANSI-92

cu aplicaii pentru MSJetSQL 4


Christian Manca

CUPRINS
1 Introducere ................................................................................................... 4
1.1
1.2

LIMBAJUL MSJETSQL ....................................................................................... 4


BAZA DE DATE DOMNITORI ............................................................................ 5

2 Sublimbajul de definiie a datelor ......................................... 5


2.1
INSTRUCIUNILE CREATE TABLE I ALTER TABLE ................................... 9
2.1.1
Instruciunea CREATE TABLE ................................................................ 9
2.1.2
Clauza CONSTRAINT ............................................................................ 11
2.1.3
Instruciunea ALTER TABLE ................................................................. 14
2.2
INSTRUCIUNEA CREATE INDEX ................................................................. 15
2.3
INSTRUCIUNEA DROP ................................................................................... 16
2.4
INSTRUCIUNILE CREATE USER I CREATE GROUP ................................ 17
2.5
INSTRUCIUNEA ADD USER .......................................................................... 17
2.6
INSTRUCIUNILE ALTER USER I ALTER DATABASE .............................. 18
2.7
INSTRUCIUNEA GRANT ................................................................................ 19
2.8
INSTRUCIUNEA REVOKE.............................................................................. 20
2.9
INSTRUCIUNILE DROP USER I DROP GROUP .......................................... 21

3 Sublimbajul de manipulare a datelor ............................... 21


3.1
SUBLIMBAJUL DE INTEROGARE ........................................................................ 22
3.1.1
Instruciunea SELECT ............................................................................ 22
3.1.1.1 Predicatele ALL, DISTINCT, DISTINCTROW i TOP .................... 23
3.1.1.2 Operatorii produs cartezian, INNER, LEFT i RIGHT JOIN ............ 27
3.1.1.3 Clauza WHERE .................................................................................. 29
3.1.1.4 Operatorii de comparaie LIKE, IN i BETWEEN...AND ................ 33
3.1.1.4.1 Operatorul LIKE ........................................................................... 33
3.1.1.4.2 Operatorul IN ................................................................................ 34
3.1.1.4.3 Operatorul BETWEEN...AND ..................................................... 35
3.1.1.5 Funciile de agregare .......................................................................... 36
3.1.1.5.1 Funcia Avg .................................................................................. 36
3.1.1.5.2 Funcia Count ............................................................................... 36
3.1.1.5.3 Funciile First i Last .................................................................... 37
3.1.1.5.4 Funciile Min i Max .................................................................... 39
3.1.1.5.5 Funciile StDev i StDevP ............................................................ 39
3.1.1.5.6 Funcia Sum .................................................................................. 40
3.1.1.5.7 Funciile Var i VarP .................................................................... 40
3.1.1.6 Clauza GROUP BY ............................................................................ 41
3.1.1.7 Clauza HAVING ................................................................................ 43
3.1.1.8 Clauza ORDER BY ............................................................................ 46
3.1.1.9 Declaraia PARAMETERS ................................................................ 47
3.1.1.10
Declaraia WITH OWNERACCESS OPTION .............................. 49
3.1.2
Subinterogri .......................................................................................... 50
3.1.3
Operatorul UNION ................................................................................. 56
3.1.4
Instruciunea TRANSFORM ................................................................... 60
3.2
SUBLIMBAJUL DE ACTUALIZARE ...................................................................... 62
3.2.1
Instruciunea SELECTINTO ............................................................... 62
3.2.2
Instruciunea INSERT INTO................................................................... 66
2

3.2.3
Instruciunea UPDATE .......................................................................... 67
3.2.4
Instruciunea DELETE ........................................................................... 69
3.3
PUNCTE DE VEDERE I PROCEDURI CATALOGATE ............................................. 70
3.3.1
Instruciunea CREATE VIEW................................................................. 70
3.3.2
Instruciunea CREATE PROCEDURE ................................................... 72
3.3.3
Instruciunea EXECUTE ........................................................................ 73
3.4
TRANZACII ..................................................................................................... 73
3.4.1
Instruciunile BEGIN, COMMIT i ROLLBACK ................................... 73

4 Diferene ntre MSJetSQL i ANSI-92 SQL ........... 77


5 Probleme propuse spre rezolvare......................................... 78
6 Comentarii i referine bibliografice ................................ 82
7 Lista referinelor bibliografice ............................................... 82

1 Introducere

Aceast carte, dedicat programrii n SQL ANSI-92 [0], este conceput ca dicionar frazeologic de MSJetSQL i folosit la laboratoarele cursului universitar de Proiectarea i interogarea conceptual a bazelor de date [1]. Prezentarea urmrete ndeaproape topica documentaiei Microsoft Corporation pentru MSJetSQL versiunea 4 [2],
motorul de baze de date (bd) ales pentru implementarea celor peste 125 de exemple de
programare SQL propuse, rezolvate i discutate n lucrare.
Seciunea 1.1 prezint pe scurt motivele alegerii MSJetSQL pentru ilustrarea
programrii n SQL. Seciunea 1.2 prezint structura i cele dou coninuturi propuse
pentru baza de date Domnitori, care sunt utilizate drept exemplu pe tot parcursul crii
(vezi i [1]). Capitolul 2 este dedicat sublimbajului de definiie a datelor, iar capitolul 3
celui de manipulare a datelor. Capitolul 4 evideniaz diferenele notabile ale MSJetSQL
fa de standardul SQL ANSI-92. Lucrarea se ncheie cu capitolele dedicate problemelor
propuse spre rezolvare, comentariilor i listei referinelor bibliografice.
Cartea este nsoit de o dischet coninnd bd Domnitori, precum i toate cele
aproape 130 de programe prezentate n carte.

1.1 Limbajul MSJetSQL


Exist foarte multe implementri comerciale ale limbajelor de interogare teoretice
studiate n [1]. Pentru exemplificare, am ales dintre acestea varianta SQL oferit de
SGBD Access 2002 [3] al corporaiei Microsoft din urmtoarele considerente:
Microsoft este compania dominant n lume pe piaa de software de sistem
Access este component a suitei Office (variantele Profesional i Premium),
alturi de i bine integrat cu Word, Excel, Powerpoint, Outlook, Publisher .a.,
de departe cea mai bine vndut i popular suit software existent, instalat
practic pe majoritatea PC-urilor din lume
Varianta Access 2002 (din Office XP) este cea mai nou i performant dintre
toate variantele existente ale acestui SGBD
Microsoft Jet SQL (MSJetSQL)1 este foarte aproape de standardele ANSI2 n
domeniu, ca i majoritatea celorlalte implementri relaionale celebre3, deci
trecerea la un alt sistem de gestiune a bd (SGBD) relaional, respectiv variant
de SQL este, din acest punct de vedere, extrem de uoar.
Motorul SGBD Access4 se numete Microsoft Jet5; versiunile curente 4.X incluse
n Office (XP, 2000) ale acestuia ofer un MSJetSQL (MSJSQL) n cea mai mare parte
compatibil att cu ANSI-92 SQL, ct i cu Microsoft Transact-SQL, limbajul
corespunztor serverului MS SQL Server.
MSJSQL este alctuit din dou sublimbaje: unul de definiie (LDD), iar cellalt de
manipulare a datelor (LMD). Dei teoria limbajelor de interogare nu se refer aproape
deloc la LDD, lucrarea trateaz succint ntreg MSJSQL, att din considerente de
completitudine a prezentrii, dar mai ales de utilitate.
De notat c MSJSQL este ncorporat n mai multe limbaje de programare de nivel
nalt, dintre care Visual Basic for Applications (VBA) [4] este att orientat obiect, ct i
bazat pe evenimente. Dei acesta nu face obiectul lucrrii de fa, pentru exemplificarea
aa-numitelor concepte MSJSQL avansate, care nu sunt suportate nici de interfaa inter1

De fapt, MSJetSQL este o component de sine stttoare, accesibil tuturor componentelor suitei Office.
Acronimul englez pentru Institutul Naional American de Standarde, un etalon mondial n domeniu.
3
Exemple: MS Visual FoxPro, Oracle, Sybase SQL Server, DB/2, NonStopSQL, CA-OpenIngres etc.
4
Dar nu numai: de exemplu, MS Jet este folosit i de Visual Basic, precum i de orice alt component a
Office care are nevoie de acces la o bd de tip .mdb, .adp etc.
5
De fapt, odat cu versiunea 2000, mai exist n Office un motor, cu adevrat de tip client/server, n
ntregime compatibil cu MS SQL Server i anume Microsoft Data Engine (MSDE).
2

activ Access i nici de modelul programatic obiectual DAO, ci numai de cel ADO i de
furnizorul Jet OLE DB6 (e.g. gestiunea grupurilor, utilizatorilor i privilegiilor acestora,
tabele derivate, proceduri catalogate, tranzacii etc.), dar i pentru a oferi o imagine ct
mai complet asupra programrii efective n Access, unele dintre exemplele ce urmeaz
fac apel i la VBA7.8
Conveniile notaionale folosite n prezentarea sintaxei MSJSQL sunt urmtoarele:
Cuvintele rezervate sunt scrise cu majuscule.
Variabilele sunt scrise cu litere mici, italice.
Clauzele opionale sunt nchise n paranteze drepte.
, semnific eventuala repetare de oricte ori a clauzei precedente.
Clauzele la alegere (doar una dintre) sunt nchise n acolade i separate ntre
ele prin |.
Prescurtrile i.e. nseamn adic, iar e.g. nseamn de exemplu.

1.2 Baza de date Domnitori


Fie bd referitoare la arborele genealogic al unei familii dinastice, cu urmtoarea
schem (vezi i [1]):
DOMNII (Domnitor, DeLa, La), cheie(La)
TATA (Tata, Copil)
PERSOANE (Nume, Moarte, Necropol)
MAMA (Mama, Copil)
Figurile 1 i 2 prezint cte un posibil coninut al acestei bd pentru familiile
Basarabilor, respectiv Muatinilor. Se observ c prima tabel are dou chei i cheia
strin Domnitor, iar n ultimele dou tabele fiecare atribut este cheie strin. Aceast
schem, evident, nu este optim din punct de vedere al proiectrii bd (vezi [1]), ns
servete excelent nelegerii n profunzime a paradigmei de programare n SQL.
Reamintim conveniile notaionale folosite (vezi i [1]):
cheile primare sunt subliniate
numele fiecrei relaii este urmat de:
nti, n paranteze, mulimea tuturor cheilor sale
apoi, mulimea dependenelor de incluziune (i.e. cheilor strine)
n fine, mulimea constrngerilor de existen simple (i.e. de tip funcie total
definit, adic valoare obligatorie sau, echivalent, valori NULL interzise).

2 Sublimbajul de definiie a datelor

LDD permite definirea i modificarea definiiilor a dou categorii de obiecte:


relaii (fundamentale sau derivate), constrngeri, fiiere index i proceduri catalogate i
utilizatori i drepturile lor de acces asupra obiectelor (de tipul celor din prima
categorie, dar nu numai).9
Din prima categorie fac parte ase instruciuni: CREATE TABLE, ALTER TABLE,
CREATE INDEX, CREATE VIEW, CREATE PROCEDURE i DROP.
6

DAO, ADO, ADOX i OLE DB sunt tehnologii de programare curent Microsoft (vezi [2], [3], ]4]).
Visual Basic for Applications (VBA), limbajul de programare al Access (derivat din Visual Basic), este
prezentat i el la laborator, att n sine, ct i cuplat cu MSJSQL ncorporat.
8
Windows, Access, MS SQL Server, Jet SQL, Transact-SQL, Office, Word, Excel, Powerpoint, Outlook,
Publisher, Visual FoxPro, Visual Basic i VBA sunt produse i mrci nregistrate al corporaiei Microsoft.
Sybase SQL Server aparine corporaiei Sybase, Oracle i PL/SQL corporaiei Oracle, DB/2 corporaiei
IBM, NonStopSQL corporaiei Tandem, iar CA-OpenIngres corporaiei Computer Associates.
9
De fapt, versiunile curente de MSJetSQL nu suport propriu-zis aceste instruciuni, dei ele figureaz n
documentaia aferent; grupurile, utilizatorii i privilegiile acestora sunt gestionate doar extern, de
utilitarul Wrkgadm.exe sau programatic, via ADOX i furnizorul Jet OLE DB. Prezentm totui i aceste
instruciuni ntru completitudine ANSI.
7

Din cea de-a doua, fac parte nou instruciuni: CREATE USER, CREATE GROUP,
ADD USER, ALTER USER, ALTER DATABASE, GRANT, REVOKE, DROP
USER i DROP GROUP.

PERSOANE (Nume)
Nume
Moarte Necropol
Alexandru Aldea
1436
Ana
Anca
Basarab I
1352
Cmpulung
Basarab epelu
Clara
Dan I
1386
Dan II
1431
Elena
Elisabeta
Laiot Basarab
1477
Maria
Maria Voichia
1511
Mtu tefan cel Mare
Mihail I
1420
Mihnea cel Ru
1509
Mircea
1447
Mircea cel Btrn
1418
Cozia
Mircea Ciobanul
1559
Neagoe Basarab
1521
Curtea Arge
Nicolae Alexandru
1364
Cmpulung
Radu cel Frumos
Radu cel Mare
1508
Dealu
Radu de la Afumai
1529
Curtea Arge
Radu I
1384
Radu II Pleuvul
1427
Radu Paisie
Ruxandra
Stanca
1530
Curtea Arge
Teodosie
Vlad
Vlad Clugrul
1495
Vlad cel Tnr
1512
Vlad Dracul
1447
Vlad epe
1477
Snagov
Vlad Uzurpatorul
1396
Vladislav II
1456
Vladislav Vlaicu
1377
Curtea Arge
MAMA (Copil) Mama Nume, Copil Nume,
Mama
Mama
Copil
Clara
Ana
Clara
Anca
Elena
Vlad
Maria
Vladislav Vlaicu
Maria
Radu I
Maria
Elisabeta
Mtu tefan cel Mare Vlad epe
Mtu tefan cel Mare Radu cel Frumos
Mtu tefan cel Mare Mircea
Mtu tefan cel Mare Vlad Clugrul
- Dan II, Radu II Pleuvul, Laiot Basarab, Vlad Clugrul
au domnit, de fapt, de mai multe ori
- au mai domnit, ns extrem de scurt timp fiecare, Mircea
i Basarab II
- Elena, soia lui Vlad epe, a fost fiica lui Iancu de
Hunedoara i sora lui Matei Corvin
- Maria Voichia a fost soia lui tefan cel Mare
- Stanca a fost soia lui tefni, domn al Moldovei, fiu al
lui Bogdan III

DOMNII (DeLa, La) Domnitor Nume,


Domnitor, La
Domnitor
DeLa La
Basarab I
1310 1352
Nicolae Alexandru 1352 1364
Vladislav Vlaicu
1364 1377
Radu I
1377 1384
Dan I
1384 1386
Mircea cel Btrn 1386 1394
Vlad Uzurpatorul 1394 1396
Mircea cel Btrn 1396 1418
Mihail I
1418 1420
Dan II
1420 1424
Radu II Pleuvul
1424 1426
Dan II
1426 1431
Alexandru Aldea 1431 1436
Vlad Dracul
1436 1442
Vladislav II
1442 1443
Vlad Dracul
1443 1447
Vladislav II
1447 1456
Vlad epe
1456 1462
Radu cel Frumos 1462 1473
Laiot Basarab
1473 1476
Vlad epe
1476 1477
Basarab epelu
1477 1481
Vlad Clugrul
1481 1495
Radu cel Mare
1495 1508
TATA (Copil) Tata Nume, Copil Nume,
Tata
Tata
Copil
Basarab I
Nicolae Alexandru
Basarab epelu
Neagoe Basarab
Dan I
Dan II
Dan I
Vlad Uzurpatorul
Dan II
Vladislav II
Dan II
Laiot Basarab
Laiot Basarab
Basarab epelu
Mircea cel Btrn Mihail I
Mircea cel Btrn Radu II Pleuvul
Mircea cel Btrn Alexandru Aldea
Mircea cel Btrn Vlad Dracul
Neagoe Basarab
Teodosie
Neagoe Basarab
Stanca
Neagoe Basarab
Ruxandra
Nicolae Alexandru Vladislav Vlaicu
Nicolae Alexandru Radu I
Nicolae Alexandru Elisabeta
Nicolae Alexandru Ana
Nicolae Alexandru Anca
Radu cel Frumos Maria Voichia
Radu cel Mare
Radu de la Afumai
Radu cel Mare
Radu Paisie
Radu cel Mare
Mircea Ciobanul
Radu I
Dan I
Radu I
Mircea cel Btrn
Vlad Clugrul
Radu cel Mare
Vlad Clugrul
Vlad cel Tnr
Vlad Dracul
Vlad epe
Vlad Dracul
Radu cel Frumos
Vlad Dracul
Mircea
Vlad Dracul
Vlad Clugrul
Vlad epe
Mihnea cel Ru
Vlad epe
Vlad

Figura 1 Baza de date Domnitori i un coninut al ei pentru nceputul dinastiei Basarabilor

DOMNII (DeLa, La) Domnitor Nume,


Domnitor, La
Domnitor
DeLa La
Bogdan I
1363 1365
Lacu
1365 1374
Petru Muat
1374 1391
Roman I
1391 1394
tefan I
1394 1399
Iuga Vod
1399 1400
Alexandru cel Bun 1400 1432
Ilia
1432 1433
tefan II
1433 1435
Ilia
1435 1442
tefan II
1442 1447
Roman II
1447 1448
Petru II
1448 1449
Bogdan II
1449 1451
Petru Aron
1451 1452
Alexndrel
1452 1455
Petru Aron
1455 1457
tefan cel Mare
1457 1504
TATA (Copil) Tata Nume, Copil Nume,
Tata
Tata
Copil
Alexandru cel Bun Ilia
Alexandru cel Bun tefan II
Alexandru cel Bun Bogdan II
Alexandru cel Bun Mtu tefan cel Mare
Alexandru cel Bun Petru Aron
Alexandru cel Bun Petru II
Bogdan I
Lacu
Bogdan I
Margareta Muata
Bogdan II
tefan cel Mare
Ilia
Roman II
Ilia
Alexndrel
Roman I
Alexandru cel Bun
Roman I
Bogdan
tefan cel Mare
Alexandru
tefan cel Mare
Elena
tefan cel Mare
Petru Ptracu
tefan cel Mare
Ilie
tefan cel Mare
Bogdnel
tefan cel Mare
Bogdan III
tefan cel Mare
Maria
tefan cel Mare
Petru Rare
- Ilia, tefan II, Alexndrel i Petru Aron au
domnit, de fapt, de mai multe ori
- Ilia i tefan II au domnit mpreun ntre 14361442, primul n jumtatea nordic, al doilea n
cea sudic, tefan II fiind considerat vasal al lui
Ilia
- numele surorii lui Petru Muat care se
presupune c era mama domnilor tefan I i Iuga
Vod nu ne este cunoscut
- Mtua lui tefan cel Mare (al crei nume nu ne
este cunoscut) a fost mama lui Vlad epe
- Maria Voichia, ultima soie a lui tefan cel
Mare, a fost fiica domnului muntean Radu cel
Frumos
- Elena, fiica lui tefan cel Mare, s-a cstorit n
1483 cu Ivan cel Tnr, fiul Marelui Cneaz al
Moscovei Ivan III

PERSOANE (Nume)
Nume
Moarte Necropol
Alexandru
1496
Bistria
Alexandru cel Bun
1432
Bistria
Alexndrel
Ana Neaca
Bistria
Anastasia
Rdui
Bogdan
1407
Rdui
Bogdan I
1365
Rdui
Bogdan II
1451
Rdui
Bogdan III
1517
Putna
Bogdnel
1477
Putna
Elena
Evdochia
1467
Ilia
1445
Ilie
1472
Putna
Iuga Vod
1400
Lacu
1374
Rdui
Margareta Losoncz
1410
Baia
Margareta Muata
1393
Siret
Maria
1518
Putna
Maria de Mangop
1477
Putna
Maria Oltea Basarab
Maria Rare din Hrlu
Maria Voichia
1511
Putna
Mariana
Mtu tefan cel Mare
Petru Aron
1470
Petru II
Petru Muat
1391
Rdui
Petru Ptracu
1480
Putna
Petru Rare
1546
Probota
Ringala Maria
Roman I
1394
Rdui
Roman II
Sor Petru Muat?
tefan cel Mare
1504
Putna
tefan I
1399
Rdui
tefan II
1447
MAMA (Copil) Mama Nume, Copil Nume,
Mama
Mama
Copil
Ana Neaca
Ilia
Anastasia
Alexandru cel Bun
Evdochia
Alexandru
Evdochia
Elena
Evdochia
Petru Ptracu
Margareta Muata
Petru Muat
Margareta Muata
Roman I
Margareta Muata
Sor Petru Muat?
Maria de Mangop
Ilie
Maria de Mangop
Bogdnel
Maria Oltea Basarab
tefan cel Mare
Maria Rare din Hrlu Petru Rare
Maria Voichia
Bogdan III
Maria Voichia
Maria
Mariana
Petru Aron
Sor Petru Muat?
tefan I
Sor Petru Muat?
Iuga Vod

Figura 2 Baza de date Domnitori i un coninut al ei pentru nceputul dinastiei Muatinilor

Deoarece instruciunile CREATE VIEW i CREATE PROCEDURE presupun


utilizarea i deci cunoaterea instruciunii LMD SELECT, ele nu sunt prezentate aici, ci
abia la sfritul capitolului 3.

2.1 Instruciunile CREATE TABLE i ALTER TABLE


Aceste instruciuni permit crearea i modificarea schemelor de relaii ntr-o bd.
2.1.1 Instruciunea CREATE TABLE
Sintaxa instruciunii de creare a unei noi scheme de relaie este urmtoarea:
CREATE [TEMPORARY] TABLE tabela (coloana1 tip [(dimensiune)] [NOT NULL]
[WITH COMPRESSION | WITH COMP] [index1] [, coloana2 tip [(dimensiune)]
[NOT NULL] [index2] [, ...]] [, CONSTRAINT indexmulticoloane [, ...]])
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
tabela
Numele schemei relaiei de creat (distinct n cadrul bd).
coloana1,
Numele atributelor schemei (cel puin unul!), toate distincte n
coloana2, ...
cadrul tabelei.
tip
Tipul de dat al valorilor atributului curent.
dimensiune
Lungimea maxim n caractere a valorilor (doar pentru tipurile de
dat TEXT/CHAR i BINARY).
index1, index2, ... O clauz de tip CONSTRAINT definind cte un index atomic (i.e.
format cu un singur atribut); vezi 2.1.2.
indexmulticoloane O clauz de tip CONSTRAINT definind cte un index compus (i.e.
format cu mai multe atribute); vezi 2.1.2.
Observaii:
1) Specificarea opiunii NOT NULL pentru un atribut interzice memorarea de
valori nule (NULL) pentru acel atribut.
2) Pentru clauza CONSTRAINT, vezi 2.1.2; pentru crearea de noi fiiere index sau
specificarea cheii primare a unei tabele existente se poate folosi i instruciunea
CREATE INDEX (vezi 2.2).
3) Modificatorul NOT NULL nu se poate specifica de mai multe ori asupra unui
acelai atribut.
4) Tabelele temporare (create cu modificatorul TEMPORARY) sunt vizibile doar
n sesiunea n care au fost create i sunt terse automat la terminarea acesteia. Pe
durata existenei lor ns, ele pot fi accesate de mai muli utilizatori.
5) Modificatorul WITH COMPRESSION se folosete numai cu tipurile de date
CHARACTER i MEMO (referite generic drept TEXT); el a fost adugat n
versiunea 2000 datorit introducerii codificrii UNICODE, care necesit cte doi
octei per caracter. Pentru a nu dubla inutil spaiul de memorare n cazul n care
nu se folosesc simultan caractere din mai multe seturi, fostele seturi de caractere
(numite Single-Byte Character Sets = SBCS) pot fi comprimate pe un singur
octet cu acest modificator. irurile de caractere memorate ca TEXT (sinonim:
MEMO) sau CHAR (echivalent cu TEXT(n), 1 n 255) sunt memorate n
UNICODE. Pentru economie de memorie ocupat se recomand comprimarea
automat a caracterelor SBCS. i atributele de tip MEMO pot memora datele n
acest format comprimat, existnd ns o limitare n acest sens: comprimarea se
face doar dac valoarea comprimat nu depete 4096 octei. Aceasta nseamn
i c este posibil ca, ntr-o aceeai coloan de tip MEMO, unele valori s fie
comprimate iar altele nu.
6) Crearea tabelei nu va reui dac ea contravine constrngerilor impuse bd!
9

7) MSJetSQL are predefinite urmtoarele 14 tipuri primare de date:


Tip de dat (sinonim) Dimensiune Descriere
BINARY
1 octet per
Poate memora orice tip de dat. Nu se face nici o
caracter
conversie a datelor: ele vor fi oferite exact aa
cum au fost memorate.
BIT
1 octet
Valori Yes sau No, respectiv 1 sau 0.
TINYINT (BYTE)
1 octet
ntregi ntre 0 i 255.
MONEY
8 octei
ntregi scalai ntre
(CURRENCY)
922,337,203,685,477.5808 i
922,337,203,685,477.5807.
DATETIME
8 octei
Date calendaristice i/sau momente de timp (ora,
(vezi DOUBLE)
minut, secund, fraciuni) ntre anii 100 i 9999.
UNIQUEIDENTIFIER 128 bii
Numere de identificare unic folosite n apelul
(GUID)
procedurilor la distan.
REAL (SINGLE)
4 octei
Reali simpl-precizie, n virgul mobil, ntre
3.402823E38 i 1.401298E-45 pentru valori
negative, sau 1.401298E-45 i 3.402823E38
pentru valori nenegative.
FLOAT (DOUBLE)
8 octei
Reali dubl-precizie, n virgul mobil, ntre
1.79769313486232E308 i
4.94065645841247E-324 pentru valori
negative, sau 4.94065645841247E-324 i
1.79769313486232E308 pentru valori
nenegative.
SMALLINT (INT)
2 octei
ntregi ntre 32,768 i 32,767.
INTEGER (LONG)
4 octei
ntregi ntre 2,147,483,648 i 2,147,483,647.
DECIMAL
17 octei
Reali exaci ntre 1028 - 1 i - 1028 - 1. Se pot
defini att precizia (1 - 28), ct i scala (0
precizie predefinit). Precizia i scala implicite
sunt 18, respectiv 0.
TEXT
2 octei per
iruri de caractere cu lungimea ntre 0 i
caracter (vezi maximum 2.14 gigaoctei.
observaia 5)
IMAGE (OLE
ct este
Obiecte OLE cu lungimea ntre 0 i maximum
OBJECT)
necesar
2.14 gigaoctei.
CHARACTER
2 octei per
iruri de caractere cu lungimea ntre 0 i
caracter (vezi maximum 255 caractere.
observaia 5)
8) Att valoarea iniial, ct i incrementul valorilor numerice generate automat de
sistem pot fi modificate cu ajutorul instruciunii ALTER TABLE (vezi 2.1.3).
Atenie ns la asemenea modificri dinamice: ele pot provoca generarea de valori
deja existente n tabel, ceea ce evident nu este permis n cazul cheilor!
9) Valoarea iniial i incrementul menionate mai sus pot fi folosite doar mpreun
cu tipurile de dat non-primitive, cu autonumrare COUNTER i IDENTITY (bazate pe LONG) i numai via furnizorul OLE DB Jet. ncepnd cu varianta 2000,
dac aceste valori sunt manipulate explicit i nu sunt ambele egale cu 1, atunci
MSJet nu mai iniializeaz automat valoarea iniial cu valoarea maxim coninut
de tabel; totui, dac ei nu sunt explicit manipulai sau chiar dac nu sunt ambii
egali cu 1, iniializarea automat este fcut atunci cnd bd este compactat.
10

10) Pentru a afla ultima valoare generat automat pentru o coloan incremental
trebuie folosit instruciunea (vezi 3.1.1): SELECT @@IDENTITY. De remarcat
c nu se poate specifica vreo tabel anume: se returneaz mereu ultima valoare
generat pentru ultima tabel pentru care s-a fcut acest lucru!
11) O parte din tipurile de date (nu doar primitive) admit sinonime.
12) Pentru echivalena cu i diferenele fa de tipurile de date standard ANSI vezi
capitolul 4.
Exemplul 1 Urmtoarea subrutin VBA creeaz tabela DOMNII 10:
Sub CreateTableDomnii()
Dim conDb As ADODB.Connection
On Error GoTo err_point
Set conDb = Application.CurrentProject.Connection
conDb.Execute "CREATE TABLE Domnii (Domnitor " _
& "CHAR(64), DeLa LONG PRIMARY KEY, La LONG " _
& "UNIQUE, CONSTRAINT KSD FOREIGN KEY " _
& "(Domnitor) REFERENCES Persoane " _
& "ON UPDATE CASCADE ON DELETE SET NULL);"
conDb.Close
Set conDb = Nothing
End Sub
Instruciunea urmtoare nu va reui s defineasc tabela CAPITALE (vezi
figura 13) deoarece n definiie este referit tabela necunoscut LOCALITI:
CREATE TABLE Capitale ([#C] COUNTER (0,2),
Capitala CHAR(32), An CHAR(4)
PRIMARY KEY, CONSTRAINT KSC FOREIGN KEY
(Capitala) REFERENCES Localiti);
Instruciunea urmtoare ns va genera aceast tabel:11
(Q001)CREATE TABLE Capitale ([#C] COUNTER (0,2),
Capitala CHAR(32), An CHAR(4)PRIMARY KEY);
De remarcat c structura sa include i cheia surogat #C, cu valori automat
generate incremental, pentru care s-au cerut valoarea iniial 0 i incrementul 2
(deci prima linie introdus va avea cod 0, a doua 2, a treia 4 etc.).
2.1.2 Clauza CONSTRAINT
Clauza CONSTRAINT permite definirea unui fiier index (deci i a unei chei) sau a
unei legturi ntre tabela curent i o alt tabel, i.e. a unei chei strine, adic a unei
dependene de incluziune (DIN). Un fiier index poate fi definit pentru un singur atribut
sau pentru un grup de atribute al unei relaii. Sintaxa pentru primul caz este urmtoarea:
CONSTRAINT nume {PRIMARY KEY | UNIQUE | NOT NULL |
REFERENCES tabelastrin [(coloanstrin1)]
[ON UPDATE {CASCADE | SET NULL}]
[ON DELETE {CASCADE | SET NULL}]}
Sintaxa pentru cel de-al doilea caz este urmtoarea:
10

n acest exemplu de programare, se observ c instruciunea SQL este transmis drept parametru de tip
ir de caractere unei metode (Execute) a obiectului de tip conexiune (la o bd) ADO numit conDb,
iniializat la bd curent. Caracterul _ de la sfritul unei linii indic continuarea acesteia pe linia
urmtoare; & este operatorul de concatenare iruri de caractere.
11
De notat c, dac un nume conine caractere speciale (precum #, spaiu, semne de punctuaie etc.),
conform conveniilor de numire ale MS Jet el trebuie nchis ntre paranteze ptrate. n mod standard,
instruciunile generate automat de sistem conin parantezele ptrate chiar dac acest lucru nu este
obligatoriu.

11

CONSTRAINT nume {PRIMARY KEY (primar1[, primar2 [, ...]]) |


UNIQUE (unic1[, unic2 [, ...]]) | NOT NULL (notnull1[, notnull2 [, ...]]) |
FOREIGN KEY [NO INDEX] (ref1[, ref2 [, ...]]) REFERENCES tabelastrin
[(coloanstrin1 [, coloanstrin2 [, ...]])]
[ON UPDATE {CASCADE | SET NULL}]
[ON DELETE {CASCADE | SET NULL}]}
Semnificaia variabilelor de mai sus este urmtoarea:
Variabil
Descriere
nume
Numele constrngerii.
primar1, 2, ... Numele atributelor ce alctuiesc cheia primar.
unic1, 2, ...
Numele atributelor injective (i.e. ale cror valori sunt unice).
notnull1, 2, ... Numele atributelor ce nu pot lua valori nule NULL.
ref1, 2, ...
Numele cheilor strine (i.e. referind atribute din alte relaii).
tabelastrin
Numele tabelei strine coninnd atributele coloanstrin.
coloanstrin1, Numele atributelor din tabelastrin specificate de ref1, ref2
coloanstrin2 (aceast clauz poate fi omis dac atributul referit este cheia
primar din tabelastrin).
Observaii:
1) CONSTRAINT poate specifica urmtoarele tipuri de constrngeri asupra
atributelor:
Injectivitate: folosind cuvntul rezervat UNIQUE, se specific chei (valori
unice). n cazul unui singur atribut, aceasta nseamn c nu pot exista doi sau
mai muli tupli avnd aceeai valoare pentru acel atribut; dac mai multe atribute
formeaz o cheie, atunci se pot repeta aceleai valori n diveri tupli pentru
fiecare din atributele componente, dar combinaia tuturor valorilor acestora
trebuie s fie mereu unic.
Cheie primar: folosind sintagma rezervat PRIMARY KEY, se desemneaz
unul sau mai multe atribute ca alctuind cheia primar a relaiei. Toate valorile
acesteia trebuie s fie unice, iar valoarea nul NULL este interzis n oricare
dintre atributele componente. O relaie nu poate avea dect o singur cheie
primar.
Chei strine: folosind sintagma rezervat FOREIGN KEY se desemneaz unul
sau mai multe atribute ca alctuind o cheie strin.12 Dac cheia primar a
tabelei strine este format din mai multe atribute, atunci trebuie folosit a doua
form a clauzei, pentru a lista toate atributele formnd cheia strin, tabela
strin i atributele sale referite, n aceeai ordine cu cele ale cheii strine. Dac
atributele referite formeaz cheia primar a tabelei referite, atunci ele nu mai
trebuie specificate explicit.13 Constrngerile de tip cheie strin pot defini i
aciunile particulare dorite n cazul modificrii coninutului tabelei referite, cu
ajutorul clauzelor ON UPDATE/DELETE, aa cum rezult din urmtorul
exemplu. n absena clauzelor ON DELETE/UPDATE, MSJet poate impune satisfacerea referinei integritilor (dac aceasta este explicit cerut ca proprietate
a legturii corespunztoare ntre cele dou tabele) prin interzicerea actualizrilor
care le-ar viola (fie ele inserri, modificri sau tergeri de tupli).
12

n Access, orice asemenea declaraie are ca efect memorarea relaiei aferente ntre tabele i a referinei
de integritate corespunztoare (i.e. a DIN; vezi opiunea de meniu \Tools\Relationships).
13
De remarcat c, din nou incredibil, motorul MSJet al Access nu impune aciclicitatea referinelor de
integritate (ceea ce nici mcar MS SQL Server nu face, de altfel!)! Astfel, de exemplu, dac atributul A al
tabelei TA refer atributul B al tabelei TB, care, la rndul su refer atributul A al TA, atunci nu se pot
introduce nici un fel de date n nici una din aceste dou tabele (n TA pentru c nu exist deja n TB, iar n
TB pentru c nu exist deja n TA)!

12

Exemplul 2 Declaraia de creare a tabelei de persoane este:


(Q002)CREATE TABLE Persoane (Nume CHAR(32)
PRIMARY KEY, Moarte INTEGER,
Necropol CHAR(32), Natere DATETIME);
Declaraia tabelei de tai definete i cele dou legturi ale acesteia cu
tabela de persoane, prin intermediul cheilor strine Tata i Copil:
(Q003)CREATE TABLE Tata (Tata CHAR(32), Copil
CHAR(32) PRIMARY KEY, CONSTRAINT KST FOREIGN KEY
(Tata) REFERENCES Persoane (Nume), CONSTRAINT
KSTC FOREIGN KEY (Copil) REFERENCES Persoane
(Nume) ON UPDATE CASCADE ON DELETE CASCADE);14
Clauza ON UPDATE CASCADE15 cere ca, dac se modific valoarea
numelui din tabela de persoane, modificarea s fie automat propagat n
tabela de tai (i.e. valorile corespunztoare ale cheii strine s fie nlocuite cu
noua valoare). Clauza ON DELETE CASCADE cere ca atunci cnd se terge
o persoan din tabela de persoane, s fie automat terse i toate apariiile sale
din tabela de tai (deci att cele referitoare la tatl, ct i cele privind copiii
persoanei), dac acestea exist n acel moment.
Fie acum urmtoarea definiie a tabelei de mame:
(Q004)CREATE TABLE Mama (Mama CHAR(32), Copil
CHAR(32) PRIMARY KEY, CONSTRAINT KSM FOREIGN KEY
(Mama) REFERENCES Persoane, CONSTRAINT KSMC
FOREIGN KEY (Copil) REFERENCES Persoane
ON UPDATE SET NULL ON DELETE SET NULL);
Clauza ON UPDATE SET NULL cere ca, dac se modific valoarea
numelui din tabela de persoane, valorile cheilor strine corespunztoare din
tabela de mame s fie modificate n valoarea nul NULL. Similar, clauza ON
DELETE SET NULL cere ca, la tergerea unei persoane din tabela de
persoane, valorile cheii strine corespunztoare din tabela de mame s fie
automat modificate n NULL.
2) Pentru a interzice crearea automat de fiiere index pentru cheile strine, se
folosete modificatorul NO INDEX. Acesta trebuie folosit doar n cazul n care
valorile cheii strine vor fi cel mai adesea dubluri, deoarece, n asemenea cazuri,
folosirea unui index nu mbuntete deloc viteza de execuie a programelor (iar
n cazul inserrii i tergerii frecvente de tupli, dimpotriv, viteza s-ar putea
chiar degrada simitor).
3) Numele constrngerilor unei bd trebuie s fie unice.
14

Deoarece Access deduce (din cheile tabelelor implicate) natura relaiilor binare (i nu permite nici
mcar ulterior modificarea lor explicit), n acest caz (i n orice asemenea cazuri similare) trebuie
dezactivat forarea automat a referinei integritilor (vezi opiunea de meniu \Tools\Relationships i
proprietile relaiei, care se pot obine cu un clic dreapta pe arcul corespunztor). n caz contrar, cum
relaia aceasta este eronat considerat injectiv i nu doar funcional (deoarece att Nume, ct i Copil
sunt chei!), nu se va putea introduce nici o persoan (neexistnd deja tatl ei), dar nici vreun tat
(neexistnd deja persoana reprezentnd copilul su)! Evident, DIN corespunztoare trebuie apoi impus
prin program! Vestea cea bun este c dac Nume nu este explicitat (vezi, de exemplu, declaraia
urmtoare pentru tabela de mame), aceast eroare nu se mai manifest (i.e. natura relaiei este corect
dedus ca fiind de tip 1- i nu 1-1)!! Vestea proast este, evident, aceea c pentru injectiviti
impunerea automat a DIN este greit tratat, deci e preferabil renunarea la ele prin consolidare ntr-o
unic tabel (conform principiului propagrii cheilor [1]).
15
Dei n documentaia MSJetSQL clauzele ON UPDATE i ON DELETE figureaz ca fiind suportate,
implementarea propriu-zis nu le accept! Ele sunt implementate exclusiv programatic, via ADOX i
furnizorul Jet OLE DB (e.g. vezi exemplul 1).

13

2.1.3 Instruciunea ALTER TABLE


Instruciunea ALTER TABLE permite modificarea schemei unei relaii existente.
Sintaxa ei este urmtoarea:
ALTER TABLE tabela {ADD {COLUMN coloana tip[(dimensiune)] [NOT NULL]
[CONSTRAINT index] |ALTER COLUMN coloana tip[(dimensiune)] |
CONSTRAINT indexmulticoloane} |
DROP {COLUMN coloana | CONSTRAINT numeindex} }
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
tabela
Numele tabelei de modificat.
coloana
Numele atributului de adugat la, ters sau modificat din tabela.
tip
Tipul de dat al valorilor coloana.
dimensiune
Lungimea maxim n caractere a valorilor (doar pentru tipurile de
dat TEXT i BINARY).
index
Indexul peste coloana; vezi clauza CONSTRAINT (2.1.2).
indexmulticoloane Definiia unui fiier index multiplu de adugat la schema tabela;
vezi clauza CONSTRAINT (2.1.2).
numeindex
Numele fiierului index multiplu de ters.
Observaii:
1) n funcie de opiunea aleas, instruciunea ALTER TABLE are unul dintre
urmtoarele efecte:
Adugare atribut: ADD COLUMN.
n plus, se pot desigur interzice valorile nule (cu modificatorul NOT NULL),
dup cum se poate i specifica construcia unui fiier index pentru atributul
adugat (cu clauza CONSTRAINT).
Modificarea tipului de dat al unui atribut existent: ALTER COLUMN.
Adugarea unui fiier index multiplu: ADD CONSTRAINT (vezi clauza
CONSTRAINT).
tergerea unui atribut existent: DROP COLUMN.
tergerea unui fiier index multiplu: DROP CONSTRAINT (vezi clauza
CONSTRAINT).
2) Nu se pot aduga sau terge mai mult de un atribut sau un index deodat.
3) Pentru a aduga un index la o tabel existent (atomic sau multiplu) se poate
folosi i instruciunea CREATE INDEX (vezi 2.2).
4) Pentru a terge un index (atomic sau multiplu) se poate folosi i instruciunea
DROP (vezi 2.3).
5) Restricia NOT NULL poate fi aplicat o singur dat asupra unui acelai
atribut.
6) Modificarea cerut nu va reui dac ea contravine constrngerilor impuse tabelei
sau dac coninutul curent al acesteia o violeaz!
Exemplul 3 Urmtoarea instruciune adaug atributul [#P], de tip cheie surogat cu autonumrare (incremental, de la i cu pas 1), la tabela PERSOANE:
(Q005)ALTER TABLE Persoane ADD COLUMN [#P] COUNTER;
Instruciunea urmtoare schimb tipul de dat al atributului La din tabela
DOMNII n INT (i.e. SHORT):
(Q006)ALTER TABLE Domnii ALTER COLUMN La SHORT;
Instruciunea urmtoare terge atributul Natere din tabela PERSOANE:
(Q007)ALTER TABLE Persoane DROP COLUMN Natere;

14

Instruciunea urmtoare nu va reui s tearg atributul Nume, deoarece


acesta este i cheie primar n PERSOANE i este i referit de atributele
Domnitor, Tata, Mama i Copil, care sunt chei strine ale celorlalte tabele:
(Q008)ALTER TABLE Persoane DROP COLUMN Nume;
Instruciunea urmtoare nu va reui s defineasc Tata drept cheie a tabelei
TATA, deoarece coninutul acesteia (indiferent c este vorba de cel din figura
1 sau 2) nu o permite (n ambele existnd duplicate pe aceast coloan,
corespunznd frailor i/sau surorilor):
(Q009)ALTER TABLE Tata ADD CONSTRAINT KTT UNIQUE
(Tata);

2.2 Instruciunea CREATE INDEX


Instruciunea CREATE INDEX creeaz un nou index pentru o tabel existent.
Sintaxa ei este urmtoarea:
CREATE [ UNIQUE ] INDEX index
ON tabela (coloana [ASC|DESC][, coloana [ASC|DESC], ...])
[WITH { PRIMARY | DISALLOW NULL | IGNORE NULL }]
Semnificaia variabilelor utilizate este urmtoarea:
Variabil Descriere
index
Numele indexului de creat.
tabela Numele tabelei pentru care se creeaz indexul.
coloana Numele atributului (pentru un index atomic) sau lista atributelor (pentru un
index multiplu) de indexat. Pentru fiiere index descresctoare, trebuie folosit
cuvntul rezervat DESC; n caz contrar, indexul se presupune a fi cresctor.
Observaii:
1) Pentru a interzice valori duble n atributul (respectiv atributele) indexat(e) se
folosete cuvntul rezervat UNIQUE.
2) Cu ajutorul clauzei opionale WITH se pot impune reguli de validare a datelor,
dup cum urmeaz:
Interzicerea valorilor nule n atributele indexate: DISALLOW NULL
Ignorarea valorilor nule din atributele indexate: IGNORE NULL; dac exist
valori nule, acestea nu vor fi incluse n index.
Definirea cheii primare: PRIMARY (ceea ce implic att interzicerea nulurilor,
ct i unicitatea, deci cuvntul rezervat UNIQUE este superfluu n acest caz).
3) Se poate crea cu aceast instruciune, folosind exact aceeai sintax i un
pseudo-index la o tabel legat (aparinnd, de exemplu, MS SQL Server) care
nu are definit acel index. Un asemenea pseudo-index este local i nu este nevoie
de drepturi de acces n acest sens la server, deoarece acesta nici nu va avea cunotin despre i deci nu va fi deloc afectat de pseudo-index. Ca atare, acest tip de
index este foarte folositor pentru cazul tabelelor legate deschise numai n citire.
4) Pentru a crea un index asupra unei tabele existente, se poate folosi i
instruciunea ALTER TABLE (vezi 2.1.3).
5) Dac tabela are deja definit cheia primar, nu trebuie folosit cuvntul rezervat
PRIMARY (n caz contrar rezultnd o eroare).
6) Crearea indexului nu va reui dac acesta contravine constrngerilor impuse
tabelei sau dac coninutul curent al acesteia l violeaz!

15

Exemplul 4 Urmtoarea subrutin VBA adaug un index unic n tabela TATA


pentru perechea de atribute TataCopil:16
Sub CreateIndexTata()
Dim conDb As ADODB.Connection
On Error GoTo err_point
Set conDb = Application.CurrentProject.Connection
dbs.Execute "CREATE UNIQUE INDEX Tata ON Tata " _
& "(Tata, Copil);"
conDb.Close
Set conDb = Nothing
End Sub
Instruciunea urmtoare nu va reui s defineasc un nou index cu numele
Tata, deoarece un asemenea index exist deja (creat fiind de subrutina de mai
sus CreateIndexTata):
(Q010)CREATE INDEX Tata ON Tata (Tata) WITH
DISALLOW NULL;
Instruciunea urmtoare nu va reui s defineasc un nou index unic (cu
numele UnicTata) i care s ignore valorile nule pentru acest atribut, deoarece
coninutul TATA (indiferent c este vorba de cel din figura 1 sau 2) nu o
permite (n ambele existnd duplicate pe aceast coloan, corespunznd
frailor i/sau surorilor):
(Q011)CREATE UNIQUE INDEX UnicTata ON Tata (Tata)
WITH IGNORE NULL;

2.3 Instruciunea DROP


Instruciunea DROP permite tergerea unei tabele fundamentale, derivate, unei proceduri catalogate sau unui index. Sintaxa ei este urmtoarea:
DROP {TABLE tabela|INDEX index ON tabela|PROCEDURE procedur|
VIEW view}
Semnificaia variabilelor utilizate este urmtoarea:
Variabil Descriere
tabela
Numele tabelei de ters sau din care se terge index.
procedur Numele procedurii catalogate de ters (doar programatic, via ADOX!).
view
Numele tabelei derivate de ters (doar programatic, via ADOX!).
index
Numele indexului de ters din tabela.
Observaii:
1) nainte de a putea fi tears (sau de i se putea terge un index) tabela tabela
trebuie s fie nchis.
2) Pentru a terge un index al unei tabele se poate folosi i instruciunea ALTER
TABLE (vezi 2.1.3).
3) tergerea nu va reui dac ea contravine constrngerilor impuse bd!
Exemplul 5 Revenind la exemplul 4, urmtoarea subrutin VBA terge
indexul Tata (de observat c n acest caz simplu poate fi folosit i DAO):

16

De remarcat c, orict ar prea de incredibil, motorul relaional MSJet al Access nu verific


minimalitatea cheilor (ceea ce este valabil, de altfel, i pentru serverul MS SQL Server!), lucru probat i
de reuita crerii acestui index unic, dei Copil este cheie primar!

16

Sub DropIndexTata()
Dim dbs As DAO.Database
Set dbs = CurrentDb()
dbs.Execute "DROP INDEX Tata ON Tata;"
Set dbs = Nothing
End Sub
Instruciunea urmtoare nu va reui s tearg indexul cu numele Tata,
deoarece un asemenea index nu mai exist (el fiind deja ters de subrutina de
mai sus DropIndexTata):
(Q012)DROP INDEX Tata ON Tata;
Instruciunea urmtoare nu va reui s tearg tabela PERSOANE, deoarece
aceasta este implicat cel puin n definiia unei relaii cu o alt tabel (vezi
exemplul 2):
(Q013)DROP TABLE Persoane;

2.4 Instruciunile CREATE USER i CREATE GROUP


Instruciunile CREATE USER i CREATE GROUP creeaz unul sau mai muli
utilizatori, respectiv grupuri de utilizatori ai bazelor de date curente. Sintaxa lor este
urmtoarea:
Pentru crearea de utilizatori:
CREATE USER utilizator parola idp [, utilizator parola idp, ]
Pentru crearea de grupuri:
CREATE GROUP grup idp[, grup idp, ]
Semnificaia variabilelor utilizate este urmtoarea:
Variabil Descriere
utilizator Numele noului utilizator de adugat n fiierul de informaii despre utilizatori.
grup
Numele noului grup de adugat n fiierul de informaii despre utilizatori.
parola
Parola asociat utilizatorului utilizator.
idp
Identificatorul personal (ntre 4 i 20 caractere, inclusiv litere mici i mari).
Observaii:
1) Un utilizator i un grup nu pot avea acelai nume.
2) idp este obligatoriu i unic pentru fiecare utilizator i pentru fiecare grup.
3) Aceste instruciuni nu sunt suportate nici de interfaa interactiv Access i nici
de modelul programatic obiectual DAO, ci numai de cel ADO/ADOX i de
furnizorul Jet OLE DB.
Exemplul 6 Urmtoarele instruciuni creeaz utilizatorii numii Vlad (avnd
parola Andreea i identificatorul personal 1108), Miron (avnd parola
Mami i identificatorul personal 0112) i Diana (avnd parola Bebe i
identificatorul personal 0714), precum i un grup de utilizatori numit Curios
(avnd identificatorul 838797).
(Q014)CREATE USER Vlad Andreea 1108,
Miron Mami 0112, Diana Bebe 0714;
(Q015)CREATE GROUP Curios 838797;

2.5 Instruciunea ADD USER


Sintaxa instruciunii care adaug unul sau mai muli utilizatori unui grup este
urmtoarea:
ADD USER utilizator[, utilizator, ] TO grup
Semnificaia variabilelor utilizate este urmtoarea:
17

Variabil Descriere
utilizator Numele noului utilizator de adugat n fiierul de informaii despre
utilizatori la grupul grup.
grup
Numele grupului la care sunt adugai utilizatorii utilizator.
Observaii:
1) Din momentul adugrii sale la un grup, utilizatorul capt automat toate
drepturile ce au fost garantate acelui grup.
2) Orice utilizator trebuie adugat ntotdeauna i grupului implicit Users; n caz
contrar, el nu va putea lucra cu Access pe acea main, deoarece nu va avea nici
mcar privilegiul de citire a tabelelor sistem ale Jet!
3) Aceast instruciune nu este suportat nici de interfaa interactiv Access i nici
de modelul programatic obiectual DAO, ci numai de cel ADO/ADOX i de
furnizorul Jet OLE DB.
Exemplul 7 Urmtoarea instruciune adaug utilizatorii numii Vlad, Miron
i Diana la grupul de utilizatori numit Curios:
(Q016)ADD USER Vlad, Miron, Diana TO Curios;

2.6 Instruciunile ALTER USER i ALTER DATABASE


Sintaxa acestor instruciuni de schimbare a parolei unui utilizator, respectiv unei
baze de date este urmtoarea:
ALTER USER utilizator PASSWORD parolanou parolaveche
ALTER DATABASE PASSWORD parolanou parolaveche
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
utilizator
Numele utilizatorului a crui parol se schimb.
parolanou Noua parol a utilizatorului utilizator, respectiv a bazei de date.
parolaveche Parola curent a utilizatorului utilizator, respectiv a bazei de date.
Observaii:
1) Pentru a crea, modifica sau terge parola unei baze de date, aceasta trebuie
deschis n prealabil n mod exclusiv.
2) Pentru a crea parola unei baze de date, valoarea parametrului parolaveche
trebuie s fie NULL.
3) Pentru a terge parola unei baze de date, valoarea parametrului parolanou
trebuie s fie NULL.
4) Aceste instruciuni nu sunt suportate nici de interfaa interactiv Access i nici de
modelul programatic obiectual DAO, ci numai de cel ADO/ADOX i de furnizorul
Jet OLE DB.
Exemplul 8 Urmtoarele instruciuni schimb parola utilizatorului numit
Vlad (din Andra n Andreea), respectiv a bazei de date curente (din
munte n admin):
(Q017)ALTER USER Vlad PASSWORD Andreea Andra;
(Q018)ALTER DATABASE PASSWORD admin munte;

18

2.7 Instruciunea GRANT


Instruciunea de garantare a drepturilor de acces pentru utilizatori sau grupuri de
utilizatori asupra bd curente, tabelelor (fundamentale sau virtuale), procedurilor catalogate i containerelor17 are urmtoarea sintax:
GRANT {privilegiu[, privilegiu, ]} ON
{TABLE tabela | OBJECT obiect | CONTAINER container | DATABASE}
TO {numeautorizat[, numeautorizat, ]}
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
privilegiu
Drepturile de acces garantate; acestea pot fi specificate numai cu
ajutorul urmtoarelor cuvinte rezervate: SELECT, DELETE, INSERT,
UPDATE, DROP, SELECTSECURITY, UPDATESECURITY,
CREATE, UPDATEIDENTITY, SELECTSCHEMA, SCHEMA,
UPDATEOWNER, ALLPRIVILEGES, CREATEDB, CONNECT,
EXCLUSIVECONNECT i ADMINDB.
tabela
Numele tabelei fundamentale pentru care sunt garantate drepturile de
acces.
obiect
Numele obiectului non-tabel fundamental (e.g. form, interogare,
raport, macro, tabel virtual, procedur catalogat) pentru care sunt
garantate drepturile de acces.
container
Numele containerului (e.g. tabele, relaii, forme, rapoarte) pentru care
sunt garantate drepturile de acces.
numeautorizat Numele unui utilizator sau grup de utilizatori pentru care sunt garantate
privilegiu asupra bd curente, tabela, obiect sau container.
Observaii:
1) Garantarea de privilegii asupra unui container asigur motenirea acestora de
ctre fiecare instan ce va fi ulterior creat pentru containerul n cauz.
2) n versiunile Access anterioare 2000, se pot garanta privilegii i asupra
containerului de module program, ba chiar i asupra modulelor individuale din
componena sa. n noile versiuni, securitatea modulelor este gestionat doar global
i numai prin intermediul parolei asociate proiectelor VBA.
3) Pentru a garanta privilegii tuturor utilizatorilor (i.e. tuturor membrilor grupului
implicit User), numeautorizat trebuie s aib valoarea rezervat PUBLIC.
4) Pentru a garanta privilegii utilizatorului implicit Admin, numeautorizat trebuie s
aib valoarea rezervat ADMIN.
5) Atenie la faptul c toate privilegiile garantate utilizatorului implicit Admin sunt
la dispoziia tuturor utilizatorilor Access, asupra tuturor bazelor de date (deoarece
de la instalarea sa, toi utilizatorii sunt implicit Admin)! n consecin, acestui
utilizator implicit nu-i trebuie n general garantate, ci mai degrab revocate
privilegii, iar pentru administrarea bd este preferabil crearea explicit de grupuri
i utilizatori ndrituii la aceasta.
5) Aceast instruciune nu este suportat nici de interfaa interactiv Access i nici
de modelul programatic obiectual DAO, ci numai de cel ADO/ADOX i de
furnizorul Jet OLE DB.
6) Semnificaia privilegiilor este urmtoarea:
17

Mulimea containerelor este una dintre cele standard ale obiectului Database oferite de ierarhia de
clase a MS Jet. Un obiect de tip container conine dou mulimi: una de documente (de exemplu: forme,
rapoarte, pagini web de acces la date, macro-uri, module de program etc.) i cealalt de proprieti ale
acestora (de exemplu: nume, tip, valoare, indicatorul boolean care precizeaz dac proprietatea respectiv
este sau nu motenit etc.).

19

Privilegiu
SELECT
DELETE
INSERT
UPDATE
DROP
SELECTSECURITY
UPDATESECURITY
UPDATEIDENTITY
CREATE
SELECTSCHEMA
SCHEMA
UPDATEOWNER
ALLPRIVILEGES
CREATEDB
EXCLUSIVECONNECT
CONNECT
ADMINDB

Aplicare
tabele, obiecte, containere
tabele, obiecte, containere
tabele, obiecte, containere
tabele, obiecte, containere
tabele, obiecte, containere
tabele, obiecte, containere
tabele, obiecte, containere
tabele
tabele, obiecte, containere
tabele, obiecte, containere
tabele, obiecte, containere
tabele, obiecte, containere
toate
bd
bd
bd
bd

Descriere
citire schem i date
tergere date
inserare date
modificare date
tergere definiie din schem
citire privilegii
modificare privilegii
modificare valori Autonumber
creare definiii n schem
citire definiii schem
modificare definiii schem
modificare proprietar
toate privilegiile
creare bd
deschidere bd n mod exclusiv
deschidere bd n mod partajat
administrare bd

Exemplul 9 Urmtoarea instruciune garanteaz tuturor utilizatorilor grupului cu numele Curios dreptul de a interoga, terge, aduga i modifica tuplii
tabelei DOMNII:
(Q019)GRANT SELECT, DELETE, INSERT, UPDATE ON TABLE
Domnii TO Curios;
Urmtoarea instruciune garanteaz utilizatorului Vlad dreptul de a
deschide n mod exclusiv bd curent:
(Q020)GRANT EXCLUSIVECONNECT ON DATABASE TO Vlad;

2.8

Instruciunea REVOKE

Sintaxa instruciunii duale GRANT, deci de revocare a drepturilor de acces ale


utilizatorilor sau grupurilor de utilizatori asupra bd curente, tabelelor (fundamentale sau
virtuale), procedurilor catalogate i containerelor, este urmtoarea:
REVOKE {privilegiu[, privilegiu, ]} ON
{TABLE tabela | OBJECT obiect | CONTAINTER container | DATABASE}
FROM {numeautorizat[, numeautorizat, ]}
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
privilegiu
Drepturile de acces revocate; acestea pot fi specificate numai cu
ajutorul cuvintelor rezervate menionate la instruciunea GRANT.
tabela
Numele tabelei fundamentale pentru care sunt revocate drepturile de
acces.
obiect
Numele obiectului non-tabel fundamental (de exemplu: tabel
virtual sau procedur) pentru care sunt revocate drepturile de acces.
container
Numele containerului pentru care sunt revocate drepturile de acces.
numeautorizat Numele unui utilizator sau grup de utilizatori pentru care sunt revocate
privilegiu asupra tabela, obiect sau container.
Observaie:
Toate observaiile de la instruciunea GRANT sunt valabile mutatis mutandis (i.e.,
n acest caz, nlocuind garantare cu revocare i TO cu FROM) i pentru REVOKE.
20

Exemplul 10 Urmtoarea instruciune revoc tuturor utilizatorilor grupului


Curios dreptul de a terge tuplii tabelei DOMNII:
(Q021)REVOKE DELETE ON TABLE Domnii FROM Curios;
Urmtoarea instruciune revoc utilizatorului Vlad dreptul de a modifica
proprietarul bazei de date curente:
(Q022)REVOKE UPDATEOWNER ON DATABASE FROM Vlad;

2.9 Instruciunile DROP USER i DROP GROUP


Sintaxa instruciunii DROP GROUP, care terge unul sau mai multe grupuri de
utilizatori este urmtoarea:
DROP GROUP grup[, grup, ]
Sintaxa instruciunii DROP USER, care terge unul sau mai muli utilizatori, dintrun grup de utilizatori sau complet, este urmtoarea:
DROP USER utilizator[, utilizator, ] [FROM grup]
Semnificaia variabilelor utilizate este urmtoarea:
Variabil Descriere
utilizator Numele utilizatorului de ters din fiierul de informaii despre utilizatori,
respectiv de eliminat din grupul grup.
grup
Numele grupului de utilizatori de ters din fiierul de utilizatori.
Observaii:
1) tergerea unui grup de utilizatori nu are drept efect i tergerea acestora; evident
ns c ei i pierd statutul de membri ai grupului ters i deci toate drepturile de
acces garantate numai de ctre acesta.
2) Utilizatorii eliminai dintr-un grup i pierd drepturile de acces garantate de acel
grup (dac ele nu le mai sunt garantate n alt mod, i.e., de exemplu, cu titlu
individual sau prin apartenena la alt grup).
3) Aceste instruciuni nu sunt suportate nici de interfaa interactiv Access i nici de
modelul programatic obiectual DAO, ci numai de cel ADO/ADOX i de furnizorul
Jet OLE DB.
Exemplul 11 Urmtoarea instruciune elimin utilizatorul cu numele Vlad
din grupul de utilizatori numit Curios:
(Q023)DROP USER Vlad FROM Curios;
Urmtoarea instruciune terge utilizatorul Miron din fiierul de informaii
despre utilizatori:
(Q024)DROP USER Miron;
Urmtoarea instruciune terge grupul de utilizatori Curios din fiierul de
informaii despre utilizatori: (Q025)DROP GROUP Curios;

3 Sublimbajul de manipulare a datelor

LMD permite interogarea i actualizarea coninutului relaiilor; instruciunile sale se


mpart n trei categorii:
interogri i subinterogri
actualizri
execuia punctelor de vedere, procedurilor catalogate i a tranzaciilor.
Prima categorie este alctuit doar din instruciunile SELECT i TRANSFORM
(dintre care TRANSFORM nu exist n standardul ANSI). A doua conine patru instruciuni: SELECT INTO, INSERT INTO, UPDATE i DELETE, pentru crearea unei noi
tabele pe baza unora existente, adugarea de noi tupli la o tabel, modificarea tuplilor
21

unor tabele, respectiv tergerea de tupli din tabelele existente. A treia categorie este
alctuit din dou instruciuni: EXECUTE i TRANSACTION.
Deoarece sunt folosite de mai multe instruciuni, am factorizat prezentarea a cinci
operaii (produs cartezian; INNER, LEFT i RIGHT JOIN; UNION) i a dou declaraii
(PARAMETERS i WITH OWNERACCESS OPTION). Clauza PROCEDURE nu este
prezentat, deoarece ea mai este nc suportat doar din considerente de compatibilitate
cu vechile programe, fiind nlocuit cu instruciunea omonim mai puternic din LDD.
Dei fac parte din LDD, prezentm abia n acest capitol instruciunile CREATE
VIEW i CREATE PROCEDURE, deoarece ambele se bazeaz pe SELECT.

3.1 Sublimbajul de interogare


3.1.1 Instruciunea SELECT
Sintaxa unicei instruciuni standard de interogare este urmtoarea:
SELECT [predicat] { * | tabela.* | [tabela.]coloana1 [AS sinonim1]
[, [tabela.]coloana2 [AS sinonim2] [, ...]]}
FROM expresietabele [, ...] [IN bdextern]
[WHERE ]
[GROUP BY... ]
[HAVING... ]
[ORDER BY... ]
[WITH OWNERACCESS OPTION]
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
predicat
Unul dintre urmtoarele patru predicate: ALL, DISTINCT,
DISTINCTROW sau TOP; folosite pentru a restrnge numrul de tupli
returnai. Dac nu este specificat nici unul, se presupune implicit c el
este ALL.
*
Specific selecia tuturor atributelor din tabela (tabelele) tabela.
tabela
Numele tabelei (tabelelor) din care sunt selectai tuplii dorii.
coloana1,
Numele atributelor sau expresiilor coninnd datele dorite; relaia
coloana2
rezultat va avea schema alctuit din aceste atribute, n ordinea indicat
n instruciune.
sinonim1,
Redenumiri (opionale) ale atributelor coloana1, coloana2,.. n relaia
sinonim2
rezultat.
expresietabele Numele tabelei (tabelelor) din care sunt selectai tuplii dorii, eventual
operanzi ai operaiilor produs cartezian, respectiv INNER, LEFT i
RIGHT JOIN.
bdextern
Numele bd coninnd tabelele referite n expresietabele, dac acestea nu
aparin bd curente.
Observaii:
1) Evident, (vezi [1], capitolul 2) clauza SELECT implementeaz lista int, clauza
FROM lista domeniilor, iar clauzele WHERE i HAVING formula expresiei
CRT-DV corespunztoare.
2) Pentru execuia acestei instruciuni, MS Jet deschide tabelele implicate, extrage
atributele dorite (efectund deci proiecia), selecteaz tuplii ce satisfac criteriile
specificate (selecie i join), grupeaz i sorteaz datele rezultate n ordinea
indicat, aplicnd eventualele funcii (de agregare, VBA sau utilizator) cerute.
3) Instruciunile SELECT nu modific datele memorate n bd.
4) Sintaxa minim a instruciunii este urmtoarea:
SELECT coloana FROM tabela;
22

5) Pentru a selecta toate coloanele unei tabele se poate folosi *18; instruciunea:
(Q026)SELECT * FROM TATA;
este echivalent cu instruciunea:
(Q027)SELECT TATA.Tata, TATA.Copil FROM TATA;
6) Dac nu exist posibilitatea nici unei ambiguiti, se poate omite numele tabelei
din lista int a instruciunii; de exemplu, (Q026) i (Q027) sunt echivalente cu:
(Q028)SELECT Tata, Copil FROM TATA;
7) Dac ns sunt posibile ambiguiti, atunci ele trebuie eliminate prin folosirea
numelui tabelelor; aceasta este obligatoriu, chiar dac nu ar exista ambiguiti, n
clauza ON a operatorilor JOIN (e.g. vezi exemplul 12).
8) Dac se dorete redenumirea unei coloane sau pentru a asigna un nume unei
coloane rezultate n urma evalurii unei expresii (ceea ce este obligatoriu!) se
folosete cuvntul rezervat AS; de exemplu, pentru a calcula durata fiecrei
domnii n parte i a obine rezultatul n ordinea descresctoare a acesteia (iar n
caz de durate egale, n ordinea cronologic), se poate folosi urmtoarea instruciune (rezultatul aplicrii ei asupra bd din figura 2 este prezentat n figura 3):
(Q029)SELECT Domnitor, La DeLa AS Durata, DeLa, La
FROM Domnii
ORDER BY La DeLa DESC, DeLa;
9) Dac este nevoie de folosirea unei aceleiai tabele de mai multe ori ntr-o
instruciune SELECT, atunci fiecare dintre apariiile duble ale acesteia trebuie
redenumite unic; pentru a calcula domnia imediat succesoare a fiecrei domnii,
se poate folosi urmtoarea instruciune (rezultatul aplicrii ei asupra bd din
figura 2 este prezentat n figura 4):
(Q030)SELECT Domnii.Domnitor AS Predecesor,
Succesiuni.Domnitor AS Succesor, Domnii.La
FROM Domnii INNER JOIN Domnii AS Succesiuni
ON Domnii.La = Succesiuni.DeLa
ORDER BY Domnii.La;
10) Pentru performane mai bune i utilizare mai uoar, se recomand folosirea
tabelelor legate n locul referirii unei bd externe cu ajutorul clauzei IN.
3.1.1.1

Predicatele ALL, DISTINCT, DISTINCTROW i TOP

Semnificaia acestor predicate este urmtoarea:


Predicat
Descriere
ALL
Sunt selectate toate liniile tabelei ce satisfac condiiile instruciunii;
este predicatul implicit.
DISTINCT
Elimin duplicatele din tabela rezultat; n consecin, aceasta nu este
actualizabil i nici nu reflect modificri ulterioare asupra
coninutului tabelelor surs fcute de ali utilizatori simultani (i.e. nu
este nici remprosptabil).
DISTINCTROW Efectueaz nti proieciile asupra operanzilor joinului, apoi elimin
eventualele duplicate aprute i abia apoi calculeaz joinurile. Ca
atare, are efect numai dac exist cel puin o proiecie i un join i este
ignorat dac expresietabele conine doar o singur tabel sau dac lista
int conine atribute din toate tabelele referite de expresietabele.
TOP n
Selecteaz doar primii sau ultimii n (care trebuie s fie un natural
[PERCENT]
reprezentabil n tipul INTEGER) tupli ai rezultatului n ordinea
18

Evident c ([1]) instruciunea SQL SELECT * FROM r; reprezint interogarea unitate 1X, 1X(r) = r,
r I(X).

23

stabilit de clauza ORDER BY, respectiv un procent de n la sut (n


loc de exact n) din tupli (dac se folosete i cuvntul rezervat
PERCENT). Dac clauza ORDER BY conine predicatul DESC,
atunci sunt selectai ultimii n (respectiv n% din) tupli (n ordine
descresctoare); dac ea conine n loc predicatul ASC (sau nici un
predicat), atunci sunt selectai primii (n ordine cresctoare); dac
instruciunea nu conine clauza ORDER BY, atunci rezultatul este
impredictibil, fiind oferii n (respectiv n% din) tupli la ntmplare.
Domnitor
Durata DeLa La
tefan cel Mare
47 1457 1504
Alexandru cel
32 1400 1432
Bun
Petru Muat
17 1374 1391
Lacu
9 1365 1374
Ilia
7 1435 1442
tefan I
5 1394 1399
tefan II
5 1442 1447
Roman I
3 1391 1394
Alexndrel
3 1452 1455
Bogdan I
2 1363 1365
tefan II
2 1433 1435
Bogdan II
2 1449 1451
Petru Aron
2 1455 1457
Iuga Vod
1 1399 1400
Ilia
1 1432 1433
Roman II
1 1447 1448
Petru II
1 1448 1449
Petru Aron
1 1451 1452

Predecesor
Bogdan I
Lacu
Petru Muat
Roman I
tefan I
Iuga Vod
Alexandru cel Bun
Ilia
tefan II
Ilia
tefan II
Roman II
Petru II
Bogdan II
Petru Aron
Alexndrel
Petru Aron

Figura 3 Duratele primelor domnii Muatine

Succesor
Lacu
Petru Muat
Roman I
tefan I
Iuga Vod
Alexandru cel Bun
Ilia
tefan II
Ilia
tefan II
Roman II
Petru II
Bogdan II
Petru Aron
Alexndrel
Petru Aron
tefan cel Mare

Figura 4 Succesiuni Muatine imediate

Exemplul 12
Urmtoarele dou instruciuni sunt echivalente19 i au ca rezultat relaia
coninnd toate domniile, n ordinea alfabetic a domnitorilor (rezultatul
lor pentru bd din figura 2 este prezentat n figura 5):
(Q031)SELECT * FROM Domnii ORDER BY Domnitor;
(Q032)SELECT ALL * FROM Domnii ORDER BY Domnitor;
Urmtoarea instruciune are ca rezultat mulimea tuturor domniilor de
copii de domnitori restrns la numele copiilor domni (ceea ce, ca atare,
devine o list!), n ordine alfabetic (rezultatul ei pentru bd din figura 1
este prezentat n figura 6a):
(Q033)SELECT Tata.Copil AS CopilDomnitor
FROM Tata INNER JOIN Domnii
ON Tata.Copil = Domnii.Domnitor
ORDER BY Tata.Copil;
Se observ n figura 6a c, din cauza faptului c SQL nu elimin automat
duplicatele din rezultat, precum i datorit domniilor multiple, numele unor
19

n fapt, n momentul salvrii unei interogri, MSJetSQL chiar terge automat predicatul ALL!

24

La
1365
1374
1391
1394
1399
1400
1432
1433
1435
1442
1447
1448
1449
1451
1452
1455
1457

domnitori se repet (aprnd cte o dat pentru fiecare dintre domniile lor).
Evident c mult mai natural i interesant din acest punct de vedere ar fi
ns mulimea copiilor de domnitori care au domnit i ei la rndul lor; prin
adugarea predicatului DISTINCT la instruciunea de mai sus se obine
exact acest rezultat (prezentat n figura 6b):
(Q034)SELECT DISTINCT Tata.Copil AS CopilDomnitor
FROM Tata INNER JOIN Domnii
ON Tata.Copil = Domnii.Domnitor
ORDER BY Tata.Copil;
n mod dual, instruciunea urmtoare are ca rezultat mulimea domnitorilor
ce au avut cel puin un copil (vezi figura 7 pentru bd din figura 1):
(Q035)SELECT DISTINCTROW Domnitor AS DomniTai
FROM Persoane INNER JOIN (Tata INNER JOIN
Domnii ON Tata.Tata = Domnii.Domnitor)
ON Persoane.Nume = Domnii.Domnitor
ORDER BY Domnitor;
n absena predicatului DISTINCTROW ns, n loc de cei 13 tupli din
figura 7, s-ar obine 42 de tupli, din cauza dublurilor ce ar aprea ca urmare
a faptului c unii domnitori au domnit de mai multe ori, precum i a faptului
c unii domnitori au avut mai muli copii (de exemplu, att Mircea cel
Btrn ct i Vlad Dracul ar aprea fiecare de cte opt ori, deoarece ambii
au domnit de cte dou ori i au avut cte patru copii).
De remarcat c, n acest caz, rezultatul ar fi acelai dac s-ar nlocui
DISTINCTROW cu DISTINCT, ceea ce ns nu este adevrat n general
(vezi urmtoarele dou interogri i problema 2).
Aparent, pentru a obine acest rezultat, ar fi suficient doar join-ul ntre
DOMNII i TATA, conform urmtoarei instruciuni:
(Q036)SELECT DISTINCTROW Domnitor AS DomniTai
FROM Tata INNER JOIN Domnii
ON Tata.Tata = Domnii.Domnitor
ORDER BY Domnitor;
n acest caz ns, rezultatul conine dubluri (i anume, pentru fiecare
domnitor, cte o apariie per domnie, deci pe lng tuplii din figura 7, ar mai
aprea nc cte unul cu Dan II, Mircea cel Btrn, Vlad Dracul i Vlad
epe) deoarece DISTINCTROW face proiecia doar pe tabela TATA
(eliminnd deci doar dublurile datorate domnitorilor cu mai muli copii) i
nu i pe DOMNII. Cum n PERSOANE exist un singur tuplu per domnitor,
(Q035) apeleaz i la joinul cu aceast tabel pentru ca DISTINCTROW s
elimine i dublurile datorate domniilor multiple.
Urmtoarea instruciune ns (al crui rezultat pentru bd din figura 1 este
exact cel din figura 7, obinut, mai complicat, de (Q035)!), constituie un
exemplu al diferenei ntre predicatele DISTINCT i DISTINCTROW.
(Q037)SELECT DISTINCT Domnitor AS DomniTai
FROM Tata INNER JOIN Domnii
ON Tata.Tata = Domnii.Domnitor
ORDER BY Domnitor;
Instruciunea urmtoare ofer doar primele 10 domnii avnd cele mai lungi
durate dintre cele ale tuturor domniilor memorate de bd (figura 8a prezint rezultatul ei pentru bd din figura 1):

25

Domnitor
Alexandru cel Bun
Alexndrel
Bogdan I
Bogdan II
Ilia
Ilia
Iuga Vod
Lacu
Petru Aron
Petru Aron
Petru II
Petru Muat
Roman I
Roman II
tefan cel Mare
tefan I
tefan II
tefan II

DeLa
1400
1452
1363
1449
1432
1435
1399
1365
1451
1455
1448
1374
1391
1447
1457
1394
1433
1442

La
1432
1455
1365
1451
1433
1442
1400
1374
1452
1457
1449
1391
1394
1448
1504
1399
1435
1447

CopilDomnitor
Alexandru Aldea
Basarab epelu
Dan I
Dan II
Dan II
Laiot Basarab
Mihail I
Mircea cel Btrn
Mircea cel Btrn
Nicolae Alexandru
Radu cel Frumos
Radu cel Mare
Radu I
Radu II Pleuvul
Vlad Clugrul
Vlad Dracul
Vlad Dracul
Vlad epe
Vlad epe
Vlad Uzurpatorul
Vladislav II
Vladislav II
Vladislav Vlaicu

Figura 5 Primele dou secole de


domnii Muatine n ordinea
alfabetic a domnitorilor

CopilDomnitor
Alexandru Aldea
Basarab epelu
Dan I
Dan II
Laiot Basarab
Mihail I
Mircea cel Btrn
Nicolae Alexandru
Radu cel Frumos
Radu cel Mare
Radu I
Radu II Pleuvul
Vlad Clugrul
Vlad Dracul
Vlad epe
Vlad Uzurpatorul
Vladislav II
Vladislav Vlaicu

DomniTai
Basarab I
Basarab epelu
Dan I
Dan II
Laiot Basarab
Mircea cel Btrn
Nicolae Alexandru
Radu cel Frumos
Radu cel Mare
Radu I
Vlad Clugrul
Vlad Dracul
Vlad epe

Figura 7 Primii
domnitori Basarabi
ce au avut copii,
n ordine alfabetic

a) cu dubluri datorate
multiplelor domnii
Figura 6 Copiii primilor
domnitori Basarabi care au
domnit i ei la rndul lor

Domnitor
Durata
Basarab I
42
Mircea cel Btrn
22
Vlad Clugrul
14
Vladislav Vlaicu
13
Radu cel Mare
13
Nicolae Alexandru
12
Radu cel Frumos
11
Vladislav II
9
Mircea cel Btrn
8
Radu I
7

DeLa
1310
1396
1481
1364
1495
1352
1462
1447
1386
1377

La
1352
1418
1495
1377
1508
1364
1473
1456
1394
1384

Domnitor
Durata DeLa La
Basarab I
42 1310 1352
Mircea cel Btrn
22 1396 1418
Vlad Clugrul
14 1481 1495

b) primele 10%
b) fr dubluri (cu
Domnitor Durata DeLa
nume distincte)
Vladislav II
Vlad epe
Dan I

La
1 1442 1443
1 1476 1477
2 1384 1386

c) ultimele 10%

a) primele 10
Domnitor
Durata
Basarab I
42
Nicolae Alexandru
12
Vladislav Vlaicu
13

DeLa
1310
1352
1364

La
1352
1364
1377

d) 10% oarecare (nici o ordonare)


Figura 8 Cele mai lungi domnii Basarabe din primele dou secole ale dinastiei

26

(Q038)SELECT TOP 10 Domnitor, LaDeLa AS Durata,


DeLa, La
FROM Domnii ORDER BY LaDeLa DESC, DeLa;
Figura 8b prezint rezultatul urmtoarei instruciuni similare, pentru 10%
n loc de 10:
(Q039)SELECT TOP 10 PERCENT Domnitor, LaDeLa AS
Durata, DeLa, La
FROM Domnii ORDER BY LaDeLa DESC, DeLa;
De notat c predicatul TOP nu elimin nici unul din tuplii avnd valori
egale pentru coloanele pe care se face ordonarea, ci, la nevoie, mrete
numrul de tupli ai rezultatului; de exemplu, instruciunea:
(Q040)SELECT TOP 4 Domnitor, LaDeLa AS Durata,
DeLa, La
FROM Domnii ORDER BY LaDeLa DESC;
are ca rezultat o relaie coninnd primii 5 tupli ai relaiei din figura 8a (i nu
doar primii 4), deoarece att Vladislav Vlaicu ct i Radu cel Mare au
domnit cte 13 ani. De notat ns c acest lucru nu mai este adevrat de
ndat ce ordonarea s-ar face i dup un alt atribut ale crui valori ar diferi
ntre ele: de exemplu, instruciunea:
(Q041)SELECT TOP 4 Domnitor, LaDeLa AS Durata,
DeLa, La
FROM Domnii ORDER BY LaDeLa DESC, Domnitor;
are ca rezultat exact 4 tupli (ultimul fiind cel corespunztor lui Radu cel
Mare; evident c dac i dup Domnitor ar fi urmat predicatul DESC,
ultimul ar fi fost n schimb cel referitor la Vladislav Vlaicu).
Urmtoarea instruciune (al crui rezultat este prezentat n figura 8c)
furnizeaz n schimb ultimele 10% domnii (sau, echivalent, primele 10%
dintre cele mai scurte):
(Q042)SELECT TOP 10 PERCENT Domnitor, LaDeLa AS
Durata, DeLa, La
FROM Domnii ORDER BY LaDeLa, DeLa;
n sfrit, instruciunea urmtoare furnizeaz trei tupli la ntmplare,
deoarece nu are clauz ORDER BY:
(Q043)SELECT TOP 10 PERCENT Domnitor, LaDeLa AS
Durata, DeLa, La
FROM Domnii;
Se observ ns n figura 8d, care prezint rezultatul acestei ultime
instruciuni, c tuplii oferii nu sunt alei absolut la ntmplare, ci provin din
chiar primii 3 tupli ai relaiei iniiale din figura 1 (evident ns c acetia nu
au nici o legtur, nici mcar ntmpltoare, cu primele sau ultimele 10%
din domnii ca durat!).
De notat c documentaia Microsoft afirm c predicatul TOP nu afecteaz
statutul de actualizabilitate sau nu a rezultatului; acest lucru este ns doar
parial adevrat: de ndat ce clauza FROM conine joinuri sau produse
carteziene, rezultatul unui SELECT urmat de predicatul TOP nu mai este
actualizabil!
3.1.1.2

Operatorii produs cartezian, INNER, LEFT i RIGHT JOIN

Sintaxa unei operaii calculnd un produs cartezian este urmtoarea:


FROM tabela1, tabela2
Sintaxa unei operaii join este urmtoarea:
FROM tabela1 INNER JOIN tabela2 ON tabela1.coloana1 opcomp tabela2.coloana2
27

Semnificaia variabilelor de mai sus este urmtoarea:


Variabil Descriere
tabela1,
Numele tabelelor operanzi.
tabela2
coloana1, Numele coloanelor pe care se face joinul (nu neaprat aceleai). Dac
coloana2 tipul lor de dat nu este numeric, atunci trebuie s aib acelai tip de dat.
opcomp
Oricare dintre urmtorii operatori relaionali: "=," "<," ">," "<=," ">=,"
sau "<>."
Observaii:
1) Spre deosebire de JOIN, produsul cartezian nu este actualizabil.
2) Dac se dorete ca rezultatul s conin i tuplii dintr-o tabel care nu au legturi
cu vreunul din tuplii celeilalte tabele (de exemplu, toate persoanele i prinii
lor, n cazul n care acetia sunt cunoscui, fr ns a elimina persoanele ai cror
prini nu se cunosc) este nevoie de un join extern (LEFT sau RIGHT).
3) Nu se admite join pe coloane avnd drept tip de dat MEMO sau OLE OBJECT.
4) Nu se poate face join nici chiar pe orice combinaie de tipuri numerice de dat,
ci doar pe cele compatibile (ca lungime de octei folosit pentru reprezentare);
de exemplu, SINGLE i DOUBLE nu sunt compatibile; n schimb, LONG i
AUTONUMBER sunt compatibile. Se pot ns folosi pentru compatibilizare
funciile de conversie a datelor din biblioteca VBA (e.g. CStr, CInt etc.).
5) Sunt posibile joinuri pe mai multe coloane simultan i/sau alternativ, folosind
sintaxa:
SELECT listacoloane
FROM tabela1 INNER JOIN tabela2
ON tabela1.coloana1 opcomp tabela2.coloana1 [AND
ON tabela1.coloana2 opcomp tabela2.coloana2 [AND] [OR
ON tabela1.coloana3 opcomp tabela2.coloana3][OR]];
6) Se pot preciza oricte compuneri de joinuri, conform urmtoarei sintaxe:
SELECT listacoloane
FROM tabela1 INNER JOIN
(tabela2 INNER JOIN [( ]tabela3
[INNER JOIN [( ]tabelax [INNER JOIN ...)]
ON tabela3.coloana3 opcomp tabelax.coloanax)]
ON tabela2.coloana2 opcomp tabela3.coloana3)
ON tabela1.coloana1 opcomp tabela2.coloana2;
7) Sintaxa operatorilor join externi LEFT JOIN i RIGHT JOIN este similar cu
cea a INNER JOIN, nlocuind doar INNER cu LEFT sau RIGHT:
FROM tabela1 [ LEFT | RIGHT ] JOIN tabela2
ON tabela1.coloana1 opcomp tabela2.coloana2
8) LEFT JOIN este folosit pentru a include n rspuns toi tuplii din prima tabel
(cea din stnga), indiferent dac le corespunde vreun tuplu din cea de-a doua
tabel sau nu; simetric, dac se dorete includerea n rspuns a tuturor tuplilor
din cea de-a doua tabel, se folosete RIGHT JOIN.
9) Observaiile de la 2) la 6) mai sus sunt valabile i pentru joinurile externe LEFT
i RIGHT.
10) Se pot compune operaii LEFT JOIN sau RIGHT JOIN n interiorul unui
INNER JOIN, dar nici un INNER JOIN nu poate fi compus n interiorul unui
LEFT JOIN sau RIGHT JOIN. Nu orice compunere de joinuri externe (LEFT,
RIGHT) i interne (INNER) este deci permis, deoarece sunt posibile
ambiguiti. n asemenea cazuri, se vor folosi mai muli pai i interogri salvate
intermediare adecvate.
28

11) Evident c operatorii LEFT i RIGHT JOIN, ca i cel de JOIN sunt operatori
compui. Pentru definiia lor exact, detalii i exemple vezi operatorul UNION
(subseciunea 3.1.3).
Exemplul 13
Urmtoarea instruciune calculeaz copiii domnitorilor aflai n via la
(sau care au decedat n acelai an cu) momentul terminrii domniilor prinilor lor (rezultatul ei pentru bd din figura 1 este prezentat n figura 9):
(Q044)SELECT DISTINCT Domnii.Domnitor, Tata.Copil
FROM (Domnii INNER JOIN Persoane
ON Domnii.La<=Persoane.Moarte) INNER JOIN
Tata ON (Persoane.Nume=Tata.Copil) AND
(Domnii.Domnitor=Tata.Tata)
ORDER BY Domnii.Domnitor, Tata.Copil;
Urmtoarea instruciune calculeaz domnitorii i prinii lor (figura 10
prezint rezultatul ei pentru bd din figura 1):
(Q045)SELECT DISTINCT Domnitor, Mama, Tata
FROM (Mama RIGHT JOIN Domnii
ON Mama.Copil=Domnii.Domnitor) LEFT JOIN
Tata ON Domnii.Domnitor=Tata.Copil
ORDER BY Domnii.Domnitor;
Urmtoarea instruciune calculeaz copiii domnitorilor i mamele lor
(rezultatul ei pentru bd din figura 1 este prezentat n figura 11):
(Q046)SELECT DISTINCT Tata.Copil, Domnitor, Mama
FROM (Mama RIGHT JOIN Tata
ON Mama.Copil = Tata.Copil) INNER JOIN
Domnii ON Tata.Tata = Domnii.Domnitor
ORDER BY Tata.Copil;
Urmtoarea instruciune ns, cu care am dori s calculm domnitorii,
eventualii lor copii, inclusiv anul morii i mamele acestora, este eronat
(mesajul de eroare preciznd c ea are joinuri externe ambigue):
(Q047)SELECT DISTINCT Domnii.Domnitor, Tata.Copil,
Persoane.Moarte, Mama.Mama
FROM ((Domnii LEFT JOIN Tata
ON Domnii.Domnitor = Tata.Tata) LEFT JOIN
Mama ON Tata.Copil = Mama.Copil) INNER JOIN
Persoane ON Tata.Copil = Persoane.Nume
ORDER BY Domnii.Domnitor, Tata.Copil;
Acest lucru este de ateptat, deoarece e posibil s existe domnitori fr copii
i deci INNER JOIN-ul nu este definit. Ca atare, n loc de INNER JOIN este
nevoie tot de un LEFT JOIN (rezultatul fiind prezentat n figura 12):
(Q048)SELECT DISTINCT Domnii.Domnitor, Tata.Copil,
Persoane.Moarte, Mama.Mama
FROM ((Domnii LEFT JOIN Tata
ON Domnii.Domnitor = Tata.Tata) LEFT JOIN
Mama ON Tata.Copil = Mama.Copil) LEFT JOIN
Persoane ON Tata.Copil = Persoane.Nume
ORDER BY Domnii.Domnitor, Tata.Copil;
3.1.1.3

Clauza WHERE

Clauza WHERE reprezint predicatul de selecie a tuplilor; sintaxa ei este


urmtoarea: SELECT listacoloane FROM expresietabele WHERE criteriu
unde criteriu este o expresie ce trebuie satisfcut de tuplii rezultatului.
29

Domnitor
Nume
Basarab I
Nicolae Alexandru
Basarab epelu
Neagoe Basarab
Dan I
Dan II
Dan I
Vlad Uzurpatorul
Dan II
Laiot Basarab
Dan II
Vladislav II
Mircea cel Btrn
Alexandru Aldea
Mircea cel Btrn
Mihail I
Mircea cel Btrn
Radu II Pleuvul
Mircea cel Btrn
Vlad Dracul
Nicolae Alexandru Radu I
Nicolae Alexandru Vladislav Vlaicu
Radu cel Frumos
Maria Voichia
Radu cel Mare
Mircea Ciobanul
Radu cel Mare
Radu de la Afumai
Radu I
Dan I
Radu I
Mircea cel Btrn
Vlad Clugrul
Radu cel Mare
Vlad Clugrul
Vlad cel Tnr
Vlad Dracul
Mircea
Vlad Dracul
Vlad Clugrul
Vlad Dracul
Vlad epe
Vlad epe
Mihnea cel Ru
Figura 9 Copiii domnitorilor Basarabi nc n via n anul terminrii domniilor prinilor lor
Domnitor
Alexandru Aldea
Basarab I
Basarab epelu
Dan I
Dan II
Laiot Basarab
Mihail I
Mircea cel Btrn
Nicolae Alexandru
Radu cel Frumos
Radu cel Mare
Radu I
Radu II Pleuvul
Vlad Clugrul
Vlad Dracul
Vlad epe
Vlad Uzurpatorul
Vladislav II
Vladislav Vlaicu
Figura 10

Mama

Tata
Mircea cel Btrn

Laiot Basarab
Radu I
Dan I
Dan II
Mircea cel Btrn
Radu I
Basarab I
Mtu tefan cel Mare
Vlad Dracul
Vlad Clugrul
Maria
Nicolae Alexandru
Mircea cel Btrn
Mtu tefan cel Mare
Vlad Dracul
Mircea cel Btrn
Mtu tefan cel Mare
Vlad Dracul
Dan I
Dan II
Maria
Nicolae Alexandru
Primii domnitori Basarabi i prinii lor

30

Copil
Domnitor
Mama
Alexandru Aldea
Mircea cel Btrn
Ana
Nicolae Alexandru Clara
Anca
Nicolae Alexandru Clara
Basarab epelu
Laiot Basarab
Dan I
Radu I
Dan II
Dan I
Elisabeta
Nicolae Alexandru Maria
Laiot Basarab
Dan II
Maria Voichia
Radu cel Frumos
Mihail I
Mircea cel Btrn
Mihnea cel Ru
Vlad epe
Mircea
Vlad Dracul
Mtu tefan cel Mare
Mircea cel Btrn Radu I
Mircea Ciobanul
Radu cel Mare
Neagoe Basarab
Basarab epelu
Nicolae Alexandru Basarab I
Radu cel Frumos
Vlad Dracul
Mtu tefan cel Mare
Radu cel Mare
Vlad Clugrul
Radu de la Afumai Radu cel Mare
Radu I
Nicolae Alexandru Maria
Radu II Pleuvul
Mircea cel Btrn
Radu Paisie
Radu cel Mare
Vlad
Vlad epe
Elena
Vlad Clugrul
Vlad Dracul
Mtu tefan cel Mare
Vlad cel Tnr
Vlad Clugrul
Vlad Dracul
Mircea cel Btrn
Vlad epe
Vlad Dracul
Mtu tefan cel Mare
Vlad Uzurpatorul Dan I
Vladislav II
Dan II
Vladislav Vlaicu
Nicolae Alexandru Maria
Figura 11 Copiii domnitorilor Basarabi i prinii lor

Observaii:
1) Dac clauza WHERE lipsete, rezultatul conine toi tuplii tabelelor implicate.
2) Dac este prezent, clauza WHERE urmeaz obligatoriu dup clauza FROM.
3) WHERE folosete i la eliminarea tuplilor ce nu trebuie grupai (vezi 3.1.1.6).
4) Se pot conecta cu AND i OR n WHERE maxim 40 de expresii atomice.
5) Literalii de tip date calendaristice trebuie folosii n format U.S. (i.e.#ll/zz/aa#,
adic n ordinea lun, zi, an, separate ntre ele de /), chiar dac versiunea Jet
folosit nu este de tip U.S. Dac Windows este configurat pentru o alt limb, ale
crei formate pentru date difer de cele U.S., se poate folosi ns funcia VBA
DateValue, care convertete formatul de dat curent n cel U.S.
6) Dac vreun atribut referit n criteriu este de tip GUID20, criteriu are o sintax
diferit (n care acoladele i liniuele de unire sunt eseniale); de exemplu:
20

Acronimul pentru Globally Unique Identifier/Universally Unique Identifier: un ir de identificare


unic folosit n apelul procedurilor aflate la distan. Orice clas de obiecte sau interfa folosete un GUID
pentru identificare. Orice GUID este memorat pe 128 bii. De exemplu, 12345678-1234-1234-1234123456789ABC este un GUID sintactic corect. GUID-urile folosite pe calculatoarele client i server
trebuie s corespund pentru a permite legarea clientului de server. Furnizorii software de clase de obiecte
pot cere Microsoft s li se aloce unul sau mai multe seturi de cte 256 GUID-uri pentru folosin

31

Domnitor
Copil
MoarteCopil
Mama
Alexandru Aldea
Basarab I
Nicolae Alexandru
1364
Basarab epelu
Neagoe Basarab
1521
Dan I
Dan II
1431
Dan I
Vlad Uzurpatorul
1396
Dan II
Laiot Basarab
1477
Dan II
Vladislav II
1456
Laiot Basarab
Basarab epelu
Mihail I
Mircea cel Btrn Alexandru Aldea
1436
Mircea cel Btrn Mihail I
1420
Mircea cel Btrn Radu II Pleuvul
1427
Mircea cel Btrn Vlad Dracul
1447
Nicolae Alexandru Ana
Clara
Nicolae Alexandru Anca
Clara
Nicolae Alexandru Elisabeta
Maria
Nicolae Alexandru Radu I
1384
Maria
Nicolae Alexandru Vladislav Vlaicu
1377
Maria
Radu cel Frumos Maria Voichia
1511
Radu cel Mare
Mircea Ciobanul
1559
Radu cel Mare
Radu de la Afumai
1529
Radu cel Mare
Radu Paisie
Radu I
Dan I
1386
Radu I
Mircea cel Btrn
1418
Radu II Pleuvul
Vlad Clugrul
Radu cel Mare
1508
Vlad Clugrul
Vlad cel Tnr
1512
Vlad Dracul
Mircea
1447
Mtu tefan cel Mare
Vlad Dracul
Radu cel Frumos
Mtu tefan cel Mare
Vlad Dracul
Vlad Clugrul
1495
Mtu tefan cel Mare
Vlad Dracul
Vlad epe
1477
Mtu tefan cel Mare
Vlad epe
Mihnea cel Ru
1509
Vlad epe
Vlad
Elena
Vlad Uzurpatorul
Vladislav II
Vladislav Vlaicu
Figura 12 Primii domnitori Basarabi, copiii lor, mamele i anul morii acestora
WHERE ReplicaID={GUID{12345678-90AB-CDEF-1234-567890ABCDEF}}

Exemplul 14 Urmtoarea instruciune (care folosete un dublu theta-join!)


selecteaz domnitorii ce au consacrat diversele capitale romneti (rezultatele ei
pentru datele din figurile 13 i 1, respectiv 2 sunt prezentate n figura 14; de remarcat compatibilizarea obligatorie cu CStr a tipurilor de date comparate!):
exclusiv. Alternativ, pentru orice plac de reea dintr-un calculator, se poate executa programul
Uuidgen.exe, care furnizeaz un set de 256 GUID-uri bazat pe data, ora, minutul i secunda curente,
precum i pe numrul unic de identificare al plcii de reea (ntotdeauna garantat de furnizorul acesteia).

32

CAPITALE (An) Capitala


Capitala
An
Cmpulung Muscel 1310
Curtea de Arge
1369
Trgovite
1419
Bucureti
1558

CAPITALE (An) Capitala


Capitala An
Siret
1363
Suceava 1375
Iai
1650

a. ara Romneasc
b. Moldova
Figura 13 Capitalele rii Romneti i Moldovei, cu anii aproximativi de stabilire a lor

Domnitor
Basarab I
Vladislav Vlaicu
Mihail I

Capitala
Cmpulung Muscel
Curtea de Arge
Trgovite

Domnitor
Bogdan I
Petru Muat

Capitala
Siret
Suceava

a. ara Romneasc
b. Moldova
Figura 14 Rezultatele interogrii (Q049) asupra relaiilor din figurile 13 i 1, respectiv 2

(Q049)SELECT Domnii.Domnitor, Capitale.Capitala


FROM Capitale INNER JOIN Domnii
ON (Capitale.An<=CStr(Domnii.La)) AND
(Capitale.An>=CStr(Domnii.DeLa))
ORDER BY Capitale.An;
Urmtoarea instruciune, care nlocuiete theta-joinul cu un produs cartezian urmat de o selecie (pentru care utilizarea CStr este tot obligatorie!),
este echivalent (dar risc s fie executat mai lent pe unele dintre motoarele
relaionale existente n lipsa unei acordri fine corespunztoare!):
(Q050)SELECT Domnii.Domnitor, Capitale.Capitala
FROM Capitale, Domnii
WHERE ((Capitale.An<=CStr(Domnii.La) AND
(Capitale.An>=CStr(Domnii.DeLa))
ORDER BY Capitale.An;
3.1.1.4

Operatorii de comparaie LIKE, IN i BETWEEN...AND

Pe lng operatorii de comparaie standard, uzuali n matematic (,,,,,),


SQL ofer nc trei: LIKE, IN i BETWEEN...AND. Ei pot fi folosii n clauzele
WHERE i HAVING, oriunde sunt acceptai cei standard.
3.1.1.4.1 Operatorul LIKE
Operatorul LIKE are sintaxa:
expresie LIKE ablon
i valoarea adevrat dac primul operand este asemntor cu cel de-al doilea,
respectiv fals n caz contrar; asemnarea const n aceea c n compunerea celui de-al
doilea operator pot intra, pe lng toate celelalte caractere (privite drept constante) i
urmtoarele metacaractere (privite drept variabile):
Metacaracter
Semnificaie
? sau _ (subliniere)
Orice caracter
* sau %
Orice (sub)ir de caractere (inclusiv vid!)
#
Orice cifr (0 9)
[listachar]
Orice caracter aprnd n listachar
[!listachar]
Orice caracter diferit de cele ce apar n listachar
33

Observaii:
1) listachar poate include aproape toate caracterele ANSI;. pentru a include i
caracterele folosite drept metacaractere (i.e. [, ?, _, #, *), apariiile acestora trebuie
nchise n paranteze drepte; listachar nu poate include metacaracterul ].
2) n listachar se pot specifica nu doar caractere, ci i intervale de caractere ale
cror limite sunt separate prin -; de exemplu, [A-Z] reprezint orice liter mare;
pot fi incluse mai multe intervale, folosind mai multe liniue despritoare ': de
exemplu, [a-zA-Z0-9] semnific orice caracter alfanumeric (i.e. litere mari, mici i
cifre).
3) ! este considerat drept metacaracter doar n construcii de tip [!listachar], unde
are rolul operatorului logic de negaie.
4) este considerat drept metacaracter doar n construcii de tip [!listachar], cu
excepia eventualelor sale apariii ca prim (dup [ sau [!), respectiv ultim
caracter al grupului (nainte de ]), caz n care este considerat drept caracter.
5) n specificarea intervalelor de caractere este obligatorie ordonarea lexicografic
cresctoare: de exemplu, intervalele [A-Z] sau [0-100] sunt valide, n timp ce
intervalele [Z-A] sau [100-0] sunt considerate drept invalide.
6) Secvena de caractere [ ] este ignorat, fiind considerat totuna cu irul vid .
Exemplul 15 Urmtoarea instruciune calculeaz submulimea domniilor
acelor domnitori al cror nume conine subirul vlad i care i-au nceput
domnia n secolul XV (rezultatul ei este prezentat n figura 15):
(Q051)SELECT * FROM Domnii WHERE (Domnitor LIKE
'*vlad*' AND DeLa LIKE '14??');
Domnitor
Vlad Dracul
Vladislav II
Vlad Dracul
Vladislav II
Vlad epe
Vlad epe
Vlad Clugrul

DeLa
1436
1442
1443
1447
1456
1476
1481

La
1442
1443
1447
1456
1462
1477
1495

Figura 15 Domnii Basarabe ncepute n secolul XV ale domnilor avnd numele


asemntor cu vlad

3.1.1.4.2 Operatorul IN
Operatorul IN implementeaz predicatul de apartenen la o mulime discret (i.e.
determin dac valoarea unei expresii este egal cu vreuna dintre valorile unei liste de
expresii). Sintaxa sa este urmtoarea:
expr [NOT] IN (val1, val2, . . .).
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
expr
Expresie identificnd atributul de evaluat.
val1, val2, ... List de expresii cu a cror valoare se compar valoarea expr.
Observaii:
1) Dac valoarea expr este printre cele ale listei val1, val2, . . ., atunci IN are
valoarea adevrat, iar altfel fals.
2) Evident, NOT IN are semantica dual celei lui IN.
3) abloanele folosind metacaracterele nu se pot utiliza n IN.
34

Nume
Moarte Necropol
Bogdan III
1517 Putna
Bogdnel
1477 Putna
Ilie
1472 Putna
Maria
1518 Putna
Maria de Mangop
1477 Putna
Maria Voichia
1511 Putna
Petru Ptracu
1480 Putna
tefan cel Mare
1504 Putna
Anastasia
Rdui
Bogdan
1407 Rdui
Bogdan I
1365 Rdui
Bogdan II
1451 Rdui
Lacu
1374 Rdui
Petru Muat
1391 Rdui
Roman I
1394 Rdui
tefan I
1399 Rdui
Figura 16 Muatini nhumai n bisericile din Putna i Rdui

Exemplul 16 Urmtoarea instruciune calculeaz submulimea persoanelor


nhumate n catedralele de la Rdui sau Putna (rezultatul ei asupra bd din
figura 2 este prezentat n figura 16):
(Q052)SELECT * FROM Persoane WHERE (Necropol In
('Rdui','Putna'))
ORDER BY Necropol, Nume;
3.1.1.4.3 Operatorul BETWEEN...AND
Operatorul BETWEEN...AND implementeaz predicatul de apartenen la un interval de valori (i.e. determin dac valoarea unei expresii este cuprins ntre dou valori).
Sintaxa sa este urmtoarea:
expr [NOT] BETWEEN val1 AND val2
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
expr
Expresie identificnd atributul de evaluat.
Expresiile ce sunt evaluate pentru a obine cele dou capete ale intervalului
val1, val2 n care se afl sau nu valoarea expr.
Observaii:
1) Dac valoarea expr se afl ntre valorile val1 i val2 (inclusiv), atunci
BETWEEN...AND are valoarea adevrat, iar altfel fals.
2) Evident, NOT BETWEEN...AND are semantica dual celei de mai sus.
3) Dac oricare dintre expr, val1 sau val2 are valoarea NULL, BETWEEN...AND
are tot valoarea NULL.
4) abloanele folosind metacaracterele nu se pot utiliza n BETWEEN...AND.
Exemplul 17 Revenind la exemplul 14, (Q050) este echivalent cu urmtoarea
instruciune (de remarcat iar obligativitatea compatibilizrii, acum dual):
(Q053)SELECT Domnitor, Capitala
FROM Capitale, Domnii
WHERE (CInt(An) Between DeLa And La)
ORDER BY An;
35

3.1.1.5

Funciile de agregare

n definiia sintaxei SELECT se specific despre lista int coloana1, coloana2, ,


c aceasta este constituit din nume de atribute sau de expresii. n alctuirea acestor
expresii pot intra att funcii oferite de bibliotecile standard ale limbajului gazd VBA
(de exemplu, funcii de conversie ntre diverse tipuri de date, funcii de manipulare a
irurilor de caractere, aritmetice, boolene etc.), ct i cele 11 funcii de agregare oferite
de SQL. Acestea sunt urmtoarele: Avg, Count, First, Last, Min, Max, StDev, StDevP,
Sum, Var i VarP (dintre care StDev i VarP nu sunt nc incluse n standardul ANSI).
3.1.1.5.1 Funcia Avg
Funcia Avg (average) calculeaz media aritmetic a unei mulimi de valori
numerice. Sintaxa ei este Avg(expr), unde expr reprezint o expresie ir de caractere
identificnd valorile numerice pentru care se dorete calculul mediei.
Observaii:
1) Operanzii expr pot fi nume de atribute, constante sau funcii VBA (dar nu alte
funcii de agregare SQL).
2) Valorile NULL sunt ignorate.
Exemplul 18 Urmtoarea instruciune calculeaz media duratei domniilor (n
ani; rezultatele ei pentru figurile 1 i 2 sunt prezentate n figura 17):
(Q054)SELECT Avg(La-DeLa) AS DurataMedie FROM Domnii;
3.1.1.5.2 Funcia Count
Funcia are sintaxa Count(expr) i calculeaz cardinalul (i.e. numrul de tupli al)
rezultatului interogrii; expr reprezint o expresie ir de caractere identificnd valorile
numerice pentru care se dorete calculul cardinalului.
Observaii:
1) Operanzii expr pot fi nume de atribute, constante sau funcii VBA (dar nu alte
funcii de agregare SQL).
2) Tipul de dat al valorilor numrate nu are importan; de exemplu, se poate
calcula numrul de apariii al unor valori de tip ir de caractere.
3) Dei expr poate efectua calcule asupra valorilor atributelor, acestea nu se reflect
dect indirect n cardinal: Count numr pur i simplu tuplii relaiei rezultat.
4) n mod normal, Count ignor tuplii avnd doar valori NULL; dac se doresc
numrate i acestea, atunci trebuie folosit sintaxa Count(*), care numr toi
tuplii tabelei rezultat.
5) Dac expr refer mai multe atribute, eventualii tupli coninnd doar valori
NULL nu sunt numrai; pentru a fi numrat, un tuplu trebuie s aib deci mcar o
valoare diferit de NULL n asemenea circumstane.
6) Dac expr conine doar o list de atribute, elementele ei trebuie separate prin
caracterul ampersand (&).
7) n absena clauzei GROUP BY, este considerat ntreaga tabel rezultat pentru a
calcula cardinalul; n prezena ei, se calculeaz cte un cardinal per grup.
Exemplul 19
Urmtoarea instruciune calculeaz numrul domniilor (rezultatul ei este
prezentat n figura 18 a i b):
(Q055)SELECT Count(*) AS NrDomnii FROM Domnii;
Urmtoarea instruciune nu calculeaz numrul domnitorilor (cum s-ar
putea crede din greeal), ci tot pe cel al domniilor (furniznd deci acelai
rezultat cu instruciunea de mai sus), deoarece Count numr pur i simplu
36

tuplii rezultatului (ignornd doar eventualele valori nule, ceea ce, pentru
acest exemplu, nu este cazul):
(Q056)SELECT Count(Domnitor) AS NrDomni FROM Domnii;
Pentru a calcula numrul domnitorilor este nevoie de doi pai: se salveaz
sub un nume oarecare (de exemplu: Q057) instruciunea urmtoare (care
calculeaz toi domnitorii, eliminnd ns duplicatele datorate domniilor
multiple):
(Q057)SELECT DISTINCT Domnitor FROM Domnii;
n al doilea pas, se execut urmtoarea instruciune asupra ei i nu asupra
DOMNII (rezultatele aplicrii acestei instruciuni sunt prezentate n figura
18 c i d):
(Q058)SELECT Count(*) AS NrDomni FROM Q057;
De reinut c expr nu poate conine predicatele DISTINCT,
DISTINCTROW sau TOP (i de aceea este nevoie de doi pai:
Count(DISTINCT Domnitor) este ilegal).
Aplicat bd din figura 2, urmtoarea instruciune calculeaz numrul de
Muatini nhumai n cea mai veche catedral-panteon a Moldovei
(Rdui):
(Q059)SELECT Count(Necropol) AS NrPersoane
FROM Persoane
WHERE (((Necropol)=Rdui));
Rezultatul ei este prezentat n figura 19a; desigur c dac ar fi aplicat bd din
figura 1, numrul respectiv ar fi 0; figura 19b prezint ns rezultatul aplicrii
asupra bd din figura 1 a instruciunii similare celei de mai sus, unde s-a nlocuit
Rdui cu Cmpulung (catedrala echivalent pentru ara Romneasc).
Urmtoarea instruciune calculeaz numrul persoanelor pentru care este
memorat i locul nhumrii (rezultatele ei pentru bd din figurile 1 i 2 sunt
prezentate n figura 20); de observat c valorile nule nu sunt numrate:
(Q060)SELECT Count(Necropol) AS NrNecropol
FROM Persoane;
Urmtoarea instruciune calculeaz numrul persoanelor pentru care este
memorat mcar una din informaiile privind anul morii i locul nhumrii
(rezultatele ei pentru bd din figurile 1 i 2 sunt prezentate n figura 21); de
observat c tuplii avnd valori nule n amndou coloanele nu sunt numrai:
(Q061)SELECT Count([Moarte] & [Necropol]) AS
NrMoarteNecropol FROM Persoane;
3.1.1.5.3 Funciile First i Last
Aceste funcii ofer o valoare (indicat de argumentul lor) din primul, respectiv
ultimul tuplu al operandului interogrii. Sintaxa lor este First(expr), respectiv
Last(expr), unde expr reprezint o expresie ir de caractere identificnd valorile
numerice a cror selecie se dorete.
Observaii:
1) Operanzii expr pot fi nume de atribute, constante sau funcii VBA (dar nu alte
funcii de agregare SQL).
2) Primul i ultimul tuplu al unei tabele sunt considerate n ordinea cheii primare a
acesteia, iar n absena ei, n ordinea cronologic a memorrii lor n tabel. Chiar
dac n interogare este prezent clauza ORDER BY, deoarece selecia primului,
respectiv ultimului tuplu se face naintea ordonrii, rezultatul obinut de aplicarea
First sau Last este acelai ca i n absena acestei clauze.

37

DurataMedie
7,83

DurataMedie
8,25

a) ara Romneasc
b) Moldova
Figura 17 Durata medie (n ani) a domniilor din primele dou secole ale Principatelor
Romneti

NrDomni
19

NrDomnii
18

NrDomnii
24

NrDomni
15

a) ara Romneasc
b) Moldova
c) ara Romneasc
d) Moldova
Figura 18 Numrul de domnii i domnitori din primele dou secole ale Principatelor Romneti

NrPersoane
8

NrNecropol
9

NrPersoane
2

a) Rdui
b) Cmpulung Muscel
Figura 19 Numrul de persoane din
familiile domnitoare nhumate n
primele catedrale-panteon romneti

NrNecropol
22

a) Basarabi
b) Muatini
Figura 20 Numrul de persoane din familiile
domnitoare pentru care este precizat locul
nhumrii

NrMoarteNecropol
27

NrMoarteNecropol
25

a) ara Romneasc
b) Moldova
Figura 21 Numrul de persoane pentru care e precizat anul morii sau necropola

Fondator
Bogdan I

Fondator
Basarab I ntemeietorul
a) ara Romneasc
Figura 22 Fondatorii primelor dinastii ale Principatelor Romne

b) Moldova

DurataMax
47

DurataMax
42

a) ara Romneasc
b) Moldova
Figura 23 Duratele maxime de domnie n primelor dou secole ale Principatelor Romne

DevStdDurateDomnii
12,4534427085091

DevStdDurateDomnii
8,85756861328945

a) ara Romneasc
b) Moldova
Figura 24 Deviaiile standard pentru duratele domniilor din figura 1, respectiv 2

TotalAni
141

TotalAni
198

a) ara Romneasc
b) Moldova
Figura 25 Totalul duratelor domniilor n ara Romneasc i Moldova conform datelor din
figura 1, respectiv 2

VarDurateDomnii
155,088235294118

VarDurateDomnii
78,4565217391304

a) ara Romneasc
b) Moldova
Figura 26 Variana pentru duratele domniilor din figura 1, respectiv 2

38

Exemplul 20 Cel mai simplu mod de a calcula fondatorul dinastiei este oferit
de urmtoarea instruciune:
(Q062)SELECT First(Domnitor) AS Fondator
FROM Domnii;
Rezultatul ei (prezentat n figura 22) se bazeaz evident pe faptul c
atributul DeLa este cheie primar i deci domniile sunt oferite de bd n
ordinea lor cronologic.
Instruciunea urmtoare nu este nici mcar acceptat de sistem (eroarea
semnalat: expresia [La]-[DeLa] nu este inclus n nici o agregare):
(Q063)SELECT Last(La-DeLa) AS DurataMax FROM Domnii
ORDER BY La-DeLa;
Este acceptat n schimb instruciunea:
(Q064)SELECT Last(La-DeLa) AS DurataMax FROM Domnii
ORDER BY Last(La-DeLa);
care este ns evident lipsit de sens (ordonate dup durata memorat de
ultimul tuplu?!?) i care, desigur, ntoarce durata ultimei domnii din tabel,
ceea ce s-ar obine i fr clauza ORDER BY, cu instruciunea:
(Q065)SELECT Last(La-DeLa) AS DurataMax FROM Domnii;
Cu ajutorul urmtoarei instruciuni, bazat din nou pe cheia primar DeLa,
se poate calcula totalul duratelor domniilor de interes (rezultatul este prezentat n figura 25):
(Q066)SELECT Last(La)-First(DeLa) AS TotalAni
FROM Domnii;
3.1.1.5.4 Funciile Min i Max
Funciile Min i Max calculeaz valoarea minim, respectiv maxim a unei mulimi
de valori. Sintaxa lor este Min(expr), respectiv Max(expr), unde expr reprezint o
expresie ir de caractere identificnd valorile numerice pentru care se dorete calculul
minimului, respectiv maximului.
Observaii:
1) Operanzii expr pot fi nume de atribute, constante sau funcii VBA (dar nu alte
funcii de agregare SQL).
2) n absena clauzei GROUP BY, este considerat ntreaga tabel rezultat pentru a
calcula un unic minim sau maxim; n prezena ei, se calculeaz cte un minim,
respectiv maxim per grup.
Exemplul 21 Urmtoarea instruciune calculeaz durata maxim a domniilor
(figura 23 prezint rezultatul ei pentru bd din figura 1 i 2):
(Q067)SELECT Max(La-DeLa) AS DurataMax FROM Domnii;
3.1.1.5.5 Funciile StDev i StDevP
Funciile StDev i StDevP calculeaz valoarea deviaiei standard21 pentru o
populaie, respectiv un eantion de populaie reprezentate ca o mulime de valori ale
unui atribut al relaiei rezultat a unei interogri. Sintaxa lor este StDev(expr), respectiv
StDevP(expr), unde expr reprezint o expresie ir de caractere identificnd valorile
numerice pentru care se dorete calculul deviaiei standard corespunztoare.

21

Deviaia standard este un parametru ce indic modul n care o funcie probabilistic este centrat n
jurul mediei ei i care este egal cu rdcina ptrat din deviaia de la medie; este folosit pentru a descrie
ct de departe variaz valorile unei mulimi n raport cu media lor aritmetic.

39

Observaii:
1) Operanzii expr pot fi nume de atribute, constante sau funcii VBA (dar nu alte
funcii de agregare SQL).
2) Dac relaia rezultat al interogrii ce memoreaz populaia conine mai puin de
doi tupli (respectiv nici un tuplu, n cazul eantioanelor de populaie) funcia
ntoarce valoarea NULL (ce indic imposibilitatea calculrii deviaiei standard).
Exemplul 22 Urmtoarea instruciune calculeaz deviaia standard a duratei
domniilor (rezultatele ei sunt prezentate n figura 24):
(Q068)SELECT StDev(La-DeLa) AS DevStdDurateDomnii
FROM Domnii;
3.1.1.5.6 Funcia Sum
Funcia Sum calculeaz suma unei mulimi de valori numerice. Sintaxa ei este
Sum(expr), unde expr reprezint o expresie ir de caractere identificnd valorile
numerice pentru care se dorete calculul sumei.
Observaii:
1) Operanzii expr pot fi nume de atribute, constante sau funcii VBA (dar nu alte
funcii de agregare SQL).
2) Valorile NULL sunt ignorate.
3) n absena clauzei GROUP BY, este considerat ntreaga tabel rezultat pentru a
calcula suma; n prezena ei, se calculeaz cte o sum per grup.
Exemplul 23 Cu ajutorul urmtoarei instruciuni, de data aceasta fcnd
complet abstracie de cheia primar a tabelei (aa cum este normal!), se
poate calcula totalul duratelor domniilor de interes (rezultatul pentru bd din
figurile 1 i 2 este prezentat n figura 25):
(Q069)SELECT Sum(La-Dela) AS TotalAni FROM Domnii;
3.1.1.5.7 Funciile Var i VarP
Funciile Var i VarP calculeaz valoarea varianei22 pentru o populaie, respectiv
un eantion de populaie reprezentate ca o mulime de valori ale unui atribut al relaiei
rezultat a unei interogri.
Sintaxa lor este Var(expr), respectiv VarP(expr), unde expr reprezint o expresie ir
de caractere identificnd valorile numerice pentru care se dorete calculul varianei
corespunztoare.
Observaii:
1) Operanzii expr pot fi nume de atribute, constante sau funcii VBA (dar nu alte
funcii de agregare SQL).
2) Dac relaia rezultat al interogrii ce memoreaz populaia conine mai puin de
doi tupli, funciile ntorc valoarea NULL (ce indic imposibilitatea calculrii
varianei).
Exemplul 24 Urmtoarea instruciune calculeaz variana duratei domniilor
(rezultatele ei sunt prezentate n figura 26):
(Q070)SELECT Var(La-DeLa) AS VarDurateDomnii
FROM Domnii;

22

Variana este egal cu ptratul deviaiei standard; este i ea o msur a distanei cu care valorile unei
mulimi se ndeprteaz de medie.

40

3.1.1.6

Clauza GROUP BY

Clauza GROUP BY nlocuiete tuplii avnd aceeai valoare pentru o submulime a


atributelor rezultatului interogrii cu un singur tuplu. Se pot calcula cu aceast ocazie,
folosind funciile de agregare (vezi 3.1.1.5), una sau mai multe valori agregate per grup
(de exemplu, sum, cardinal, medie etc.). Sintaxa ei este urmtoarea:
SELECT listacoloane FROM expresietabele [WHERE criteriu]
[GROUP BY listacoloanegrupare]
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
listacoloane
Numele atributelor rezultatului, inclusiv sinonime pentru funcii
de agregare i eventuale alte opiuni (predicate DISTINCT,
DISTINCTROW etc.).
expresietabele
Tabela sau compunerea joinurilor asupra tabelelor operanzi.
criteriu
Criteriul de selecie al clauzei opionale WHERE; dac aceasta
este prezent, gruparea se aplic doar tuplilor ce satisfac criteriu.
listacoloanegrupare Lista numelor a cel mult 10 atribute conform crora se face
gruparea; ordinea lor n list determin nivelele de grupare
(primul atribut fiind de cel mai nalt nivel).
Observaii:
1) Valorile NULL nu sunt omise i sunt i ele grupate; reamintim ns c ele sunt
ignorate de toate funciile de agregare.
2) Clauza WHERE se folosete pentru a exclude din grupare tuplii nedorii, nainte de
grupare; pentru a filtra tuplii obinui dup grupare trebuie folosit clauza HAVING.
3) MS Jet nu admite n listacoloanegrupare atribute avnd tipul de dat MEMO sau
OLE DB.
4) listacoloanegrupare poate conine orice atribut al oricreia dintre tabelele referite de
expresietabele, chiar dac el nu apare n listacoloane, cu condiia ca instruciunea s
conin cel puin o funcie de agregare.
5) Toate atributele din listacoloane trebuie s figureze ori n listacoloanegrupare, ori
drept argument al unei funcii de agregare (i.e. dac nu figureaz ca argument al
unei funcii de agregare, ele trebuie obligatoriu s figureze i n
listacoloanegrupare).
6) Predicatele DISTINCT, DISTINCTROW i TOP se aplic rezultatului gruprii (i.e.
dup grupare, nu naintea ei); ca atare, funciile de agregare iau n considerare i
eventualele dubluri.
Exemplul 25
Urmtoarea instruciune calculeaz numrul domniilor pentru fiecare
domnitor n parte (rezultatele ei sunt prezentate n figura 27):
(Q071)SELECT Count(*) AS NrDomnii, Domnitor
FROM Domnii
GROUP BY Domnitor
ORDER BY Count(*), Domnitor;
Urmtoarea instruciune calculeaz, pentru fiecare dintre mame, maximum
duratei domniilor copiilor ei, ordonate descresctor dup maximele
calculate, iar n caz de egalitate, ordonate cresctor dup numele mamelor
(joinul extern incluznd toate mamele, indiferent dac copiii lor au domnit
sau nu); rezultatele sunt prezentate n figura 28:
(Q072)SELECT Mama, Max(La-DeLa) AS MaxDomnieCopii
FROM Mama LEFT JOIN Domnii
ON Mama.Copil = Domnii.Domnitor
41

GROUP BY Mama
ORDER BY Max(La-DeLa) DESC, Mama;
Pentru a calcula capitala curent n momentul nceperii fiecrei domnii
(vezi figura 29) este nevoie de doi pai: nti se calculeaz pentru fiecare
domnie maximul dintre toi anii de stabilire a capitalei cu ajutorul
urmtoarei instruciuni (de notat i obligativitatea calificrii operandului
Max cu numele tabelei: n lipsa acestuia, datorit faptului c rezultatul
expresiei corespunztoare se numete tot An, SQL raporteaz o eroare
sintactic de definire circular!):
(Q073)SELECT Max(CInt(Capitala.An)) AS An,
Domnitor, DeLa, La
FROM Domnii, Capitale
WHERE (CInt(An)<=DeLa)
GROUP BY Domnitor, DeLa, La;
Apoi, salvnd interogarea de mai sus sub un nume oarecare (de exemplu,
Q073), se obine rspunsul dorit cu ajutorul instruciunii urmtoare (care
nlocuiete anii stabilirii capitalelor cu nsei capitalele):
(Q074)SELECT Domnitor, DeLa, La, Capitala
FROM Capitale INNER JOIN Q073
ON CInt(Capitale.An) = Q073.An
ORDER BY DeLa;
Urmtoarea instruciune calculeaz numrul total al anilor de domnie
pentru fiecare voievod n parte, prezentndu-i n ordinea descresctoare a
totalurilor, iar n caz de egalitate, n ordinea cresctoare a numelor
(rezultatele ei sunt prezentate n figura 30):
(Q075)SELECT Domnitor, Sum(La-DeLa) AS TotalAniDomnie
FROM Domnii GROUP BY Domnitor
ORDER BY Sum(La-DeLa) DESC, Domnitor;
Urmtoarea instruciune nu calculeaz corect numrul de copii ai
domnitorilor, deoarece predicatul DISTINCT se aplic dup funcia de
agregare Count (i nu invers; vezi 3.1.1.5.2); ca atare, pentru domnitorii ce
au avut mai multe domnii, numrul de copii avui se multiplic, n mod
eronat, cu numrul domniilor:
(Q076)SELECT DISTINCT Domnitor, Count(Copil) AS
NrCopii
FROM Tata RIGHT JOIN Domnii
ON Tata.Tata = Domnii.Domnitor
GROUP BY Domnitor
ORDER BY Count(Copil) DESC, Domnitor;
Pentru a calcula corect numrul copiilor, este nevoie deci de doi pai: se
salveaz nti sub un nume oarecare (de exemplu: Q077) instruciunea:
(Q077)SELECT DISTINCT Domnitor, Copil
FROM Tata RIGHT JOIN Domnii
ON Tata.Tata = Domnii.Domnitor;
dup care, urmtoarea instruciune (al crei rezultat este prezentat n figura
31) calculeaz numrul copiilor, oferit n ordine descresctoare (iar n caz de
egalitate, n ordinea alfabetic a domnitorilor):
(Q078)SELECT Domnitor, Count(Copil) AS NrCopii
FROM Q077 GROUP BY Domnitor
ORDER BY Count(Copil) DESC, Domnitor;

42

NrDomnii
Domnitor
1 Alexandru Aldea
1 Basarab I
1 Basarab epelu
1 Dan I
1 Laiot Basarab
1 Mihail I
1 Nicolae Alexandru
1 Radu cel Frumos
1 Radu cel Mare
1 Radu I
1 Radu II Pleuvul
1 Vlad Clugrul
1 Vlad Uzurpatorul
1 Vladislav Vlaicu
2 Dan II
2 Mircea cel Btrn
2 Vlad Dracul
2 Vlad epe
2 Vladislav II

NrDomnii
Domnitor
1 Alexandru cel Bun
1 Alexndrel
1 Bogdan I
1 Bogdan II
1 Iuga Vod
1 Lacu
1 Petru II
1 Petru Muat
1 Roman I
1 Roman II
1 tefan cel Mare
1 tefan I
2 Ilia
2 Petru Aron
2 tefan II
b) Moldova

a) ara Romneasc
Figura 27 Numrul domniilor per domnitor pentru bd din figurile 1 i 2

Mama
MaxDomnieCopii
Mtu
14
tefan cel Mare
Maria
13
Clara
Elena
a) ara Romneasc

Mama
MaxDomnieCopii
Maria Oltea Basarab
47
Anastasia
32
Margareta Muata
17
Ana Neaca
7
Sor Petru Muat?
5
Mariana
2
Evdochia
Maria de Mangop
Maria Rare din Hrlu
Maria Voichia

b) Moldova
Figura 28 Maximum domniilor pentru copiii fiecrei mame din bd prezentate n figurile 1 i 2

De remarcat c, atunci cnd numr doar valori NULL, funcia Count are
drept rezultat, n mod corect, valoarea 0 (i nu 1): altfel spus, apariia unui
NULL nu este numrat ca atare, ci ea semnalizeaz mulimea vid.
3.1.1.7

Clauza HAVING

Clauza HAVING specific care dintre tuplii grupai de clauza GROUP BY sunt
reinui n final pentru rezultatul interogrii; sintaxa ei este urmtoarea:
SELECT listacoloane FROM expresietabele [WHERE criteriu]
GROUP BY listacoloanegrupare
[HAVING criteriugrupare]
43

Domnitor
Basarab I
Nicolae Alexandru
Vladislav Vlaicu
Radu I
Dan I
Mircea cel Btrn
Vlad Uzurpatorul
Mircea cel Btrn
Mihail I
Dan II
Radu II Pleuvul
Dan II
Alexandru Aldea
Vlad Dracul
Vladislav II
Vlad Dracul
Vladislav II
Vlad epe
Radu cel Frumos
Laiot Basarab
Vlad epe
Basarab epelu
Vlad Clugrul
Radu cel Mare

DeLa
1310
1352
1364
1377
1384
1386
1394
1396
1418
1420
1424
1426
1431
1436
1442
1443
1447
1456
1462
1473
1476
1477
1481
1495

La
Capitala
1352 Cmpulung Muscel
1364 Cmpulung Muscel
1377 Cmpulung Muscel
1384 Curtea de Arge
1386 Curtea de Arge
1394 Curtea de Arge
1396 Curtea de Arge
1418 Curtea de Arge
1420 Curtea de Arge
1424 Trgovite
1425 Trgovite
1431 Trgovite
1436 Trgovite
1442 Trgovite
1443 Trgovite
1447 Trgovite
1456 Trgovite
1462 Trgovite
1473 Trgovite
1476 Trgovite
1477 Trgovite
1481 Trgovite
1495 Trgovite
1508 Trgovite

Domnitor
DeLa La Capitala
Bogdan I
1363 1365 Siret
Lacu
1365 1374 Siret
Petru Muat
1374 1391 Siret
Roman I
1391 1394 Suceava
tefan I
1394 1399 Suceava
Iuga Vod
1399 1400 Suceava
Alexandru cel Bun 1400 1432 Suceava
Ilia
1432 1433 Suceava
tefan II
1433 1435 Suceava
Ilia
1435 1442 Suceava
tefan II
1442 1447 Suceava
Roman II
1447 1448 Suceava
Petru II
1448 1449 Suceava
Bogdan II
1449 1451 Suceava
Petru Aron
1451 1452 Suceava
Alexndrel
1452 1455 Suceava
Petru Aron
1455 1457 Suceava
tefan cel Mare
1457 1504 Suceava

b) Moldova

a) ara Romneasc
Figura 29 Capitalele Principatelor Romne pentru domniile secolelor XIV i XV

Domnitor
TotalAniDomnie
Basarab I
42
Mircea cel Btrn
30
Vlad Clugrul
14
Radu cel Mare
13
Vladislav Vlaicu
13
Nicolae Alexandru
12
Radu cel Frumos
11
Vlad Dracul
10
Vladislav II
10
Dan II
9
Radu I
7
Vlad epe
7
Alexandru Aldea
5
Basarab epelu
4
Laiot Basarab
3
Dan I
2
Mihail I
2
Radu II Pleuvul
2
Vlad Uzurpatorul
2

Domnitor
TotalAniDomnie
tefan cel Mare
47
Alexandru cel Bun
32
Petru Muat
17
Lacu
9
Ilia
8
tefan II
7
tefan I
5
Alexndrel
3
Petru Aron
3
Roman I
3
Bogdan I
2
Bogdan II
2
Iuga Vod
1
Petru II
1
Roman II
1
b) Moldova

a) ara Romneasc
Figura 30 Duratele domniilor Basarabe i Muatine din secolele XIV i XV

44

Domnitor
Nicolae Alexandru
Mircea cel Btrn
Vlad Dracul
Radu cel Mare
Dan I
Dan II
Radu I
Vlad Clugrul
Vlad epe
Basarab I
Basarab epelu
Laiot Basarab
Radu cel Frumos
Alexandru Aldea
Mihail I
Radu II Pleuvul
Vlad Uzurpatorul
Vladislav II
Vladislav Vlaicu

NrCopii
5
4
4
3
2
2
2
2
2
1
1
1
1
0
0
0
0
0
0

Domnitor
tefan cel Mare
Alexandru cel Bun
Bogdan I
Ilia
Roman I
Bogdan II
Alexndrel
Iuga Vod
Lacu
Petru Aron
Petru II
Petru Muat
Roman II
tefan I
tefan II

NrCopii
8
6
2
2
2
1
0
0
0
0
0
0
0
0
0

b) Moldova

a) ara Romneasc
Figura 31 Numrul de copii ai primilor domnitori Basarabi i Muatini

Semnificaia variabilelor utilizate este urmtoarea:


Variabil
Descriere
listacoloane
Numele atributelor rezultatului, inclusiv sinonime pentru funcii
de agregare i eventuale alte opiuni (predicate DISTINCT,
DISTINCTROW etc.)
expresietabele
Tabela sau compunerea joinurilor asupra tabelelor operanzi.
criteriu
Criteriul de selecie al clauzei opionale WHERE; dac aceasta
este prezent, gruparea se aplic doar tuplilor ce satisfac
criteriu.
listacoloanegrupare Lista numelor a cel mult 10 atribute conform crora se face
gruparea; ordinea lor n list determin nivelele de grupare
(primul atribut fiind de cel mai nalt nivel).
criteriugrupare
Criteriul de selecie ce trebuie satisfcut de tuplii obinui n
urma gruprii pentru a fi inclui n rezultatul instruciunii.
Observaii:
1) Clauza WHERE se folosete pentru a exclude din grupare tuplii nedorii, nainte de
grupare; pentru a filtra tuplii obinui dup grupare trebuie folosit clauza HAVING.
2) criteriugrupare poate conine cel mult 40 de atomi conectai cu AND i OR.
Exemplul 26 S reconsiderm (Q078) din exemplul 25; urmtoarea
instruciune (al crei rezultat este similar celui din figura 31, cu excepia
faptului c tabela a. conine doar primii 9 tupli, iar tabela b. doar primii 5)
calculeaz domnitorii care au avut cel puin 2 copii (de remarcat c aceast
condiie nu poate fi pus n clauza WHERE, deoarece, la momentul
evalurii acesteia, numrul copiilor nici mcar nu este definit!):
(Q079)SELECT DISTINCT Domnitor, Count(Copil) AS NrCopii
FROM Q077 GROUP BY Domnitor
HAVING (Count(Copil) >= 2)
ORDER BY Count(Copil) DESC, Domnitor;
45

Evident c, n acest caz, (Q077) se poate simplifica (ocazie cu care ea se


va i executa mai rapid!) nlocuind RIGHT cu INNER JOIN.
Dac dorim s calculm acelai lucru ca mai sus, dar impunnd condiia
suplimentar ca toi copiii considerai s fi supravieuit tatlui lor (i.e.
fiecare dintre copiii luai n calculul cardinalului s fi murit cel mai devreme
n anul morii tatlui su) este evident c e nevoie n plus de un join cu
PERSOANE i de o clauz WHERE:
(Q080)SELECT DISTINCT Domnitor, Count(Copil) AS
NrCopii
FROM (Q077 INNER JOIN Persoane
ON Q077.Copil = Persoane.Nume)
INNER JOIN Persoane AS Domni
ON Q077.Domnitor = Domni.Nume
WHERE ((Persoane.Moarte>=Domni.Moarte))
GROUP BY Domnitor
HAVING (Count(Copil)>=2)
ORDER BY Count(Copil) DESC, Domnitor;
Examinnd rezultatul acesteia (prezentat n figura 32), care este similar cu
cel al interogrii de mai sus, se observ i c sunt mai puini tupli (deoarece
unora dintre domni nu le-au supravieuit cel puin 2 copii) i c ceilali tupli
au, n general, alte valori n coloana NrCopii (deoarece nu toi copiii au
supravieuit prinilor lor).
Domnitor
Mircea cel Btrn
Vlad Dracul
Dan I
Dan II
Nicolae Alexandru
Radu cel Mare
Radu I
Vlad Clugrul

NrCopii
4
3
2
2
2
2
2
2

Domnitor
NrCopii
Alexandru cel Bun
4
tefan cel Mare
3
Bogdan I
2
Roman I
2
b) Moldova

a) ara Romneasc
Figura 32 Numrul copiilor de domni ce au supravieuit tailor lor, pentru domnitorii cu cel
puin 2 copii supravieuindu-le
3.1.1.8

Clauza ORDER BY

Clauza ORDER BY ordoneaz tuplii rezultatului dup valorile unei liste de atribute,
n ordine cresctoare sau descresctoare pentru fiecare din acestea; sintaxa ei este
urmtoarea:
SELECT listacoloane FROM expresietabele [WHERE ] [GROUP BY ]
[HAVING ] [ORDER BY coloana1 [ASC | DESC][, coloana2 [ASC | DESC]][, ]]
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
listacoloane
Numele atributelor rezultatului.
expresietabele Tabela sau compunerea joinurilor asupra tabelelor operanzi.
coloana1,
Numele atributelor (sau expresii algebrice construite peste atribute)
coloana2
dup care se face sortarea, n aceast ordine.
Observaii:
1) Ordinea de sortare pentru coloana1, coloana2 este precizat de predicatele ASC
(pentru ascendent, cresctor; e.g. de la A la Z i de la 0 la 9) i DESC (pentru
46

2)

3)
4)

5)
6)
7)

descendent, descresctor; e.g. de la Z la A i de la 9 la 0). Implicit, n absena


vreunui astfel de predicat, ordinea este cresctoare.
n absena clauzei ORDER BY, rezultatul nu este ordonat n nici un fel dect
ntmpltor! (ntmpltor, n implementarea curent a MS Jet, n asemenea cazuri
rezultatul este ordonat cresctor dup toate atributele sale, dar acest lucru nu este
garantat explicit i deci este nesigur).
Tuplii sunt sortai nti dup coloana1, apoi, n caz de egalitate pe coloana1, dup
coloana2 i aa mai departe.
Clauza WHERE se folosete pentru a exclude din rspuns tuplii nedorii, nainte de
ordonare; clauza HAVING este folosit pentru a filtra tuplii obinui dup grupare,
ns tot naintea ordonrii.
MS Jet nu admite n lista coloana1, coloana2, atribute avnd tipul de dat
MEMO sau OLE DB.
Lista coloana1, coloana2, poate referi oricare din atributele tabelelor referite n
expresietabele, indiferent dac ele sunt sau nu referite n listacoloane.
Operatorul ORDER BY este aplicat ntotdeauna ultimul, dup WHERE, GROUP
BY i HAVING (care sunt aplicai ntotdeauna n aceast ordine).
Exemplul 27 S reconsiderm (Q080) din exemplul 26; dac se dorete
obinerea rezultatelor n ordine invers (i.e. alfabetic a domnitorilor i att,
deoarece nu pot exista mai muli domnitori avnd acelai nume), atunci
trebuie modificat astfel instruciunea corespunztoare (al crei rezultat este
prezentat n figura 33):
(Q081)SELECT DISTINCT Domnitor, Count(Copil) AS
NrCopii
FROM (Q077 INNER JOIN Persoane
ON Q077.Copil = Persoane.Nume)
INNER JOIN Persoane AS Domni
ON Q077.Domnitor = Domni.Nume
WHERE ((Persoane.Moarte>=Domni.Moarte))
GROUP BY Domnitor
HAVING (Count(Copil)>=2)
ORDER BY Domnitor;
n absena clauzei ORDER BY din instruciunea de mai sus, rezultatele sunt
aceleai, ns doar ntmpltor!

3.1.1.9

Declaraia PARAMETERS

Aceast declaraie, care poate precede orice instruciune SQL de manipulare a


datelor, precizeaz o list de nume i de tipuri de dat asociate acestora, list ce
constituie parametrii instruciunii (astfel parametrizate); sintaxa ei este urmtoarea:
PARAMETERS nume1 tipdat [, nume2 tipdat [, ]]; instrSQL
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
nume1, nume2
Numele parametrilor.
tipdat
Tipul de data al parametrului curent: unul dintre tipurile primare de
date ale MS Jet (sau un sinonim al unuia dintre ele; vezi 2.1.1).
instrSQL
Instruciunea SQL parametrizat cu parametrii nume1, nume2, .
Observaii:
1) n DAO i ADO, numele fiecrui parametru este asignat proprietii Name
a obiectului Parameter i e folosit pentru identificarea parametrului
respectiv n cadrul coleciei Parameters.
47

Domnitor
Dan I
Dan II
Mircea cel Btrn
Nicolae Alexandru
Radu cel Mare
Radu I
Vlad Clugrul
Vlad Dracul

NrCopii
2
2
4
2
2
2
2
3

Domnitor
NrCopii
Alexandru cel Bun
4
Bogdan I
2
Roman I
2
tefan cel Mare
3
b) Moldova

a) ara Romneasc
Figura 33 Tabelele din figura 32 n ordinea alfabetic a domnitorilor

2) Numele parametrilor sunt folosite de MS Jet pentru a cere utilizatorilor bd


valoarea dorit pentru fiecare parametru n parte (a nu se uita parantezele ptrate
dac numele include spaii i/sau caractere de punctuaie!). Valorile acestora pot
fi ns furnizate i de ctre codul VBA al programului (fr a face deci
obligatorie participarea utilizatorilor la precizarea lor).
3) Aceast declaraie este folosit n general pentru flexibilizarea codului
programelor executate regulat, prin modificarea dinamic a criteriilor de selecie
a rezultatelor dorite.
4) nume1, nume2, pot fi folosite doar n clauzele WHERE i HAVING ale
instrSQL; tipdat nu se poate folosi nicieri n instrSQL.
Exemplul 28 S reconsiderm exemplul 26 i figura 31 de mai sus; dac se
dorete obinerea rezultatelor similare (Q079), dar pentru un numr oarecare
de copii, ce urmeaz a fi specificat de utilizator la momentul execuiei
instruciunii, atunci se poate folosi n loc urmtoarea instruciune:
(Q082)PARAMETERS
[Care este numrul minim de copii dorit?] Integer;
SELECT DISTINCT Domnitor, Count(Copil) AS NrCopii
FROM Q077 GROUP BY Domnitor
HAVING Count(Copil) >=
[Care este numrul minim de copii dorit?]
ORDER BY Count(Copil) DESC, Domnitor;
n momentul execuiei instruciunii de mai sus, apare o fereastr semimodal23 cu titlul Enter parameter value i prompt-ul Care este numrul
minim de copii dorit? ; de exemplu, dac utilizatorul tasteaz orice numr
negativ sau 0, rezultatul instruciunii este evident cel din figura 31; dac
numrul este 2, atunci rezultatul conine doar primii 9 tupli din tabela a) i
primii 5 din b); dac numrul este 4, atunci apar doar primii 3 tupli din
tabela a) i primii 2 din tabela b); dac numrul este 6, 7 sau 8, atunci tabela
a) conine doar primul tuplu, iar tabela b) este vid; dac numrul este mai
mare dect 8, atunci ambele tabele sunt vide etc.
23

O fereastr Windows se zice semi-modal daca este afiat deasupra tuturor celorlalte ferestre deschise
n acel moment, fr butoane de minimizare (dar avndu-l pe cel de nchidere) i nu permite continuarea
execuiei programului curent pn cnd utilizatorul nu o nchide sau nu introduce de la tastatur valoarea
ateptat de fereastr, urmat de apsarea butonului OK (dup care fereastra se nchide automat, paseaz
valoarea tastat de utilizator programului, iar acesta i poate n sfrit relua execuia). Dac valoarea
tastat nu are valide valoarea i/sau tipul de dat, atunci este afiat un mesaj de eroare corespunztor i se
ateapt reintroducerea altei valori; acest lucru se repet ori de cte ori este nevoie (pn cnd utilizatorul
introduce o valoare valid sau nchide fereastra). Dac fereastra este nchis (fie din butonul OK ori
Cancel, fie din cel standard de nchidere al oricrei ferestre) fr s fi specificat vreo valoare, execuia
este abandonat.

48

Un alt exemplu tipic de utilizare a instruciunilor parametrizate este legat de


selecia informaiilor n funcie de diverse (intervale de) date calendaristice; de
exemplu, pentru a selecta doar domniile dintr-o anumit perioad de timp
(oricare ar fi ea, la latitudinea utilizatorului) se poate folosi urmtoarea
instruciune:
Domnitor
Mircea cel Btrn
Mihail I
Dan II
Radu II Pleuvul
Dan II
Alexandru Aldea

DeLa
1396
1418
1420
1424
1426
1431

La
1418
1420
1424
1425
1431
1436

Domnitor
tefan II
Roman II
Petru II
Bogdan II
Petru Aron
Alexndrel
Petru Aron

a) Domnii Basarabe simultane cu


domnia lui Alexandru cel Bun
(1400-1432)

DeLa
1442
1447
1448
1449
1451
1452
1455

La
1447
1448
1449
1451
1452
1455
1457

b) Domnii Muatine simultane cu


a doua domnie a lui Vladislav II
(1447-1456)

Figura 34 Selecia domniilor dintr-un interval de timp parametrizat

(Q083)SELECT * FROM Domnii


WHERE ([Data minim:] <= La AND
DeLa <= [Data maxim:]);
Executnd aceast instruciune cu valorile 1400, respectiv 1432 (pentru data
minim, respectiv maxim) asupra coninutului bd din figura 1 se obine
tabela din figura 34a (care pune n eviden faptul c, pe parcursul domniei lui
Alexandru cel Bun, n ara Romneasc s-au succedat nu mai puin de 6
domnii!). Similar, executnd-o cu valorile 1447, respectiv 1456 asupra
coninutului bd din figura 2, se obine tabela din figura 34b (care ne
informeaz c, ntr-un interval de trei ori mai scurt, n rstimpul celei de-a
doua domnii a lui Vladislav II, n Moldova s-au succedat nu mai puin de 7
domnii!).
3.1.1.10 Declaraia WITH OWNERACCESS OPTION

Aceast declaraie opional are sens doar n medii de lucru multi-utilizator, cu


drepturi de acces selective la date i programe pentru utilizatorii i grupurile concurente;
ea garanteaz utilizatorului instruciunii, ns numai pentru execuia acesteia, aceleai
drepturi cu cele pe care le are proprietarul ei. Sintaxa declaraiei este urmtoarea:
instrSQL
WITH OWNERACCESS OPTION
unde instrSQL este o instruciune SQL de manipulare a datelor oarecare (deci nu numai
SELECT, dar nu vreo instruciune a sublimbajului de definire a datelor).
Observaii:
1) Cu ajutorul acestei declaraii, utilizatori care altfel nu au acces nici chiar n citire la
anumite date le pot mcar parial citi, att ct le permite instruciunea respectiv (cu
condiia, evident, ca proprietarul instruciunii s aib toate drepturile necesare).
Similar, ei pot aduga tupli la o tabel la care altfel nu au acces n scriere etc.
2) Dac se dorete o politic de control strict a accesului la date pentru utilizatorii
concureni, nu folosii niciodat aceast opiune!
3) Pentru ca aceast declaraie s aib efect n Access, este necesar dreptul de acces la
fiierul de informaii despre utilizatori i grupuri (system.mdw) al bd curente.
49

4) n medii de lucru neconcureniale sau fr asigurarea securitii datelor prin


garantarea de drepturi de acces utilizatorilor, aceast declaraie nu are nici un efect.
3.1.2 Subinterogri
Se zice subinterogare orice instruciune SELECT ncapsulat n corpul unei alte
instruciuni gazd SELECT, SELECTINTO, INSERT INTO, UPDATE, DELETE,
TRANSFORM (limitat) sau a unei alte subinterogri; sintaxa unei subinterogri poate
avea una din urmtoarele patru forme:
(instrSELECT)
comparaie [ANY | ALL | SOME] (instrSELECT)
expresie [NOT] IN (instrSELECT)
[NOT] EXISTS (instrSELECT)
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
comparaie
O expresie i un operator de comparaie ce compar expresia cu
rezultatul instrSELECT.
expresie
Expresia ale crei valori sunt cutate printre cele ale instrSELECT.
instrSELECT Instruciunea SELECT constituind subinterogarea propriu-zis.
Observaii:
1) Subinterogrile se folosesc pentru a furniza submulimi de tupli de interes (unei
interogri sau instruciuni de actualizare a datelor gazd) de o manier compact,
natural i elegant, evitnd spargerea problemei n doi sau mai muli pai sau,
dimpotriv, punnd n eviden doi sau mai muli subpai ai unei instruciuni.
2) Subinterogrile se pot folosi n lista int (numai prima form, cu condiia s aib ca
rezultat un singur tuplu compus dintr-o unic valoare!), precum i n clauzele
FROM, WHERE i HAVING; n instruciunile TRANSFORM ns, subinterogrile
se pot folosi doar ca predicate n clauza WHERE (niciodat deci n lista int sau n
clauzele FROM ori HAVING).
3) Subinterogrile se execut, n general, n mod static, o singur dat, naintea
interogrii gazd; excepia o constituie subinterogrile de tipul celor descrise la
punctul 13 de mai jos, care se execut dinamic, ntreesut, cte o dat pentru
fiecare tuplu evaluat de interogarea gazd (ceea ce, evident, poate dura enorm!).
4) Subinterogrile nu pot conine clauza ORDER BY.
5) Dac se folosete a doua form fr predicatele ANY, SOME sau ALL (i.e. doar cu
operatorii =, <>,<, <=, >, >=), atunci subinterogarea trebuie s aib drept rezultat o
unic valoare (i.e. o relaie cu o unic coloan i o unic linie). n restul cazurilor
(i.e. cu operatorii de comparaie IN, SOME, ANY, ALL, EXISTS), subinterogrile
pot returna mai multe linii i mai multe coloane.
6) Predicatele ANY i SOME sunt sinonime; ele se folosesc pentru ca instruciunea
gazd s selecteze doar tuplii ce satisfac operatorul de comparaie pentru mcar unul
dintre tuplii rezultatului subinterogrii (echivalent: cuantificatorul existenial).
7) < ANY nseamn mai puin dect maximum; > ANY, mai mult dect minimum; =
ANY este echivalent cu IN.
8) Predicatul ALL (echivalent: cuantificatorul universal) se folosete pentru selecia
tuplilor ce satisfac operatorul de comparaie pentru toi tuplii rezultatului
subinterogrii.
9) < ALL nseamn mai puin dect minimum; > ALL, mai mult dect maximum.
10) Predicatul IN (echivalent: = ANY, deci incluziunea / apartenena) se folosete
pentru selecia tuplilor ce conin o aceeai valoare cu mcar unul dintre tuplii
rezultatului subinterogrii (dual, evident, NOT IN, care este totuna cu <> ALL, este
echivalent cu predicatul nu este inclus n / nu aparine).
50

11) Dac rezultatul subinterogrii include o valoare NULL, atunci forma NOT IN va
ntoarce rezultatul NULL (evident, acest lucru nu se ntmpl i pentru forma IN).
12) Predicatul [NOT] EXISTS (echivalent: comparaia cu mulimea vid) se folosete n
comparaii booleene pentru a decide dac subinterogarea are ca rezultat mulimea
vid sau nu.
13) n subinterogri se pot folosi i sinonime (doar opional precedate de cuvntul
rezervat AS) ale tabelelor referite n clauza FROM a instruciunii gazd (pentru
corelarea dinamic a tuplilor subinterogrii cu cei ai instruciunii gazd).
14) Subinterogrile al cror rezultat este o relaie cu mai multe atribute nu pot fi folosite
dect n clauzele WHERE i HAVING. n asemenea cazuri, operandul stng al
comparaiei trebuie s fie tot un tuplu (evident avnd aceeai aritate i tipuri
compatibile de date cu cel al rezultatului subinterogrii) care, sintactic, trebuie scris
ca o list nchis ntre paranteze, cu elementele separate prin virgule. Comparaiile
se fac desigur tuplu cu tuplu (i.e. simultan pe toate atributele acestora).
15) Atributele definite de o subinterogare nu pot fi folosite n clauza GROUP BY.
16) O subinterogare nu poate defini o reuniune (UNION) sau o interogare tabular
ncruciat (TRANSFORM).
Exemplul 29
Urmtoarea instruciune calculeaz abaterea (liniar a) duratei domniilor
de la media acestora (vezi figura 35):
(Q084)SELECT Domnii.*, La-DeLa AS Durata,
(SELECT Avg(La-DeLa) As DurataMedie
FROM Domnii) AS DurataMedie,
La-DeLa-DurataMedie AS Abatere
FROM Domnii ORDER BY La-DeLa, DeLa;
Urmtoarea instruciune calculeaz domniile mai scurte dect cel puin una
dintre domniile unuia din copiii domnitorului respectiv (vezi figura 36):
(Q085)SELECT * FROM Domnii AS D
WHERE (((La-DeLa)<Any
(SELECT La-DeLa AS Durata
FROM Domnii INNER JOIN Tata
ON Tata.Copil=Domnii.Domnitor
WHERE (Tata.Tata=D.Domnitor))))
ORDER BY D.DeLa;
De remarcat c MS Jet calculeaz ns eronat duala instruciunii de mai sus
(n care ANY este nlocuit cu ALL, pentru domniile mai scurte dect toate
cele ale copiilor domnitorului respectiv): probabil c subinterogarea nu se mai
calculeaz n acest caz dinamic, pentru fiecare tuplu al interogrii gazd n
parte, ci static, o singur dat nainte de calculul tuplilor interogrii gazd,
ceea ce elimin practic filtrul constituit de clauza WHERE i, n consecin,
rezultatul conine n mod eronat i domniile domnitorilor fr copii!
Urmtoarea instruciune calculeaz domniile strict mai lungi dect toate
cele ale copiilor lor ajuni domnitori la rndul lor (vezi figura 37):
(Q086)SELECT DISTINCT d.*
FROM Domnii AS d INNER JOIN Tata
ON d.Domnitor=Tata.Tata
WHERE ((La-DeLa)>All
(SELECT La-DeLa AS Durata
FROM Domnii INNER JOIN Tata
ON Tata.Copil=Domnii.Domnitor
WHERE (d.Domnitor=Tata.Tata)) AND EXISTS
51

(SELECT * FROM Domnii INNER JOIN Tata


ON Tata.Copil=Domnii.Domnitor
WHERE (d.Domnitor=Tata.Tata))=True)
ORDER BY DeLa;
Urmtoarea instruciune (fr subinterogri) calculeaz mulimea
perechilor (domnitor, copil) cu proprietatea c i copilul domnitorului a
ajuns domnitor la rndul lui (rezultatele sunt prezentate n figura 38):
(Q087)SELECT DISTINCT Domnitor, Copil
FROM (Domnii INNER JOIN Tata
ON Domnii.Domnitor = Tata.Tata)
INNER JOIN Domnii AS CopiiDomni
ON Tata.Copil = CopiiDomni.Domnitor
ORDER BY Domnitor, Copil;
Ea admite urmtoarea instruciune echivalent (construit cu ajutorul unei
subinterogri):
(Q088)SELECT DISTINCT Domnitor, Copil
FROM Domnii INNER JOIN Tata
ON Domnii.Domnitor = Tata.Tata
WHERE Copil IN
(SELECT Copil FROM Tata INNER JOIN Domnii
ON Tata.Copil = Domnii.Domnitor)
ORDER BY Domnitor, Copil;
Se observ n acest caz c nu mai este necesar redenumirea celei de-a doua
invocri a tabelei DOMNII i deci nici un atribut nu mai trebuie calificat cu
numele tabelei (nemaiexistnd nici o ambiguitate); n plus, subinterogarea pune
n eviden faptul c aceast problem are de fapt dou subprobleme
interconectate ntre ele: depistarea domnilor (de dou ori, o dat pentru tai i a
doua oar pentru copii) i combinarea rezultatelor pariale ale acestor
subprobleme folosind predicatul de apartenen adecvat.
Pentru a calcula dualul rezultatului de mai sus (i.e. mulimea domnitorilor care nu au avut nici un copil care s fii domnit i el la rndul su) pare evident, la
o prim privire superficial, c interogarea anterioar ofer imediat o soluie
banal (prin negarea predicatului IN):
(Q089)SELECT DISTINCT Domnitor, Copil
FROM Domnii INNER JOIN Tata
ON Domnii.Domnitor = Tata.Tata
WHERE Copil NOT IN
(SELECT Copil FROM Tata INNER JOIN Domnii
ON Tata.Copil = Domnii.Domnitor)
ORDER BY Domnitor, Copil;
La o analiz mai atent, se observ ns cu uurin c, de fapt, aceast
instruciune ofer tuplii (domnitor, copil) cu proprietatea c domnitor este tatl
copilului, iar copil nu figureaz ca domnitor la rndul lui (rspunznd deci la o
cu totul alt ntrebare, i.e. copiii de domni care n-au ajuns domnitori i taii lor!).
Soluia corect i elegant a acestei probleme folosind subinterogri este dat de
urmtoarea instruciune (vezi rezultatul n figura 39); de remarcat c ea
folosete dou subinterogri ncapsulate una n cealalt:

52

Domnitor
Vladislav II
Vlad epe
Dan I
Vlad Uzurpatorul
Mihail I
Radu II Pleuvul
Laiot Basarab
Dan II
Vlad Dracul
Basarab epelu
Dan II
Alexandru Aldea
Vlad Dracul
Vlad epe
Radu I
Mircea cel Btrn
Vladislav II
Radu cel Frumos
Nicolae Alexandru
Vladislav Vlaicu
Radu cel Mare
Vlad Clugrul
Mircea cel Btrn
Basarab I

DeLa
1442
1476
1384
1394
1418
1424
1473
1420
1443
1477
1426
1431
1436
1456
1377
1386
1447
1462
1352
1364
1495
1481
1396
1310

La Durata DurataMedie Abatere


1443
1
8.25 -7.25
1477
1
8.25 -7.25
1386
2
8.25 -6.25
1396
2
8.25 -6.25
1420
2
8.25 -6.25
1426
2
8.25 -6.25
1476
3
8.25 -5.25
1424
4
8.25 -4.25
1447
4
8.25 -4.25
1481
4
8.25 -4.25
1431
5
8.25 -3.25
1436
5
8.25 -3.25
1442
6
8.25 -2.25
1462
6
8.25 -2.25
1384
7
8.25 -1.25
1394
8
8.25 -0.25
1456
9
8.25
0.75
1473
11
8.25
2.75
1364
12
8.25
3.75
1377
13
8.25
4.75
1508
13
8.25
4.75
1495
14
8.25
5.75
1418
22
8.25 13.75
1352
42
8.25 33.75

Figura 35 Abaterea (liniar a) duratei primelor domnii Basarabe de la media lor

Domnitor
DeLa La
Nicolae Alexandru 1352 1364
Radu I
1377 1384
Dan I
1384 1386
Dan II
1420 1424
Dan II
1426 1431
Vlad Dracul
1436 1442
Vlad Dracul
1443 1447
Laiot Basarab
1473 1476

Domnitor
DeLa La
Basarab I
1310 1352
Mircea cel Btrn 1386 1394
Mircea cel Btrn 1396 1418
Vlad Clugrul
1481 1495
Figura 37 Primele domnii Basarabe
strict mai lungi dect toate cele ale
domnitorilor copii ai acestor domni

Figura 36 Primele domnii Basarabe mai


scurte dect cel puin una dintre domniile
unuia din copiii domnitorului respectiv

53

Domnitor
Basarab I
Dan I
Dan I
Dan II
Dan II
Laiot Basarab
Mircea cel Btrn
Mircea cel Btrn
Mircea cel Btrn
Mircea cel Btrn
Nicolae Alexandru
Nicolae Alexandru
Radu I
Radu I
Vlad Clugrul
Vlad Dracul
Vlad Dracul
Vlad Dracul

Copil
Nicolae Alexandru
Dan II
Vlad Uzurpatorul
Laiot Basarab
Vladislav II
Basarab epelu
Alexandru Aldea
Mihail I
Radu II Pleuvul
Vlad Dracul
Radu I
Vladislav Vlaicu
Dan I
Mircea cel Btrn
Radu cel Mare
Radu cel Frumos
Vlad Clugrul
Vlad epe

Domnitor
Alexandru cel Bun
Alexandru cel Bun
Alexandru cel Bun
Alexandru cel Bun
Alexandru cel Bun
Bogdan I
Bogdan II
Ilia
Ilia
Roman I

Copil
Bogdan II
Ilia
Petru Aron
Petru II
tefan II
Lacu
tefan cel Mare
Alexndrel
Roman II
Alexandru cel Bun

b) Moldova

a) ara Romneasc
Figura 38 Domnitori cu copiii lor ce au ajuns i ei domnitori la rndu-le

(Q090)SELECT DISTINCT Domnitor FROM Domnii


WHERE (((Domnitor) Not In
(SELECT DISTINCT Domnitor
FROM Domnii INNER JOIN Tata
ON Domnii.Domnitor = Tata.Tata
WHERE Copil IN
(SELECT Copil
FROM Tata INNER JOIN Domnii
ON Tata.Copil = Domnii.Domnitor))))
ORDER BY Domnitor;
Pentru a rezolva aceast problem fr a folosi subinterogri, lucrurile sunt
desigur mai complicate, fiind nevoie de doi pai: nti se salveaz (Q087) de
mai sus (de exemplu, chiar sub acest nume), dup care se execut asupra ei,
n al doilea pas, urmtoarea instruciune:
(Q091)SELECT DISTINCT Domnii.Domnitor
FROM Domnii LEFT JOIN Q087
ON Domnii.Domnitor = Q087.Domnitor
WHERE (((Q087.Domnitor) Is Null));
Urmtoarea instruciune calculeaz dinamic domnitorii care nu au avut
nici un copil care s fi ajuns i el domnitor la rndul su (vezi figura 39):
(Q092)SELECT DISTINCT D.Domnitor FROM Domnii AS D
WHERE (((Not Exists
(SELECT * FROM Domnii INNER JOIN Tata
ON Tata.Copil=Domnii.Domnitor
WHERE (Tata.Tata=D.Domnitor)))=True))
ORDER BY D.Domnitor;

54

Domnitor
Alexandru Aldea
Basarab epelu
Mihail I
Radu cel Frumos
Radu cel Mare
Radu II Pleuvul
Vlad epe
Vlad Uzurpatorul
Vladislav II
Vladislav Vlaicu

Domnitor
Alexndrel
Iuga Vod
Lacu
Petru Aron
Petru II
Petru Muat
Roman II
tefan cel Mare
tefan I
tefan II

Domnitor
Basarab I
Dan I
Dan II
Laiot Basarab
Mircea cel Btrn
Nicolae Alexandru
Radu I
Vlad Clugrul
Vlad Dracul

Domnitor
Alexandru cel Bun
Ilia
Bogdan I
Bogdan II
Roman I

a) ara Romneasc
b) Moldova
Figura 40 Domnitori cu cel puin un copil ajuns
i el domnitor la rndul su

a) ara Romneasc
b) Moldova
Figura 39 Domnitori fr vreun copil
care s fi domnit i el la rndul su

Urmtoarea instruciune calculeaz (tot dinamic) domnitorii care au avut


cel puin un copil ajuns i el domnitor la rndul su (vezi figura 40):
(Q093)SELECT DISTINCT D.Domnitor FROM Domnii AS D
WHERE (((Exists
(SELECT * FROM Domnii INNER JOIN Tata
ON Tata.Copil=Domnii.Domnitor
WHERE (Tata.Tata=D.Domnitor)))=True))
ORDER BY D.Domnitor;
Urmtoarea instruciune calculeaz (cu dou subinterogri) domnitorii ce au
domnit mai mult dect media totalurilor anilor de domnie ai tuturor
domnitorilor (figura 41 prezint rezultatul ei pentru bd din figura 1):
(Q094)SELECT Sum(La-DeLa) AS Total, Domnitor
FROM Domnii GROUP BY Domnitor
HAVING (((Sum(La-DeLa))>
(SELECT Avg(Totaluri) FROM
(SELECT Domnitor, Sum(La-DeLa) AS Totaluri
FROM Domnii GROUP BY Domnitor))))
ORDER BY Sum(La-DeLa) DESC, Domnitor;
Urmtoarea instruciune calculeaz (din nou dinamic) domniile mai scurte
dect cel puin o domnie a unuia dintre copiii domnitorului respectiv
(rezultatul ei pentru bd din figura 1 este prezentat n figura 42):
(Q095)SELECT DISTINCT d.Domnitor, d.La-d.DeLa
AS Durata
FROM Domnii AS d INNER JOIN Tata
ON d.Domnitor=Tata.Tata
WHERE (((Exists
(SELECT c.Domnitor
FROM Domnii AS c INNER JOIN Tata
ON c.Domnitor=Tata.Copil
WHERE d.Domnitor=Tata.Tata
GROUP BY Domnitor
HAVING max(c.La-c.DeLa) >
d.La-d.DeLa))=True))
ORDER BY d.Domnitor, d.La-d.DeLa DESC;
55

Total
Domnitor
42 Basarab I
30 Mircea cel Btrn
14 Vlad Clugrul
13 Radu cel Mare
13 Vladislav Vlaicu
12 Nicolae Alexandru
11 Radu cel Frumos

Domnitor
Durata
Dan I
2
Dan II
5
Dan II
4
Laiot Basarab
3
Nicolae Alexandru
12
Radu I
7
Vlad Dracul
6
Vlad Dracul
4

Figura 41 Domnitori Basarabi


ce au domnit n total mai mult
dect media totalurilor domniilor
per domni

Figura 42 Domnii Basarabe mai


scurte dect cea mai lung
domnie a unui fiu al acelui domn

3.1.3 Operatorul UNION


Operatorul UNION reunete rezultatele a dou sau mai multe interogri i/sau
tabele; sintaxa sa este urmtoarea:
[TABLE] interog1 UNION [ALL][TABLE]
interog2 [UNION [ALL][TABLE] interog3 []]
unde operanzii interog1, interog2, interog3, sunt fiecare:
ori o instruciune SELECT
ori numele unei tabele virtuale (view, vezi 3.3.1)
ori numele unei relaii (caz n care acesta trebuie precedat de cuvntul rezervat
TABLE).
Observaii:
1) n mod implicit, rezultatul instruciunii UNION nu conine duplicate; dac totui se
dorete acest lucru, atunci trebuie folosit predicatul ALL (naintea numelui oricrui
operand ai crui tupli se doresc adugai cu toii la rezultat, indiferent dac dubleaz
sau nu tuplii existeni).
2) Toi operanzii UNION trebuie s aib acelai cardinal al listei int (respectiv
mulimii de atribute ce alctuiesc schema tabelei); dimensiunea sau tipul de dat al
componentelor acestora nu trebuie ns neaprat s fie aceeai pentru toi operanzii.
3) Sinonimele se pot folosi doar n instruciuni SELECT (altfel ele sunt ignorate).
4) Fiecare operand poate avea clauze GROUP BY i HAVING.
5) Referirile la atribute n clauza ORDER BY trebuie s foloseasc numele
corespunztoare acestora din primul operand de tip instruciune SELECT.
6) Pentru ordonarea tuplilor rezultatului, se poate folosi o clauz ORDER BY n
ultimul operand de tip instruciune SELECT.
7) Instruciunile de tip:
SELECT tabela1.coloana1, tabela2.coloana2
FROM tabela1 LEFT JOIN tabela2
ON tabela1.coloana1 opcomp tabela2.coloana2;
sunt echivalente cu:
SELECT tabela1.coloana1, tabela2.coloana2 FROM tabela1, tabela2
WHERE (tabela1.coloana1 opcomp tabela2.coloana2) UNION
SELECT tabela1.coloana1, NULL AS coloana2 FROM tabela1
WHERE (tabela1.coloana1 NOT IN
(SELECT tabela2.coloana2 FROM tabela2));
Similar, instruciunile de tip:
SELECT tabela1.coloana1, tabela2.coloana2
FROM tabela1 RIGHT JOIN tabela2
ON tabela1.coloana1 opcomp tabela2.coloana2;
56

sunt echivalente cu:


SELECT tabela1.coloana1, tabela2.coloana2 FROM tabela1, tabela2
WHERE (tabela1.coloana1 opcomp tabela2.coloana2) UNION
SELECT NULL AS coloana1, tabela2.coloana2 FROM tabela2
WHERE (tabela2.coloana2 NOT IN
(SELECT tabela1.coloana1 FROM tabela1));
Exemplul 30 Reuniunea tabelelor TATA i MAMA (al crui rezultat pentru
bd din figura 1 este oferit n figura 43) poate fi implementat de urmtoarea
instruciune:
(Q096)TABLE Tata UNION TABLE Mama;
Dac se dorete i redenumirea coloanelor (n acest caz din Tata n
Printe) i ordonarea tuplilor exact ca n figura 43, atunci instruciunea
devine:
(Q097)SELECT Tata AS Printe, Copil FROM Tata UNION
TABLE Mama
ORDER BY Copil, Printe;
Prima jumtate a instruciunii (Q045) din exemplul 13 (i.e. cea
corespunznd operatorului RIGHT JOIN) este echivalent cu instruciunea:
(Q098)SELECT DISTINCT Domnitor, Mama
FROM Mama, Domnii
WHERE (Domnii.Domnitor=Mama.Copil)
UNION
SELECT DISTINCT Domnitor, NULL AS Mama
FROM Domnii WHERE (Domnitor Not In
(SELECT Copil FROM Mama))
ORDER BY Domnitor;
A doua jumtate (i.e. cea corespunznd operatorului LEFT JOIN), este
echivalent cu instruciunea:
(Q099)SELECT DISTINCT Domnitor, Tata
FROM Domnii, Tata
WHERE (Domnii.Domnitor=Tata.Copil)
UNION
SELECT DISTINCT Domnitor, NULL AS Tata
FROM Domnii WHERE (Domnitor Not In
(SELECT Copil FROM Tata))
ORDER BY Domnitor;
Echivalentul propriu-zis al instruciunii (Q045) din exemplul 13 este deci
urmtoarea instruciune (rezultatul pentru figura 1 este cel din figura 10):
(Q100)SELECT DISTINCT Domnitor, Mama, Tata
FROM Mama, Domnii, Tata
WHERE (Domnii.Domnitor=Mama.Copil AND
Domnii.Domnitor=Tata.Copil)
UNION SELECT DISTINCT Domnitor, NULL AS Mama, Tata
FROM Domnii, Tata
WHERE (Domnii.Domnitor=Tata.Copil AND
Domnitor Not In
(SELECT Copil FROM Mama))
UNION SELECT DISTINCT Domnitor, Mama, NULL AS Tata
FROM Mama, Domnii
WHERE (Domnii.Domnitor=Mama.Copil AND
Domnitor Not In
(SELECT Copil FROM Tata))
57

UNION SELECT DISTINCT Domnitor, NULL AS Mama,


NULL AS Tata
FROM Domnii
WHERE (Domnitor Not In
(SELECT Copil FROM Tata) AND
Domnitor Not In
(SELECT Copil FROM Mama))
ORDER BY Domnitor;
De notat c operatorii IN i UNION nu se pot compune; ca atare,
urmtoarea instruciune, similar anterioarei i evident mai elegant, nu este
acceptat nici mcar sintactic de MSJetSQL:
(Q101)SELECT DISTINCT Domnitor, Mama, Tata
FROM Mama, Domnii, Tata
WHERE (Domnii.Domnitor=Mama.Copil AND
Domnii.Domnitor=Tata.Copil)
UNION SELECT DISTINCT Domnitor, NULL AS Mama, Tata
FROM Domnii, Tata
WHERE (Domnii.Domnitor=Tata.Copil AND
Domnitor Not In
(SELECT Copil FROM Mama))
UNION SELECT DISTINCT Domnitor, Mama, NULL AS Tata
FROM Mama, Domnii
WHERE (Domnii.Domnitor=Mama.Copil AND
Domnitor Not In
(SELECT Copil FROM Tata))
UNION SELECT DISTINCT Domnitor, NULL AS Mama,
NULL AS Tata
FROM Domnii
WHERE (Domnitor Not In
((SELECT Copil FROM Tata)
UNION
(SELECT Copil FROM Mama))
ORDER BY Domnitor;
De notat de asemenea puterea deosebit pe care o au aceti doi operatori
derivai (i.e. LEFT i RIGHT JOIN), att fiecare n parte, ct i, mai ales,
compui mpreun: n absena lor, efortul de programare se dubleaz nu doar
cu fiecare apariie a lor, dar i cu fiecare compunere a lor n parte!

58

Printe
Mircea cel Btrn
Nicolae Alexandru
Clara
Nicolae Alexandru
Clara
Laiot Basarab
Radu I
Dan I
Nicolae Alexandru
Maria
Dan II
Radu cel Frumos
Mircea cel Btrn
Vlad epe
Vlad Dracul
Mtu tefan cel Mare
Radu I
Radu cel Mare
Basarab epelu
Basarab I
Vlad Dracul
Mtu tefan cel Mare
Vlad Clugrul
Radu cel Mare
Nicolae Alexandru
Maria
Mircea cel Btrn
Radu cel Mare
Neagoe Basarab
Neagoe Basarab
Neagoe Basarab
Vlad epe
Elena
Vlad Dracul
Mtu tefan cel Mare
Vlad Clugrul
Mircea cel Btrn
Vlad Dracul
Mtu tefan cel Mare
Dan I
Dan II
Nicolae Alexandru
Maria

Copil
Alexandru Aldea
Ana
Ana
Anca
Anca
Basarab epelu
Dan I
Dan II
Elisabeta
Elisabeta
Laiot Basarab
Maria Voichia
Mihail I
Mihnea cel Ru
Mircea
Mircea
Mircea cel Btrn
Mircea Ciobanul
Neagoe Basarab
Nicolae Alexandru
Radu cel Frumos
Radu cel Frumos
Radu cel Mare
Radu de la Afumai
Radu I
Radu I
Radu II Pleuvul
Radu Paisie
Ruxandra
Stanca
Teodosie
Vlad
Vlad
Vlad Clugrul
Vlad Clugrul
Vlad cel Tnr
Vlad Dracul
Vlad epe
Vlad epe
Vlad Uzurpatorul
Vladislav II
Vladislav Vlaicu
Vladislav Vlaicu

Figura 43 Reuniunea tabelelor TATA i MAMA din figura 1

59

3.1.4 Instruciunea TRANSFORM


Exemplul 31 Fie tabela CTITORII(CtitorCtitorieAn) din figura 44a (creat
cu ajutorul instruciunii SQL cerute de problema 5), care memoreaz cteva
dintre cele mai importante ctitorii ale primilor Muatini (respectiv anul
ctitoririi, unde prin ctitor se nelege n general binefctor; de exemplu,
nu doar cel care construiete sau reconstruiete o ctitorie, ci i cel care o
picteaz, i face daruri, o repar etc.). Se observ c este nevoie de cheia tripl
CtitorCtitorieAn deoarece, n general, un ctitor este binefctorul mai
multor ctitorii, de mai multe ori (chiar i n acelai an), o ctitorie este datoare
mai multor ctitori, iar n acelai an, un binefctor poate ctitorii de mai multe
ori o aceeai ctitorie (pentru simplitate, este memorat aici doar anul n care a
nceput ctitoria). Desigur c, pentru a vedea mai uor ce ctitori au fost
binefctorii fiecrei ctitorii, este nevoie de ordonarea primelor dou coloane
n ordine invers, ca n figura 44b, evident conform instruciunii urmtoare:
(Q102)SELECT * FROM Ctitorii
ORDER BY Ctitorie, Ctitor;
Adesea ns, este preferabil o prezentare alternativ a acestor date mult
mai clar i sugestiv, care nglobeaz ambele ordonri de mai sus, precum
cea din figura 44c. O asemenea tabel se poate evident obine imediat i
ntotdeauna din orice relaie cu minim 3 atribute (printr-un procedeu zis de
tabulare ncruciat), schimbnd semnificaia celor dou axe ortogonale
astfel: se pstreaz valorile distincte ale unuia din atributele tabelei iniiale
drept ax y (atributul respectiv fiind primul pe axa x; n exemplul de fa,
este evident vorba de Ctitor); n continuarea axei x, se nlocuiesc celelalte
dou atribute iniiale rmase cu cte unul nou pentru fiecare dintre valorile
distincte ale unuia dintre acestea (numele acestor noi atribute fiind exact
valorile atributului iniial ales pentru aceasta; n cazul de fa, este evident
vorba de Ctitorie); n sfrit, valorile singurului atribut iniial rmas (An n
acest caz) constituie n mod natural valorile noilor atribute generate: la
intersecia oricrei perechi (x,y) se memoreaz ori valoarea NULL (dac
relaia iniial nu conine un tuplu care s includ aceast pereche), ori
valoarea corespunztoare a acestui atribut.
Tabela 44c se obine din 44a cu urmtoarea instruciune TRANSFORM
(n care First ar putea fi nlocuit cu oricare alt funcie de agregare):
(Q103)TRANSFORM First(An) AS AnBinefacere
SELECT Ctitor
FROM Ctitorii
GROUP BY Ctitor
PIVOT Ctitorie;
Instruciunea TRANSFORM creeaz o interogare tabular ncruciat. Sintaxa este:
TRANSFORM fciedeagregare instrSELECT
PIVOT atribpivot [IN (valoare1[, valoare2[, ...]])]
Semnificaia variabilelor folosite este urmtoarea:
Variabil
Descriere
fciedeagregare O funcie de agregare SQL aplicat unuia din atributele tabelelor
referite n clauza FROM a instrSELECT.
instrSELECT
O instruciune SELECT.
atribpivot
Un atribut (fundamental sau derivat) sau o expresie evaluabil la un
atribut dintre cele ale tabelelor din clauza FROM a instrSELECT.
valoare1,
Valori folosite pentru crearea noilor atribute n procesul de tabulare
valoare2
ncruciat.
60

Observaii:
1) Lista int a instrSELECT conine atributele tabelei iniiale ale cror valori vor
constitui axa y a tabulrii ncruciate.
2) Adesea este util ca lista int a instrSELECT s conin i un atribut calculat cu
ajutorul fciedeagregare care s ofere rezultatul agregrii respective i pentru
fiecare din liniile relaiei generate prin tabulare ncruciat (de exemplu, dac
funcia de agregare este Sum, s-ar putea obine astfel pentru fiecare linie i suma
tuturor sumelor din noile coloane generate).
3) Valorile atribpivot sunt folosite drept numele noilor atribute generate.
4) Ordinea noilor atribute generate este cea cresctoare a valorilor atribpivot.
5) Dac atribpivot conine i valori nule, atunci se va genera corespunztor i un
nou atribut numit <> (care este plasat naintea tuturor celorlalte).
6) Lista valoare1, valoare2, ... a clauzei opionale IN se poate folosi pentru a
elimina din valorile atribpivot pe cele nedorite sau, dimpotriv, pentru a aduga
noi valori, inexistente n momentul execuiei instruciunii TRANSFORM (de
exemplu, pentru a asigura mereu o aceeai structur a relaiei generate,
indiferent de valorile de moment ale atribpivot, necesar unui raport bazat pe
aceast relaie).
7) instrSELECT trebuie s conin obligatoriu clauza GROUP BY (evident,
deoarece fciedeagregare oblig la aceasta!); n schimb, n mod inexplicabil, ea
nu poate conine clauza HAVING!!
8) instrSELECT poate include subinterogri doar n clauza WHERE.
9) Rezultatul unei tabulri ncruciate se poate afia/tipri, dar nu poate fi salvat ca
o tabel permanent! (i.e. instrSELECT nu poate fi de tip SELECT ... INTO).
Exemplul 32 Figura 45a prezint tabela BTLII (creat cu ajutorul
instruciunii SQL cerute de problema 5 i avnd cheia format din toate cele
6 atribute ale sale!) ce memoreaz principalele btlii duse de domnitorii
Basarabi n primele dou secole de istorie ale dinastiei lor.
Urmtoarea instruciune de tabulare ncruciat calculeaz, pentru fiecare
domnitor, totalul btliilor mpotriva fiecrui duman n parte (rezultatul
este prezentat n figura 45b):
(Q104)TRANSFORM Count(Btlii.An) AS NrBtlii
SELECT Domn, Count(An) AS Total
FROM Btlii
GROUP BY Domn
PIVOT Duman;
De remarcat c dac n instruciunea de mai sus s-ar nlocui An cu
Victorie, rezultatul ar fi absolut acelai (deoarece Count numr toate
apariiile nenule ale valorilor, distincte sau nu); dimpotriv (din cauza
valorilor nule pe care Count le ignor), dac s-ar nlocui An cu Loc sau
Inamic, doar schema rspunsului i coninutul primei sale coloane ar fi
aceleai, n timp ce coninutul celorlalte ar diferi.
Dac se dorete o privire mai detaliat asupra acestor totaluri, n sensul
defalcrii lor pe victorii, respectiv nfrngeri, instruciunea necesar este
evident urmtoarea (rezultatul ei este prezentat n figura 45c):
(Q105)TRANSFORM Count(An) AS NrBtlii
SELECT Domn, Victorie, Count(An) AS Total
FROM Btlii GROUP BY Domn, Victorie
PIVOT Duman;

61

CTITORII (CtitorCtitorieAn) CtitorNume


Ctitor
Ctitorie
An
Alexandru cel Bun Bistria
1407
Alexandru cel Bun Moldovia 1402
Alexandru cel Bun Neam
1420
Alexandru cel Bun Rdui
1410
Bogdan I
Rdui
1359
Petru Muat
Neam
1380
Petru Rare
Bistria
1532
Petru Rare
Moldovia 1532
Petru Rare
Neam
1533
Petru Rare
Probota
1530
Petru Rare
Vorone
1534
tefan cel Mare
Bistria
1485
tefan cel Mare
Neam
1497
tefan cel Mare
Putna
1466
tefan cel Mare
Rdui
1479
tefan cel Mare
Vorone
1488
a) tabela iniial

Q102
Ctitor
Alexandru cel Bun
Petru Rare
tefan cel Mare
Alexandru cel Bun
Petru Rare
Alexandru cel Bun
Petru Muat
Petru Rare
tefan cel Mare
Petru Rare
tefan cel Mare
Alexandru cel Bun
Bogdan I
tefan cel Mare
Petru Rare
tefan cel Mare

Ctitorie
Bistria
Bistria
Bistria
Moldovia
Moldovia
Neam
Neam
Neam
Neam
Probota
Putna
Rdui
Rdui
Rdui
Vorone
Vorone

An
1407
1532
1485
1402
1532
1420
1380
1533
1497
1530
1466
1410
1359
1479
1534
1488

b) tabela iniial sortat nti dup ctitorii

Ctitor
Bistria Moldovia Neam Probota Putna Rdui Vorone
Alexandru cel Bun
1407
1402 1420
1410
Bogdan I
1359
Petru Muat
1380
Petru Rare
1532
1532 1533
1530
1534
tefan cel Mare
1485
1497
1466
1479
1488
c) tabela obinut din cea iniial prin tabulare ncruciat
Figura 44 Cteva dintre cele mai importante ctitorii ale primilor Muatini

3.2 Sublimbajul de actualizare


3.2.1 Instruciunea SELECTINTO
Instruciunea SELECT...INTO are ca efect salvarea pe disc a rezultatului interogrii
SELECT ntr-o nou tabel. Sintaxa ei (similar cu cea a instruciunii SELECT, cu
excepia clauzei suplimentare INTO i a subclauzei opionale IN a acesteia) este
urmtoarea: SELECT listaint INTO tabel [IN bdextern]
FROM expresietabele [clauzeopionale]
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
listaint
Expresie rezultnd ntr-o list de nume unice de atribute (exact ca i
n cazul instruciunii SELECT) care vor constitui schema noii tabel.
tabel
Numele noii tabele create prin salvarea rezultatelor interogrii
SELECT.
bdextern
Numele bd (alta dect cea curent) n care se dorete crearea tabel.
expresietabele (Exact ca i la instruciunea SELECT) coninutul clauzei FROM.
clauzeopionale Eventualele clauze WHERE, GROUP BY, HAVING, ORDER BY
(exact ca la instruciunea SELECT, n aceeai ordine).
62

An
Domn
1324 Basarab I
1328 Basarab I
1330 Basarab I
1360 Nicolae Alexandru
1368 Vladislav Vlaicu
1369 Vladislav Vlaicu
1371 Vladislav Vlaicu
1377 Radu I
1386 Mircea cel Btrn
1388 Mircea cel Btrn
1389 Mircea cel Btrn
1391 Mircea cel Btrn
1393 Mircea cel Btrn
1394 Mircea cel Btrn
1395 Mircea cel Btrn
1395 Mircea cel Btrn
1396 Mircea cel Btrn
1396 Mircea cel Btrn
1397 Mircea cel Btrn
1400 Mircea cel Btrn
1401 Mircea cel Btrn
1403 Mircea cel Btrn
1404 Mircea cel Btrn
1417 Mircea cel Btrn
1420 Mihail I
1423 Dan II
1425 Dan II
1427 Dan II
1428 Dan II
1429 Dan II
1442 Vlad Dracul
1444 Vlad Dracul
1445 Vlad Dracul
1447 Vlad Dracul
1448 Vlad epe
1448 Vlad epe
1448 Vladislav II
1456 Vlad epe
1457 Vlad epe
1460 Vlad epe
1461 Vlad epe
1462 Vlad epe
1462 Vlad epe
1462 Vlad epe
1462 Vlad epe
1469 Radu cel Frumos
1471 Radu cel Frumos
1473 Radu cel Frumos
1474 Radu cel Frumos
1475 Laiot Basarab
1476 Vlad epe
1477 Vlad epe
1481 Basarab epelu
1482 Basarab epelu

Duman
ttari
ttari
Posada
unguri
ttari
Ialomia
unguri
Vidin
turci
Crmen
turci
unguri
Severin
unguri
Hrova
turci
Isaccea
turci
turci
Vidin
turci
Rovine
turci
Turnu
unguri
Curtea de Arge turci
Nicopole
turci
Dmbovia
munteni
turci
moldoveni
turci
Chilia
turci
Silistra
turci
turci
turci
turci
Vidin
turci
turci
Golubac
turci
Chilia
moldoveni
unguri
Varna
turci
turci
transilvneni
munteni
transilvneni
Kossovopolje
turci
munteni
Braov
transilvneni
Braov
transilvneni
Giurgiu
turci
munteni
Trgovite
turci
Brila
turci
Turnu
turci
moldoveni
Soci
moldoveni
Vodnu
moldoveni
moldoveni
Vaslui
moldoveni
munteni
Snagov
munteni
Rmnic
moldoveni
Crciuna
moldoveni
Loc

Inamic

Carol Robert de Anjou


Nicolae Lackfi

Ludovic cel Mare

Firuz-bey
Baiazid Ildirim
Sigismund de Luxemburg
Vlad Uzurpatorul
Baiazid Ildirim
Vlad Uzurpatorul
Iuga Vod
Evrenos-bey

Radu II Pleuvul
Alexandru cel Bun
Vladislav I
Murad II
Iancu de Hunedoara
Vladislav II
Iancu de Hunedoara
Vladislav II
Dan cel Tnr
Radu cel Frumos
Mahomed II
Mahomed II
tefan cel Mare
tefan cel Mare
tefan cel Mare
tefan cel Mare
tefan cel Mare
Laiot Basarab
Laiot Basarab
tefan cel Mare
tefan cel Mare

Figura 45a Btliile purtate de primii domnitori Basarabi:

63

Victorie
Yes
Yes
Yes
Yes
Yes
Yes
No
Yes
Yes
Yes
Yes
Yes
No
No
No
No
No
Yes
Yes
Yes
Yes
Yes
Yes
No
No
Yes
Yes
Yes
No
No
Yes
No
Yes
No
Yes
No
No
Yes
Yes
Yes
Yes
No
Yes
Yes
No
No
No
No
No
No
Yes
No
No
No

BTLII Domn Nume

Domn
Total moldoveni munteni ttari transilvneni turci unguri
Basarab I
3
2
1
Basarab epelu
2
2
Dan II
5
1
4
Laiot Basarab
1
1
Mihail I
1
1
Mircea cel Btrn
16
1
1
12
2
Nicolae Alexandru
1
1
Radu cel Frumos
4
4
Radu I
1
1
Vlad Dracul
4
1
2
1
Vlad epe
12
5
3
4
Vladislav II
1
1
Vladislav Vlaicu
3
2
1
Figura 45b Totalul btliilor purtate de primii Basarabi, clasificate pe dumani

Domn
Victorie Total moldoveni munteni ttari transilvneni turci unguri
Basarab I
Yes
3
2
1
Basarab epelu
No
2
2
Dan II
Yes
3
3
Dan II
No
2
1
1
Laiot Basarab
No
1
1
Mihail I
No
1
1
Mircea cel Btrn
Yes
10
1
1
7
1
Mircea cel Btrn
No
6
5
1
Nicolae Alexandru
Yes
1
1
Radu cel Frumos
No
4
4
Radu I
Yes
1
1
Vlad Dracul
Yes
2
1
1
Vlad Dracul
No
2
1
1
Vlad epe
Yes
8
3
2
3
Vlad epe
No
4
2
1
1
Vladislav II
No
1
1
Vladislav Vlaicu
Yes
2
1
1
Vladislav Vlaicu
No
1
1
Figura 45c Totalul victoriilor i nfrngerilor primilor Basarabi, pe dumani

Observaii:
1) La salvarea noii tabele, atributele acesteia motenesc doar tipul de dat i
dimensiunea atributelor iniiale din care provin (respectiv cele standard corespunztoare rezultatelor pentru atribute calculate). Evident c orice alte modificri ale schemei sale se pot face ns ulterior cu ajutorul instruciunilor LDD
ALTER TABLE, CREATE INDEX i DROP.
2) Spre deosebire de instruciunea LDD similar CREATE TABLE (destinat n
special crerii tabelelor fundamentale, dei aceasta nu este obligatoriu), care
creeaz o tabel vid, SELECT...INTO este evident destinat crerii de tabele
derivate i specificrii simultane a cte unui coninut (n general nevid) al lor.
64

COPII (Copil) Copil Nume, Tata Nume, Mama Nume


Copil
Tata
Mama
Alexndrel
Ilia
Alexandru
tefan cel Mare
Evdochia
Alexandru cel Bun
Roman I
Anastasia
Bogdan
Roman I
Bogdan II
Alexandru cel Bun
Bogdan III
tefan cel Mare
Maria Voichia
Bogdnel
tefan cel Mare
Maria de Mangop
Elena
tefan cel Mare
Evdochia
Ilia
Alexandru cel Bun Ana Neaca
Ilie
tefan cel Mare
Maria de Mangop
Lacu
Bogdan I
Margareta Muata
Bogdan I
Maria
tefan cel Mare
Maria Voichia
Mtu tefan cel Mare Alexandru cel Bun
Petru Aron
Alexandru cel Bun Mariana
Petru II
Alexandru cel Bun
Petru Ptracu
tefan cel Mare
Evdochia
Petru Rare
tefan cel Mare
Maria Rare din Hrlu
Roman II
Ilia
tefan cel Mare
Bogdan II
Maria Oltea Basarab
tefan II
Alexandru cel Bun
Figura 46 Copiii Muatini din figura 2 avnd tatl cunoscut

3) SELECT...INTO este folosit pentru crearea de fotografii ale coninutului bd,


copii de siguran, arhive, tabele derivate pentru calcule intermediare, forme sau
rapoarte, precum i pentru exportul datelor n alte bd (externe) dect cea curent.
Exemplul 33 Urmtoarea instruciune creeaz o tabel numit COPII (vezi
figura 46) ce conine toi copii din tabela TATA (din figura 2), taii lor, iar
acolo unde aceast informaie este cunoscut i mamele acestora:
(Q106)SELECT Tata.Copil, Tata, Mama INTO Copii
FROM Tata LEFT JOIN Mama
ON Tata.Copil = Mama.Copil
ORDER BY Tata.Copil;
De remarcat c, aa cum era de ateptat, rezultatul nu conine i copiii
pentru care sunt cunoscute doar mamele, nu i taii.
Urmtoarea instruciune, care are drept rezultat o tabel rspuns identic
cu cea din figura 46, ns fr tuplii pentru care mamele sunt cunoscute i
fr a crea tabela temporar COPII, calculeaz submulimea copiilor avnd
mama necunoscut i constituie un exemplu al celui mai elegant i eficient
mod general de calcul n SQL a diferenei a dou mulimi:
(Q119)SELECT Tata.Copil, Tata, Mama
FROM Tata LEFT JOIN Mama
ON Tata.Copil = Mama.Copil
WHERE (Mama Is Null)
ORDER BY Tata.Copil;
65

3.2.2 Instruciunea INSERT INTO


Instruciunea INSERT INTO adaug tuplii rezultat ai unei interogri la o tabel.
Tuplii adugai pot fi rezultatul unei interogri propriu-zise de tip SELECT (prima
form a sintaxei); pentru adugarea unui singur tuplu (ale crui valori trebuie
specificate) se poate folosi a doua form a sintaxei sale; acestea sunt urmtoarele:
INSERT INTO int [(atrib1[, atrib2[, ...]])] [IN bdextern]
SELECT listaint FROM expresietabele [clauzeopionale], respectiv:
INSERT INTO int [(atrib1[, atrib2[, ...]])] [IN bdextern]
VALUES (valoare1[, valoare2[, ...]])
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
int
Numele unei tabele sau view (vezi 3.3.1) la care se vor aduga noii
tupli.
atrib1,
Numele atributelor din schema int crora listaint respectiv lista
atrib2,...
valoare1, valoare2,... le furnizeaz valori pentru toi tuplii de adugat.
listaint
Expresie rezultnd ntr-o list de nume unice de atribute (exact ca i
n cazul instruciunii SELECT) care trebuie s corespund ca numr
(i tip compatibil de dat) listei atrib1, atrib2,...
bdextern
Numele bd (alta dect cea curent) n care este memorat tabel.
expresietabele (Exact ca i la instruciunea SELECT) coninutul clauzei FROM
definind int.
clauzeopionale Eventualele clauze WHERE, GROUP BY, HAVING, ORDER BY
(exact ca la instruciunea SELECT, n aceeai ordine).
valoare1,
Valorile tuplului de inserat pentru atributele atrib1, atrib2,... n exact
valoare2,...
aceast ordine; valorile de tip ir de caractere trebuie nchise ntre
apostroafe.
Observaii:
1) Tuplii sunt adugai la sfritul tabelelor int.
2) Dac int este o interogare, atunci sunt adugai tuplii corespunztori n toate
tabelele implicate (evident cu condiia ca rezultatul interogrii s fie actualizabil;
n caz contrar, nu se adaug nici un tuplu! Sunt evident neactualizabile
urmtoarele: cele care conin predicate DISTINCT, DISTINCTROW, TOP sau
clauza GROUP BY; produsele carteziene, reuniunile; tabulrile ncruciate;
atributele calculate sau cele de tip AUTONUMBER etc.).
3) Pentru atributele int nespecificate n lista atrib1, atrib2,... sunt automat
inserate valorile lor implicite, iar atunci cnd acestea nu sunt precizate, se
insereaz valoarea NULL; tipul de dat AUTONUMBER are ntotdeauna
asociat o valoare implicit (i anume urmtoarea valoare disponibil n acel
moment, fie c ea este generat incremental ori aleator).
4) Adugarea tuplilor reuete doar dac nu sunt nclcate constrngerile de
integritate ale tabelelor int. De exemplu:
dac tabelele int au definite chei primare, atunci valorile pentru acestea
trebuie s fie unice i nu NULL
similar, nu se pot dubla valori pentru atribute declarate UNIQUE
trebuie specificate obligatoriu valori pentru toate atributele cu proprietatea
Required (i pentru care nu sunt definite valori implicite)
referinele de integritate nu pot fi nclcate (de exemplu, n bd din figura 1,
nu se poate insera n Domnitor, Tata, Mama sau oricare din cele dou atribute
Copil nici o valoare care s nu existe deja printre cele ale Nume)
nu pot fi nclcate regulile de validare ale atributelor (de exemplu, dac
DeLa i La ar avea asociat regula BETWEEN 1300 AND 2000, atunci
66

orice tuplu avnd o valoare n afara acestui interval pentru oricare din aceste
dou atribute ar fi respins).
5) Dac se folosete a doua form sintactic fr lista atrib1, atrib2,..., atunci lista
valoare1, valoare2,... trebuie s includ cte o valoare pentru fiecare dintre
atributele int (n caz contrar, adugarea tuplului eueaz).
Exemplul 34 S completm tabela COPII din figura 46 cu toi ceilali copii
Muatini cunoscui din figura 2, plus Ana, cel de-al noulea copil al lui
tefan cel Mare, nelegitim, nhumat la mnstirea Bistria, a crui mam, an
natere i deces nu se cunosc (i care nu apare n tabelele PERSOANE i
TATA din figura 2). Pentru a aduga <Ana lui tefan, tefan cel Mare> este
nevoie de instruciunea urmtoare:
(Q107)INSERT INTO Copii ( Copil, Tata )
VALUES (Ana lui tefan, tefan cel Mare);
Urmtoarea instruciune adaug la tabela COPII i copiii (din MAMA) care
nu au tat cunoscut:
(Q108)INSERT INTO Copii ( Copil, Mama )
SELECT Mama.Copil, Mama.Mama
FROM Mama LEFT JOIN Tata
ON Mama.Copil = Tata.Copil
WHERE (((Tata.Copil) Is Null));
Se observ c n figura 47 (care prezint noul coninut al COPII obinut ca
rezultat al celor dou instruciuni INSERT INTO de mai sus), fa de figura
46, au mai fost adugai ase copii (Ana lui tefan, Iuga Vod, Petru Muat,
Roman I, Sor Petru Muat? i tefan I) i c acum tabela COPII conine
toi copiii Muatini din figura 2, plus Ana lui tefan cel Mare.
3.2.3 Instruciunea UPDATE
Sintaxa instruciunii pentru modificarea valorilor atributelor este urmtoarea:
UPDATE int SET atrib1 = nouvaloare1 [, atrib2 = nouvaloare2 [,...]]
[clauzWHERE];
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
int
Numele unei tabele sau interogri salvate ai crei tupli se modific.
atrib1, atrib2,... Numele atributelor din schema int ale cror valori se modific
conform nouvaloare1, nouvaloare2,....
nouvaloare1,
Expresii evaluabile (n contextul instruciunii) la valori avnd tipul de
nouvaloare2,... dat identic sau compatibil cu cel al atrib1, atrib2,....
clauzWHERE Clauz WHERE (vezi 3.1.1.3) pe care trebuie s o satisfac tuplii ale
cror valori sunt modificate.
Observaii:
1) Dac int este o interogare, atunci rezultatul acesteia trebuie s fie actualizabil;
n caz contrar, nu se modific nici un tuplu! (pentru exemple de interogri neactualizabile vezi observaia 2 de la 3.2.2). n plus, atributele atrib1, atrib2,... trebuie s fie i ele actualizabile (nu pot fi evident modificate atributele calculate!).
2) Modificarea tuplilor reuete doar dac nu sunt nclcate constrngerile de
integritate ale tabelelor int (vezi observaia 4 de la 3.2.2).
3) nouvaloare1, nouvaloare2,... pot evident conine nume de atribute ale int;
de exemplu, pentru a crete cu 10% valoarea unui atribut Salariu, se poate scrie
SET Salariu = Salariu * 1,1; sau, pentru a recalcula atributul Total
din valorile atributelor Suma i ProcentTVA:
67

COPII (Copil) Copil Nume, Tata Nume, Mama Nume


Copil
Tata
Mama
Alexndrel
Ilia
Alexandru
tefan cel Mare
Evdochia
Alexandru cel Bun
Roman I
Anastasia
Ana lui tefan
tefan cel Mare
Bogdan
Roman I
Bogdan II
Alexandru cel Bun
Bogdan III
tefan cel Mare
Maria Voichia
Bogdnel
tefan cel Mare
Maria de Mangop
Elena
tefan cel Mare
Evdochia
Ilia
Alexandru cel Bun Ana Neaca
Ilie
tefan cel Mare
Maria de Mangop
Iuga Vod
Sor Petru Muat?
Lacu
Bogdan I
Margareta Muata
Bogdan I
Maria
tefan cel Mare
Maria Voichia
Mtu tefan cel Mare Alexandru cel Bun
Petru Aron
Alexandru cel Bun Mariana
Petru II
Alexandru cel Bun
Petru Muat
Margareta Muata
Petru Ptracu
tefan cel Mare
Evdochia
Petru Rare
tefan cel Mare
Maria Rare din Hrlu
Roman I
Margareta Muata
Roman II
Ilia
Sor Petru Muat?
Margareta Muata
tefan cel Mare
Bogdan II
Maria Oltea Basarab
tefan I
Sor Petru Muat?
tefan II
Alexandru cel Bun
Figura 47 Copiii Muatini din figura 2, plus Ana lui tefan cel Mare

SET Total = Suma * (1 + ProcentTVA/100)


4) UPDATE nu genereaz o relaie rezultat.
5) Odat executat, instruciunea UPDATE nu mai poate fi dat napoi (rolled
back, i.e. nu se mai poate renuna la modificrile efectuate i reveni la
coninutul bd dinaintea execuiei acestei instruciuni); pentru a obine acest
lucru, este nevoie de execuia unei sau unor alte instruciuni i/sau de
modificarea interactiv a datelor astfel nct noul coninut s fie identic cu cel
iniial. Ca atare, se recomand testarea prealabil a clauzei WHERE ntr-o
instruciune SELECT (pentru a verifica tuplii ce vor fi modificai), precum i
salvarea int naintea execuiei instruciunii.
Exemplul 35 Urmtoarea instruciune modific valoarea atributului
Necropol al tabelei PERSOANE pentru tuplii corespunztori lui Neagoe
Basarab, Radu de la Afumai, Stanca i Vladislav Vlaicu din Curtea
Arge n Curtea de Arge:
(Q109)UPDATE PERSOANE SET Necropol =
Curtea de Arge WHERE Necropol = Curtea Arge;
68

3.2.4 Instruciunea DELETE


Sintaxa instruciunii de tergere tupli din tabele este urmtoarea:
DELETE [[int.]*] FROM expresietabele [clauzWHERE];
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
int
Numele unei tabele sau interogri salvate ai crei tupli se terg.
expresietabele (Exact ca i la instruciunea SELECT) coninutul clauzei FROM
definind int.
clauzWHERE Clauz WHERE (vezi 3.1.1.3) pe care trebuie s o satisfac tuplii
care sunt teri.
Observaii:
1) Dac int este o interogare, atunci rezultatul acesteia trebuie s fie actualizabil;
n caz contrar, nu se terge nici un tuplu! (pentru exemple de interogri
neactualizabile vezi observaia 2 de la 3.2.2).
2) tergerea tuplilor reuete doar dac nu sunt nclcate constrngerile de integritate ale tabelelor int (n particular, dac sunt definite referine de integritate
fr clauze ON DELETE CASCADE sau ON DELETE SET NULL tergerea
tuplilor care le-ar viola nu este permis; vezi i observaia 4 de la 3.2.2).
3) n prezena referinelor de integritate nsoite de clauza ON DELETE
CASCADE, tergerea unui tuplu din tabela domeniu de definiie antreneaz
automat tergerea tuturor tuplilor din tabelele codomeniu care refer acel tuplu;
la rndul lor, tergerea acestora antreneaz, similar, tergerea tuturor tuplilor din
tere tabele care i refer, n cascad etc. De exemplu, dac bd din exemplul 1 ar
avea aceast clauz, tergerea din PERSOANE a tuplului corespunztor unui
domnitor tat ar avea ca efect att tergerea tuturor domniilor sale din tabele
DOMNII, ct i a tuturor copiilor si din tabela TATA.
4) n prezena referinelor de integritate nsoite de clauza ON DELETE SET
NULL, tergerea unui tuplu din tabela domeniu de definiie antreneaz automat
nlocuirea cu NULL a tuturor referinelor din tabelele codomeniu care refer
acel tuplu. Revenind la exemplul dat la punctul anterior, n acest caz, tergerea
din PERSOANE a unui domnitor tat ar avea ca efect nlocuirea numelui su cu
NULL n coloana Domnitor a tuturor tuplilor afereni domniilor sale din tabela
DOMNII i, similar, n coloana Tata din tabela TATA a tuturor tuplilor
corespunztori copiilor si.
5) Odat executat, instruciunea DELETE nu mai poate fi dat napoi (rolled
back, i.e. nu se mai poate renuna la tergerile efectuate i reveni la coninutul
bd dinaintea execuiei acestei instruciuni); pentru a obine acest lucru, este
nevoie de execuia unei sau unor alte instruciuni i/sau de modificarea
interactiv a datelor astfel nct noul coninut s fie identic cu cel iniial. Ca
atare, se recomand testarea prealabil a clauzei WHERE ntr-o instruciune
SELECT (pentru a verifica tuplii ce vor fi teri), precum i salvarea int
naintea execuiei instruciunii.
Exemplul 36 Urmtoarea instruciune terge din tabela COPII (vezi figura
47) toi tuplii pentru care copilului nu i se cunoate mama (n urma execuiei
sale, coninutul tabelei este cel prezentat n figura 48):
(Q110)DELETE FROM Copii
WHERE (Mama Is Null);

69

Copil
Alexandru
Alexandru cel Bun
Bogdan III
Bogdnel
Elena
Ilia
Ilie
Iuga Vod
Maria
Petru Aron
Petru Muat
Petru Ptracu
Petru Rare
Roman I
Sor Petru Muat?
tefan cel Mare
tefan I

Tata
tefan cel Mare
Roman I
tefan cel Mare
tefan cel Mare
tefan cel Mare
Alexandru cel Bun
tefan cel Mare

Mama

Evdochia
Anastasia
Maria Voichia
Maria de Mangop
Evdochia
Ana Neaca
Maria de Mangop
Sor Petru Muat?
tefan cel Mare
Maria Voichia
Alexandru cel Bun Mariana
Margareta Muata
tefan cel Mare
Evdochia
tefan cel Mare
Maria Rare din Hrlu
Margareta Muata
Margareta Muata
Bogdan II
Maria Oltea Basarab
Sor Petru Muat?

Figura 48 Tabela COPII din figura 47 dup execuia instruciunii (Q110)

3.3 Puncte de vedere i proceduri catalogate


3.3.1 Instruciunea CREATE VIEW
Instruciunea CREATE VIEW creeaz o tabel virtual, constituind un punct de
vedere alternativ asupra datelor memorate de schema bazei de date (virtual deoarece
ea nu este memorat ca atare n baza de date, dect eventual temporar; ceea ce se
memoreaz permanent este doar definiia ei, care este aplicat pentru a i calcula
coninutul la fiecare deschidere a respectivului view). De notat c n definiia unui view
pot apare coloane din mai multe tabele, dar nu i parametri.
Sintaxa instruciunii este urmtoarea:
CREATE VIEW view [(coloana1[, coloana2[, ...]])] AS instrSELECT
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
view
Numele tabelei virtuale.
coloana1,
Numele coloanelor tabelei virtuale view (corespunztoare celor specificate
coloana2
de instrSELECT).
instrSELECT O instruciune SQL SELECT (vezi 3.1.1).
Observaii:
1) Instruciunea SELECT care definete view nu poate fi de tip SELECT...INTO.
2) Instruciunea SELECT care definete view nu poate conine parametri.
3) Numele view trebuie s fie distinct de numele oricrei alte tabele fundamentale
sau virtuale ale schemei bazei de date respective.
4) Dac rezultatul instruciunii SELECT ncorporate este actualizabil, atunci este
posibil i actualizarea datelor coninute de view (actualizare care este, de fapt,
automat fcut de MS Jet asupra coninutului tabelelor fundamentale implicate
n instruciunea SELECT ncorporat); n caz contrar, view este read-only (i.e.
coninutul su poate fi doar citit, nu i modificat).
70

5) Atributele instruciunii SELECT ncorporate nu trebuie neaprat s aib nume


distincte; toate numele atributelor coloana1, coloana2, ... alctuind tabela
virtual trebuie s fie ns unice.
6) De notat c n MSJSQL se pot defini i manipula view-uri numai programatic,
via ADOX i furnizorul Jet OLE DB. Mai mult, eventualele view-uri astfel
definite nu sunt vizibile utilizatorilor interactivi de Access (i.e. nu fac parte din
mulimea de interogri salvate!).
7) instrSELECT nu poate avea clauz ORDER BY sau declaraie PARAMETERS.
8) View-urile se folosesc n Access doar pentru compatibilitate ANSI-92 (de
exemplu pentru a asigura portabilitatea aplicaiilor i pe MS SQL Server, Oracle
etc.). n mod nativ, Access privete interogrile salvate (queries) neparametrizate drept view-uri.
Exemplul 37 Fie interogarea calculnd submulimea persoanelor avnd
ambii prini cunoscui (vezi rspunsul corespunztor n figura 49):
(Q111)SELECT Nume, Mama, Tata
FROM Persoane INNER JOIN (Tata INNER JOIN
Mama ON Tata.Copil=Mama.Copil)
ON Tata.Copil=Persoane.Nume
ORDER BY Persoane.Nume;
Un punct de vedere (view, tabela virtual) echivalent acestei interogri (cu
excepia ordonrii!) numit, de exemplu Parinti, poate fi definit de
urmtoarea procedur VBA CreateViewParinti:
Sub CreateViewParinti()
Dim conDb As ADODB.Connection
On Error GoTo err_point
Set conDb = Application.CurrentProject.Connection
conDb.Execute "CREATE VIEW Parinti AS " _
& "SELECT Nume, Tata, Mama " _
& "FROM Persoane INNER JOIN (Tata INNER JOIN " _
& "Mama ON Tata.Copil=Mama.Copil) " _
& "ON Tata.Copil=Persoane.Nume;"
conDb.Close
Set conDb = Nothing
Exit Sub
err_point: MsgBox Err.Description
End Sub
Acest view poate fi apoi folosit (evident doar programatic) ca orice
interogare salvat (de exemplu, pentru a defini alte view-uri sau reuniuni
UNION bazate i pe el).
Nume
Mama
Tata
Ana
Clara
Nicolae Alexandru
Anca
Clara
Nicolae Alexandru
Elisabeta
Maria
Nicolae Alexandru
Mircea
Mtu tefan cel Mare Vlad Dracul
Radu cel Frumos Mtu tefan cel Mare Vlad Dracul
Radu I
Maria
Nicolae Alexandru
Vlad
Elena
Vlad epe
Vlad Clugrul
Mtu tefan cel Mare Vlad Dracul
Vlad epe
Mtu tefan cel Mare Vlad Dracul
Vladislav Vlaicu
Maria
Nicolae Alexandru
Figura 49 Coninutul (Q111) i tabelei virtuale corespunztoare Parinti pentru bd din figura 1

71

3.3.2 Instruciunea CREATE PROCEDURE


Sintaxa instruciunii de creare a procedurilor catalogate este urmtoarea:
CREATE PROCEDURE procedur [param1 tipdat [, param2 tipdat [, ...]]]
AS instrSQL
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
procedur
Numele procedurii create.
param1,
Unul sau mai multe nume de atribute sau parametri.
param2
tipdat
Numele unui tip de date standard SQL oferit de MS Jet sau un sinonim
al unui asemenea tip (vezi 2.1.1).
instrSQL
O instruciune SQL oarecare.
Observaii:
1) Numele procedurilor trebuie s se conformeze standardelor impuse de sistem
pentru numele de obiecte.
2) Numele oricrei proceduri trebuie s fie distinct de cel al oricrei tabele
(fundamentale sau derivate).
3) O procedur SQL const dintr-o clauz PROCEDURE ce specific numele
procedurii, o list opional de definiii a parametrilor (n numr de maxim 255)
i o unic instruciune SQL.
4) Execuia unei proceduri catalogate se face cu instruciunea SQL EXECUTE.
5) De notat c n MSJSQL se pot defini i executa proceduri catalogate numai
programatic, via ADOX i furnizorul Jet OLE DB. Mai mult, eventualele
proceduri catalogate astfel definite nu sunt vizibile utilizatorilor interactivi de
Access (i.e. nu fac parte din mulimea de interogri salvate!).
6) Procedurile catalogate se folosesc n Access doar pentru compatibilitate ANSI-92
(de exemplu, pentru a asigura portabilitatea aplicaiilor i pe MS SQL Server,
Oracle etc.). n mod nativ, Access privete interogrile salvate (queries)
parametrizate (cu declaraia PARAMETERS) drept proceduri catalogate.
Exemplul 38 Revenind la exemplul 28 i interogarea parametrizat (Q083),
urmtoarea procedur catalogat echivalent selecteaz domniile dintr-un
interval oarecare de timp:
(Q112)CREATE PROCEDURE DomniiPerioada
([Data minim] Integer, [Data maxim] Integer) AS
SELECT * FROM Domnii
WHERE ([Data minim]<=La AND DeLa<=[Data maxim]);
Evident c salvarea acestei interogri nu va reui ca atare (mesajul
semnaleaz o eroare sintactic n instruciunea CREATE TABLE pe cuvntul
PROCEDURE!), n schimb execuia urmtoarei proceduri VBA corespunztoare va cataloga procedura sub numele DomniiPerioada:
Sub CreateProcDomniiPerioada()
Dim conDb As ADODB.Connection
On Error GoTo err_point
Set conDb = Application.CurrentProject.Connection
conDb.Execute "CREATE PROCEDURE DomniiPerioada " _
& "([Data minima] Integer, " _
& "[Data maxima] Integer) AS SELECT * " _
& "FROM Domnii WHERE ([Data minima]<=La " _
& "AND DeLa<=[Data maxima]);"
conDb.Close
72

Set conDb = Nothing


Exit Sub
err_point:
MsgBox Err.Description
End Sub
3.3.3 Instruciunea EXECUTE
Sintaxa instruciunii de lansare n execuie a unei proceduri catalogate (creat cu
instruciunea CREATE PROCEDURE) este urmtoarea:
EXECUTE procedur [param1[, param2[, ...]]]24
Semnificaia variabilelor utilizate este urmtoarea:
Variabil
Descriere
procedur
Numele procedurii de executat.
param1, param2,... Valorile parametrilor procedur definii de CREATE PROCEDURE.
Exemplul 39 Urmtoarea procedur VBA permite execuia procedurii
catalogate DomniiPerioada definit n exemplul 38 (rezultatul execuiei ei
pentru bd din figura 1 i cu valorile 1400, respectiv 1432 pentru parametrii
[Data minima] i [Data maxima] este exact cel prezentat n figura 34a):
Sub ExecuteProcDomniiPerioada()
Dim conDb As ADODB.Connection
On Error GoTo err_point
Set conDb = Application.CurrentProject.Connection
conDb.Execute "EXECUTE DomniiPerioada 1400, 1432;"
conDb.Close
Set conDb = Nothing
Exit Sub
err_point:
MsgBox Err.Description
End Sub

3.4 Tranzacii
3.4.1 Instruciunile BEGIN, COMMIT i ROLLBACK
Sintaxa instruciunilor de iniiere i ncheiere a tranzaciilor explicite este, respectiv:
Iniierea unei noi tranzacii:
BEGINTRANS
ncheierea normal a tranzaciei curente (nsoit de salvarea rezultatelor ei n
bd):
COMMITTRANS
ncheierea anormal a tranzaciei curente (nsoit de renunarea la rezultatele
execuiei sale curente asupra bd):
ROLLBACK [TRANSACTION | WORK]
Observaii:
1) Tranzaciile explicite nu sunt iniiate automat (implicit), ci doar explicit, la
execuia BEGINTRANS.
2) n MSJSQL, tranzaciile explicite (numite prescurtat de acum ncolo tranzacii)
pot fi ncapsulate n alte tranzacii pe maxim 5 nivele de adncime.
3) Tranzaciile nu sunt admise pentru tabele legate (i.e. neaparinnd bd curente).
4) Practic, modificrile cerute asupra bd de instruciunile ce se afl ntre o
instruciune BEGINTRANS i instruciunea corespunztoare COMMITTRANS
nu se fac direct asupra bd, ci n fiiere de manevr sistem memornd o copie a
24

n MSJSQL se pot executa proceduri catalogate numai programatic, via ADO i Jet OLE DB.

73

5)

6)
7)

8)

bd; doar la execuia instruciunii COMMITTRANS se nlocuiete bd cu copia


coninnd modificrile tranzaciei; dac nu se ajunge la execuia instruciunii
COMMITTRANS corespunztoare (de exemplu, dintr-o eroare sistem,
ntreruperea accidental a alimentrii electrice etc.) sau dac, n loc, se execut o
instruciune ROLLBACK (deoarece programul a ntlnit o eroare; de exemplu o
tabel lips sau distrus sau blocat de un alt utilizator etc.) atunci nu mai are loc
nlocuirea bd cu copia ei de manevr coninnd eventualele modificri aduse de
tranzacie (efectul fiind renunarea la aceasta). ntr-un cuvnt, modificrile
asupra bd ale tuturor instruciunilor aflate ntre o instruciune BEGINTRANS i
instruciunea COMMITTRANS corespunztoare se fac ori integral, ori deloc.
Fiecare instruciune BEGINTRANS trebuie nchis cu o instruciune
corespunztoare (fie ea COMMITTRANS ori ROLLBACK). Evident c
parantezele nchise n exces (de instruciuni COMMITTRANS ori
ROLLBACK crora nu le corespunde vreo instruciune COMMITTRANS
anterioar) nu afecteaz coninutul de date al bd, dar execuia lor are totui ca
efect generarea de ctre Jet a cte unei erori corespunztoare. n schimb, lipsa
mcar unei asemenea paranteze nchise poate avea rezultate imprevizibile: n
anumite situaii, Jet poate comite automat tranzacia nenchis explicit (i.e.
simula execuia COMMITTRANS), n timp ce n altele va renuna la ea (chiar
dac, conform inteniei programatorului, ea ar fi deja ncheiabil cu succes).
n MSJSQL se pot defini tranzacii numai programatic, via ADO i furnizorul Jet
OLE DB.
De remarcat c i ADO are propriile metode de definire i control a tranzaciilor;
acestea ns nu trebuie niciodat mixate cu instruciunile tranzacionale SQL
descrise n prezenta subseciune: n caz contrar, rezultatele sunt impredictibile!
De notat c, implicit, fiecare instruciune SQL n parte este ntotdeauna
implementat ca o tranzacie (i.e. ea ori are efectul integral scontat, ori nici un
efect; de exemplu, crearea unei tabele ori reuete n totalitate, ori deloc, chiar
dac crearea ei parial ar fi posibil; e.g. tabela CAPITALE din exemplul 1).
Exemplul 40 S presupunem c se dorete execuia urmtoarei secvene de
ase instruciuni SQL:
a) din tabela BTLII prezentat n figura 45a, se creeaz o nou tabel
numit TOTALBTLII coninnd doar coloanele Domn, Duman i
Victorie, cu ajutorul instruciunii urmtoare:
(Q113)SELECT Domn, Duman, Victorie
INTO TotalBtlii FROM Btlii;
b) apoi, pentru a nlocui n coloana Duman a acestei noi tabele toate
valorile transilvnean, muntean i moldovean cu valoarea romn, se
execut instruciunea:
(Q114)UPDATE TotalBtlii SET Duman = "romni"
WHERE (Duman IN
('transilvneni','munteni','moldoveni'));
c) pentru a modifica valorile coloanei Duman i pentru tuplii ce conin
valoarea unguri nlocuind-o cu maghiari, se execut instruciunea:
(Q115)UPDATE TotalBtlii SET Duman = "maghiari"
WHERE (Duman = "unguri");
d) din tabela astfel obinut, se creeaz n urmtorul pas o nou tabel,
numit TOTALURIBTLII, cu totaluri pe Domn, Duman i Victorie
(calculnd numrul de victorii, respectiv nfrngeri pe fiecare asemenea
grup), executnd instruciunea urmtoare:
(Q116)SELECT Domn, Duman, Victorie,
74

Count(Victorie) AS Scor INTO TotaluriBtlii


FROM TotalBtlii
GROUP BY Domn, Duman, Victorie;
e) se creeaz apoi cheia primar a acestei noi tabele, format evident cu
atributele Domn, Duman i Victorie, folosind instruciunea:
(Q117)CREATE INDEX kpTB ON TotaluriBtlii
(Domn, Duman, Victorie) WITH PRIMARY;
f) n sfrit, se terge tabela TOTALBTLII, cu instruciunea:
(Q118)DROP TABLE TotalBtlii;
Evident c, dac n cursul execuiei acestei secvene de ase instruciuni ar
avea loc un incident fatal (e.g. cderea tensiunii de alimentare, lips spaiu
liber suficient pe disc, imposibilitate execuie instruciune datorit faptului
c un alt utilizator/proces concurent a blocat tabela respectiv, imposibilitate
recreare tabel deja existent etc.), o parte dintre instruciuni s-ar putea
termina normal, iar restul nu, ceea ar avea ca efect obinerea unui coninut
impredictibil al bd (n funcie de momentul survenirii incidentului).
Dac acest lucru nu este admisibil, ci dimpotriv, se dorete execuia
atomic a ntregii secvene de mai sus (i.e. trebuie s aib loc toate
modificrile coninutului bd, conform tuturor celor ase instruciuni sau nici
una din ele nu reuete), atunci secvena de mai sus trebuie evident
mbrcat ntr-o tranzacie.
Exclusiv din considerente didactice, soluia VBA prezentat n procedura
CreateTotaluriBatalii de mai jos folosete dou niveluri de tranzacii
ncapsulate unul ntr-altul (similar, cele dou instruciuni UPDATE consecutive ar putea fi evident combinate ntr-una singur); rezultatul execuiei
acesteia, n condiii de terminare normal, este prezentat n figura 50:
Private Sub CreateTotaluriBatalii()
Dim conDb As ADODB.Connection
On Error GoTo Err_point
Set conDb = Application.CurrentProject.Connection
conDb.BeginTrans
conDb.Execute "SELECT Domn, Duman, Victorie " _
& "INTO TotalBtlii FROM Btlii;"
conDb.Execute "UPDATE TotalBtlii SET Duman = "
& "'romni' WHERE (Duman IN " _
& "('transilvneni','munteni','moldoveni'));"
conDb.Execute "UPDATE TotalBtlii SET Duman = "
& "'maghiari' WHERE (Duman='unguri');"
conDb.BeginTrans
conDb.Execute "SELECT Domn, Duman, Victorie, "
& "Count(Victorie) AS Scor INTO Totaluri" _
& "Btlii FROM TotalBtlii GROUP BY Domn, "
& "Duman, Victorie;"
conDb.Execute "CREATE INDEX kpTB ON Totaluri" _
& "Btlii(Domn, Duman, Victorie) WITH " _
& "PRIMARY;"
conDb.CommitTrans
conDb.Execute "DROP TABLE TotalBtlii;"
conDb.CommitTrans

75

_
_
_
_

Exit_point:
conDb.Close
Set conDb = Nothing
Exit Sub
Err_point:
MsgBox Err.Description
conDb.RollbackTrans
Resume Exit_point
End Sub
Domn
Basarab I
Basarab I
Basarab epelu
Dan II
Dan II
Dan II
Laiot Basarab
Mihail I
Mircea cel Btrn
Mircea cel Btrn
Mircea cel Btrn
Mircea cel Btrn
Mircea cel Btrn
Nicolae Alexandru
Radu cel Frumos
Radu I
Vlad Dracul
Vlad Dracul
Vlad Dracul
Vlad Dracul
Vlad epe
Vlad epe
Vlad epe
Vlad epe
Vladislav II
Vladislav Vlaicu
Vladislav Vlaicu
Vladislav Vlaicu

Duman Victorie Scor


maghiari
-1 1
ttari
-1 2
romni
0 2
romni
0 1
turci
-1 3
turci
0 1
romni
0 1
turci
0 1
maghiari
-1 1
maghiari
0 1
romni
-1 2
turci
-1 7
turci
0 5
ttari
-1 1
romni
0 4
maghiari
-1 1
maghiari
-1 1
romni
0 1
turci
-1 1
turci
0 1
romni
-1 5
romni
0 3
turci
-1 3
turci
0 1
turci
0 1
maghiari
-1 1
turci
-1 1
turci
0 1

Figura 50 Tabela TOTALURIBTLII obinut n urma execuiei cu succes a procedurii VBA


CreateTotaluriBatalii din exemplul 4025

25

De notat c Access folosete codificarea: 0 pentru False, -1 (complementul bit cu bit al 0) pentru True.

76

4 Diferene ntre MSJetSQL i ANSI-92 SQL

n general, abaterile MS Jet SQL de la standardul ANSI sunt puine, iar


majoritatea lor o constituie mbuntiri (care, foarte probabil, vor fi adugate
standardelor n viitorul apropiat).
MS Jet SQL i ANSI SQL difer prin denumirea unor cuvinte rezervate i tipuri
de date. De exemplu:
DATE, TIME i TIMESTAMP din ANSI au un singur corespondent n Jet:
DATETIME;
CHARACTER este prescurtat n Jet cu CHAR;
Jet nu are echivalent pentru tipul de dat ANSI INTERVAL;
Jet ofer ns 6 tipuri de date suplimentare: TINYINT, COUNTER, MONEY,
UNIQUEIDENTIFIER, TEXT, IMAGE (plus subtipuri sau sinonime pentru
acestea).

Pentru operatorul de comparaie BETWEEN...AND, exist urmtoarea diferen


semantic: n Jet, value1 poate fi mai mare dect value2, n timp ce n ANSI,
value1 poate fi doar cel mult egal cu value2.
Access suport pentru operatorul LIKE att metacaracterele (jolly jocker)
ANSI, ct i altele, proprii; folosirea acestora este ns mutual exclusiv: se poate
folosi doar una dintre cele dou convenii, la alegere, n funcie de mediul de
programare dorit. Astfel, metacaracterele ANSI se pot folosi doar n Jet 4.X i n
MS OLE DB Provider for Jet; n QBE (i.e. aa-numitul mod de proiectare al
interogrilor) sau DAO, ele sunt interpretate ca literali. Dual, matacaracterele
Access se pot folosi doar n QBE sau DAO, n timp ce n Jet 4.X i n MS OLE
DB ele sunt interpretate drept literali. Cele dou variante sunt urmtoarele:
Definiie metacaracter MS Jet SQL ANSI SQL
Orice caracter
?
_ (subliniere)
Zero sau oricte caractere *
%
MS Jet SQL este n general mai bogat i mai puin restrictiv. De exemplu, el
permite gruparea i ordonarea folosind expresii.
MS Jet SQL suport expresii mai puternice.
MS Jet SQL ofer cteva mbuntiri semnificative, dintre care se disting
urmtoarele trei:
Instruciunea TRANSFORM, care permite construcia de interogri tabulare
ncruciate (de tipul celor din Excel).
Declaraia PARAMETERS, ce permite construcia de interogri
parametrizate.
Funcii de agregare suplimentare, precum StDev (pentru calculul deviaiei
statistice standard) i VarP (pentru calculul varianei bazat pe o ntreag
populaie).
MS Jet SQL nu suport urmtoarele caracteristici ale ANSI SQL:
Folosirea predicatului DISTINCT n funciile de agregare; de exemplu, nu este
permis apelul de tip Sum(DISTINCT numecoloana).
Nu exist clauza LIMIT TO nn ROWS, destinat limitrii numrului de tupli
ai rezultatului unei interogri la maxim nn. Pentru a limita rezultatele, se pot
ns evident folosi clauza WHERE i/sau predicatul TOP.

77

5 Probleme propuse spre rezolvare


1 Fie urmtoarea schem a unei baze de date referitoare la un catalog de cri
incluznd i date personale despre autori:
CRI (ISBN, #Autor, Titlu, #Editura, An)
COAUTORI (#Coautor, ISBN#Autor)
AUTORI (#Autor, Nume, DataNaterii, Domiciliu)
EDITURI (#Editura, Editura, #Localitate)
LOCALITI (#Localitate, Localitate),
unde CRI.[#Autor] memoreaz primul autor al fiecrei cri, ceilali coautori
(dac este cazul) sunt memorai de relaia COAUTORI, iar Domiciliu reprezint
localitatea de reedin a persoanelor.
a. Scriei instruciunile SQL pentru crearea acestei bd.
b. Scriei instruciunile SQL pentru a calcula:
crile al cror prim autor locuiete n localitatea editorului crii respective
coautorii mai tineri dect prim autorii corespunztori, indicnd i titlul i anul de
apariie al crilor n cauz
perechile de persoane care au publicat mpreun cel puin dou cri, la care
rolurile lor (prim autor, respectiv coautor) sunt inverse
autorii care au publicat o carte naintea naterii unui coautor al lor (evident,
coautor la o carte ulterioar).
2
Furnizai condiiile necesare i suficiente ca rezultatele obinute de o instruciune
SELECT s fie ntotdeauna aceleai (indiferent de coninutul bd asupra creia se
execut instruciunea) atunci cnd ele difer doar prin prezena predicatului
DISTINCT n locul lui DISTINCTROW.
3
Scriei instruciunile SQL corespunztoare expresiilor AR de la (E3.1) la (E3.8) i
(E3.31) din [1].
4
Scriei instruciunile SQL corespunztoare expresiilor CR de la (E3.10) la (E3.13)
i (E3.26) din [1].
5
Scriei instruciunile SQL necesare pentru crearea tabelelor CTITORII din
exemplul 31 (figura 44a) i BTLII din exemplul 32 (figura 45a).
6
a. Scriei instruciunile SQL necesare pentru crearea urmtoarelor tabele:
RI (#ara, ara, Capitala, DenSubDivAdm), Capitala #Loc
SUBDIVADM (#SDA, araSubDivAdm, Reedina) ara #ara,
Reedina #Loc
LOCALITI (#Loc, araSubDivAdmLoc) ara #ara,
SubDivAdm #SDA
AEZMINTE (#AM, AezmntLoc), Loc #Loc
b. scriei instruciunile SQL pentru a calcula:
rile a cror capital nu este o localitate din respectiva ar (indicaie: pentru
orice coninut real, rspunsul trebuie s fie ntotdeauna vid!).
Lista aezmintelor, ordonat pe ri, subdiviziuni administrative i localiti.
Idem, dar numai pentru aezmintele dintr-o list de ri cunoscut.
Idem, dar numai pentru rile cu cel puin 3 localiti avnd fiecare mcar 2
aezminte.
7
Scriei instruciunile SQL i apoi tranzacia VBA cuprinzndu-le pe toate, n
exact aceast ordine, pentru:
adugarea la tabelele PERSOANE, respectiv CTITORII a cte unui atribut ntreg
de tip cheie cu autonumrare numit #Necropola, respectiv #Ctitorie
78

10

11

12
13

14

completarea valorilor acestor noi atribute cu referine ctre atributul #AM din tabela AEZMINTE de la problema 6, cu proprietatea c valorile corespunztoare ale atributelor Necropol, respectiv Ctitorie sunt egale cu cele ale atributului
Aezmnt
definirea cheilor strine astfel construite #Necropola, respectiv #Ctitorie
tergerea atributelor Necropol din tabela PERSOANE, respectiv Ctitorie din
tabela Ctitorii.
Scriei instruciuni SQL pentru a calcula primii 10, respectiv primii 10% dintre
domnitorii care au purtat cele mai multe btlii, respectiv repurtat cele mai multe
victorii (Domn, NrBtlii; respectiv Domn, NrVictorii); calculai coninutul
acestor interogri pentru bd din figura 45a.
Scriei instruciuni SQL pentru a calcula media numrului de btlii, respectiv de
victorii i abaterile de la medie pentru fiecare domnitor; calculai coninutul
acestor interogri pentru bd din figura 45a.
Se poate calcula capitala curent n momentul nceperii fiecrei domnii (vezi
Q074 din exemplul 25 i figura 29) cu o singur instruciune SQL folosind
subinterogri? Justificai rspunsul.
Scriei o instruciune SQL coninnd subinterogri pentru a calcula domnii care sau luptat cu ali domni din aceeai dinastie; calculai coninutul acestei interogri
pentru bd din figurile 45a i 1.
Scriei o instruciune SQL pentru a calcula tabularea ncruciat dual celei din
figura 45b (i.e. cu dumani pe axa y i domnitori pe axa x).
Scriei o instruciune SQL pentru a calcula tabularea ncruciat a numrului de
btlii ale fiecrui domn n fiecare an (i.e. avnd Domn pe axa y i anii btliilor
pe axa x); calculai coninutul acestei interogri pentru bd din figura 45a.
Scriei o instruciune SQL pentru a crea o tabel care s memoreze, pentru fiecare
domnitor, ctitoriile sale din acelai an cu btliile purtate de acetia; calculai
coninutul acestei tabele pentru bd din figurile 45a i 51.
CTITORII (CtitorCtitorieAn) CtitorNume
Ctitor
Ctitorie
An
Basarab I
Negru Vod 1330
Nicolae Alexandru Negru Vod 1360
Vladislav Vlaicu
Vodia
1370
Radu cel Mare
Vodia
1500
Radu I
Tismana
1377
Dan I
Tismana
1384
Mircea cel Btrn
Tismana
1386
Mircea cel Btrn
Tismana
1396
Radu cel Mare
Tismana
1495
Mircea cel Btrn
Cozia
1388
Mircea cel Btrn
Cotmeana
1389
Alexandru Aldea
Dealu
1431
Radu cel Mare
Dealu
1501
Mircea cel Btrn
Snagov
1396
Vladislav II
Snagov
1448
Vlad epe
Snagov
1462
Vlad epe
Snagov
1476
Vlad epe
Govora
1460
Vlad Clugrul
Govora
1490
Radu cel Mare
Govora
1496
Figura 51 Cteva dintre cele mai importante ctitorii ale primilor Basarabi

79

15

16

17
18

19
20
21

22

23

24

25

26
27

28

29

Scriei instruciuni SQL pentru a insera n tabela BTLII cte un tuplu simetric
pentru fiecare inamic dintre domnitorii moldoveni; calculai coninutul tabelei dup execuia lor pentru bd din figurile 45a i 1.
Scriei o instruciune SQL pentru a terge din tabela BTLII toi tuplii pentru
care dumanii sunt romni; calculai coninutul tabelei dup execuia acestei
instruciuni pentru bd din figura 45a.
S se traduc n SQL interogrile LMDMEA prezentate n seciunea 1.4, precum i
cele cerute de problema 1.8 din [1].
Scriei instruciunea SQL corespunztoare pentru calculul domnitorilor i
prinilor acestora, cu condiia ca mcar unul dintre prini s fie cunoscut;
calculai rspunsurile acestora pentru bd din figurile 1 i 2.
Scriei instruciunea SQL pentru aflarea domnitorilor al cror nume ncepe cu
tefan i calculai rezultatul ei pentru bd din figura 2.
Scriei instruciunea SQL pentru calculul mulimii domnitorilor care au avut
copii.
Scriei instruciunile SQL corespunztoare cu i fr subinterogri pentru calculul
perechilor (Domnitor, Copil) selectnd doar domnitorii cu cel puin doi copii ce
au domnit i ei la rndul lor de cel puin 2 ori i, de fiecare din aceste di, mcar
cte 2 ani.
Scriei instruciunile SQL corespunztoare cu i fr subinterogri pentru calculul
perechilor (Domnitor, Copil) selectnd doar domnitorii cu cel puin doi copii ce
au domnit i ei la rndul lor i care, n plus, au avut numele mai mic (lexicografic)
dect cel al unuia dintre copiii si.
a. Scriei instruciunile SQL corespunztoare cu i fr subinterogri pentru
calculul perechilor (Domnitor, Copil) selectnd doar domnitorii i copiii care au
avut cel puin la fel de muli copii domnitori pe ci a avut i copilul
corespunztor.
b. Idem, nlocuind copiii cu nepoii.
Scriei instruciunile SQL corespunztoare cu i fr subinterogri pentru calculul
perechilor (Domnitor, Copil) selectnd doar domnitorii ai cror copii au domnit cu
toii.
Scriei instruciunile SQL corespunztoare cu i fr subinterogri pentru calculul
perechilor (Domnitor, Copil) selectnd doar domnitorii care au avut cel puin un
strnepot domnitor.
Scriei o instruciune SQL pentru a calcula tabularea ncruciat a mediei anilor
ctitoriilor asupra tabelei din figura 51, cu ctitorii pe axa y i ctitori pe axa x.
a. Scriei instruciunile SQL corespunztoare cu i fr subinterogri pentru
calculul nchiderii tranzitive a relaiei TATA i calculai rspunsurile aferente bd
din figura 1 i 2.
b. idem pentru relaia MAMA.
Demonstrai c nchiderile tranzitive nu sunt unicele interogri cu sens pe care
limbajele complete nu trebuie s fie capabile s le exprime, dei rezultatele lor
conin doar valori memorate de bd i sunt invariante la orice automorfism al
coninutului acesteia (Indicaie: considerai tabela TATA din figura 1 i ncercai
s scriei instruciunile SQL pentru calculul perechilor de frai, astfel nct
rezultatul s nu conin nici o pereche (f,g), dac el deja conine o pereche (g,f).
Scriei apoi un program n orice limbaj de programare, de exemplu VBA,
Transact-SQL, PL/SQL, C etc.- care realizeaz acest lucru. Generalizai!).
a. Scriei instruciunea SQL parametrizat pentru calculul urmailor de ordin cel
mult doi al unui domnitor oarecare (indicaie: rspunsul va trebui s includ toi
copiii si, precum i toi copiii acestora i, evident, nimic altceva; folosii
operatorul de reuniune).
80

30

31

32

33

34
35
36

37
38

b. Scriei instruciunea similar pentru ordinul trei (indicaie: folosii de dou ori
operatorul de reuniune!).
c. Proiectai algoritmul i implementai programul corespunztor n SQL i un
limbaj gazd de nivel nalt oarecare (i.e. VBA, VB, C++, C#, Java etc.) sau ntr-un
SQL CH-complet (i.e. QL, Transact-SQL, PL/SQL etc.) pentru parametrizarea
instruciunii de mai sus nu doar cu domnitorul, ci i cu ordinul dorit, astfel:
ordinul poate lua orice valoare natural n i dac aceasta este strict pozitiv, atunci
se calculeaz toi urmaii pn la generaia n, iar dac n=0, atunci se calculeaz
nchiderea tranzitiv a acestei relaii (indicaii: folosii o bucl while i o tabel
temporar n care, la fiecare pas i, 1in, se adaug urmaii de nivel i; nainte de
orice nou iteraie, cu excepia primei, asigurai-v c n iteraia precedent s-a
mai calculat cel puin un nou urma, iar n caz contrar oprii imediat buclarea,
pentru c s-a calculat deja nchiderea tranzitiv!).
a. Proiectai bd necesar gestionrii de ctre un SGBD relaional a utilizatorilor,
grupurilor de utilizatori i privilegiilor acestora, conform facilitilor oferite de
sublimbajul SQL de definiie a datelor.
b. Scriei instruciunea SQL pentru calculul urmtorului rspuns asupra acestei bd:
Care sunt utilizatorii ce fac parte din cel puin dou grupuri, fiecare dintre
acestea avnd mcar cte trei utilizatori? (indicaie: folosii subinterogri).
a. Proiectai cadrul unei familii parametrizate de instruciuni SQL pentru calculul
diferenei a dou coninuturi de relaii folosind predicatul IsNull.
b. Similar, acelai lucru pentru calculul diferenei simetrice.
a. ncercai s proiectai, programai n SQL i testai o instruciune SELECT cu o
clauz WHERE n care lista operatorului IN este un parametru. De ce credei c
testele nu reuesc? (indicaie: revedei tipurile de date oferite de motoarele
relaionale).
b. Proiectai totui o soluie pur SQL (ANSI-92) a acestei probleme (indicaie:
folosii o tabel temporar care s memoreze valorile actuale ale parametrului).
a. Proiectai o bd relaional n FNDC (vezi [1]) pentru gestiunea sistemului de
fiiere Windows, n contextul unei reele de calculatoare, n care fiecare calculator
poate avea mai multe discuri virtuale; mai intereseaz i serverele de baze de date
eventual gzduite de aceste calculatoare, bd gestionate de acestea i fiierele care
le memoreaz.
b. Scriei un program pentru calculul tuturor fiierelor existente n reea, ordonate
cresctor dup calea lor (indicaie: vezi indicaiile de la problema 29c!).
c. Scriei un program pentru calculul cii complete (i.e. de tipul \\calculator\drive
virtual:\...\nume fiier.extensie) a unui fiier oarecare (indicaie: i aceasta este tot
o problem de tip nchidere tranzitiv!).
d. Scriei instruciunea SQL corespunztoare interogrii: Care sunt fiierele ce nu
particip la memorarea nici unei baze de date? (indicaie: folosii predicatul
IsNull).
Scriei procedura VBA pentru crearea tabelei CTITORII din figura 44a (vezi i 5).
Scriei procedura VBA pentru crearea tabelei BTLII din figura 45a (vezi i 5).
Pornind de la exemplul 33 (i anume interogarea (Q119)), artai c singura
alternativ de a calcula diferena a dou mulimi n SQL necesit recursul la o
tabel temporar i la sublimbajul de manipulare a datelor.
Proiectai i scriei o procedur catalogat SQL pentru calculul diferenei simetrice
a dou tabele oarecare (considerate drept parametri).
Proiectai i scriei procedurile catalogate SQL pentru calculul i afiarea tuturor
indexilor injectivi non-minimali dintr-o bd (dat drept parametru) memorat pe un
tip de server la alegerea Dvs. (e.g. MS SQL Server, Oracle, IBM DB/2 etc.).
81

39
40

Idem cu problema 38, nlocuind ns indexi injectivi non-minimali cu referinele


de integritate circulare.
a. Folosind operatorul UNION ca n observaia 7 de la 3.1.3 s se arate c
operatorul (IBM SQL DB/2) FULL OUTER JOIN, care este n acelai timp i
LEFT i RIGHT JOIN, este, la rndul su, un operator derivat (i.e.
nefundamental).
b. Ce diferen exist ntre operatorii FULL OUTER JOIN i produs cartezian?

6 Comentarii i referine bibliografice


SQL provine din SEQUEL (acronimul pentru Structured English QUEry
Language), creaie a cercettorilor corporaiei IBM (vezi [5]), bazat la rndul su pe
teoria calcului relaional al tuplilor (vezi [1]) i limbajul aferent ALPHA propuse tot de
printele modelului relaional, distinsul cercettor IBM E.F.Codd (vezi [6]).
Astzi, SQL este un standard universal n programarea bd: de remarcat nu doar c
aproape toate SGBD relaionale existente se bazeaz pe acest limbaj, dar i c majoritatea celor nerelaionale (e.g. obiectuale, deductive) i bazeaz limbajele aferente (e.g.
Gomql, MMEDQL) tot pe SQL (vezi [1]).
Atragem atenia asupra faptului c lucrarea de fa a fost redactat pentru toate
nivelurile, de la nceptori la experi, ns mai degrab drept o referin tinznd ntru
exhaustivitate. Ca atare, ea se preteaz la citiri multiple i trebuie folosit n
consecin: nceptorii pot sri peste VBA, majoritatea detaliilor din observaii, notelor
de subsol i problemelor propuse avnd numr mai mare de 27, fiind ncurajai n
schimb s exerseze fiecare exemplu, verificnd cu atenie rezultatele obinute i s
rezolve primele 27 probleme propuse, n timp ce, desigur, experii se vor delecta cu
multe dintre toate acestea, ignornd complet att rezultatele interogrilor (cu excepia
cazului n care ar fi pasionai de istoria noastr medieval), ct i primele 27 probleme
propuse.

7 Lista referinelor bibliografice


0. D.E.C., ISO/IEC 9075:1992 Database Language SQL Standard,
Maynard, Massachussets, July 30, 1992 (vezi, de exemplu, http://
www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt).
1. C. Manca, Proiectarea i interogarea conceptual a bazelor de date,
note de curs, Universitatea Ovidius, Constana, 2002 (n curs de
publicare).
2. Microsoft Corporation, Programming MS Access 2002, Microsoft Press,
2001.
3. Microsoft Corporation, Access 2002 Users Guide, Microsoft Press, 2001.
4. Microsoft Corporation, MS Office XP Visual Basic Programmers Guide,
Microsoft Press, 2001.
5. D.D. Chamberlin & R.F. Boyce, SEQUEL A Structured English Query
Language, SIGMOD Workshop vol. 1, 1974, 249-264.
6. E. F. Codd, A database sublanguage founded on the relational calculus,
In ACM SIGFIDET Workshop on Data Description, Access and Control,
1971:35-61.

82

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