Professional Documents
Culture Documents
34. Care este varianta corecta pentru a crea tabelul CARTE, cu caracteristicile de mai jos, indicand cheile la nive
de coloana?
(Tabelele DOMENIU_CARTE si CARTE sunt in relatia 1:M)
care este secventa corecta pentru a modifica salariile cu 10% , care nu contin valori NULL?
a. UPDATE PROF SET SALARIU = SALARIU*1.1
WHERE SALARIU NOT NULL;
b. UPDATE PROF SET SALARIU = SALARIU*1.1
WHERE SALARIU IS NOT NULL;
c. UPDATE PROF SElLECT SALARIU = SALARIU*1.1
WHERE SALARIU <>0;
49. Pentru tabelul PROF
cod_prof# cod_fac nume pren salariu cod_funct
care este secventa corecta pentru a sterge toate cadrele didactice care sunt profesori consultanti?
a. DELETE FROM PROF WHERE
b. COD_FUNCT=’C’;
c. DELETE PROF WHERE COD_FUNCT<>’C’;
d. DROP FROM PROF WHERE COD_FUNCT=’C’;
DROP
50. Pentru tabelul:PROF WHERE COD_FUNCT=’C’;
FAC
cod_fac# denumire adresa
care este secventa corecta pentru o inserare, folosind instructiunea SELECT
care este secventa corecta pentru a afisa toti profesorii impreuna cu media _ salariu pentru fiecare
facultate , rotunjita la doua pozitii zecimale
a. SELECT COD_FAC,
ROUND (AVG (SALARIU), 2) AS
FROM PROF medie_salariu
ORDER BY COD_FAC;
b. SELECT COD_FAC,
ROUND (AVG (SALARIU, 2) AS
FROM PROF medie_salariu
GROUP BY COD_FAC;
c. SELECT COD_FAC,
ROUND (AVG (SALARIU), 2) AS
FROM PROF medie_salariu
GROUP BY COD_FAC;
d. SELECT FROM PROF COD_FAC,
ROUND AVG (SALARIU), 2 AS
medie_salariu
GROUP BY COD_FAC;
52. Pentru
tabelul
cod_prof# cod_fac nume pren salariu
care este secventa corecta pentru a afisa suma salariilor tuturor profesorilor din universitate.
a. SELECT SUM (Salariu) AS Total_Salariu
FROM PROF;
b. SELECT SUM (Salariu) AS Total_Salariu
FROM PROF
GROUP BY COD_FAC;
c. SELECT SALARIU, SUM (Salariu) AS
Total_Salariu
d. FROM PROF;
SELECT COD_FAC, SUM (Salariu) AS Total_Salariu
53. PentruFROM PROF;
tabelul
cod_prof# cod_fac nume pren salariu
care este secventa corecta pentru a afisa toti profesorii pentru care COD_FAC =1 si
salariu>=1200, sau toti profesorii pentru care COD_FAC =3 si salariu < 2000.
FAC
cod_fac# denumire adresa
care este secventa corecta pentru o interogare de uniune interna(inner join) care sa afiseze toti profesorii si
denumirile facultatilor la care predau, in ordinea crescatoare a denumirilor
a. SELECT NUME, PREN, DENUMIRE
FROM FAC, PROF
WHERE A.COD_FAC =B.COD_FAC
ORDER BY FAC.DENUMIRE;
b. SELECT NUME, PREN, DENUMIRE
FROM FAC, PROF
WHERE
FAC.COD_FAC=PROF.COD_FAC ORDER
BY FAC.DENUMIRE;
c. SELECT NUME, PREN, DENUMIRE
FROM FAC, PROF
WHERE FAC.COD_FAC=PROF.COD_FAC;
58. a.Să SELECT
se obtinapentru
codcfiecare carte, codul sau şi numarul de exemplare care nu au fost inca restituite.
FROM IMPRUMUTA
WHERE dataef IS
NULL
GROUP BY codc;
b. SELECT COUNT(*)
FROM
IMPRUMUTA
GROUP BY codc;
c. SELECT codc,
COUNT(*)
FROM IMPRUMUTA
WHERE
GROUP BY dataef codc;
IS
d. SELECT COUNT(*)
FROM
IMPRUMUTA
WHERE
GROUP BY dataef =0 codc;
59. Care este secventa corecta care să afişeze numărul cărŃilor împrumutate cel puŃin de
două ori
(pentru fiecare carte împrumutată mai mult decât o dată să se obŃină numărul de câte o
a fost împrumutată).
a. SELECT
COUNT(COUNT(codel))
FROM imprumuta
GROUP BY codcarte
b. HAVING COUNT(*)>1;
SELECT COUNT(codel)
FROM imprumuta
GROUP BY codcarte
HAVING COUNT(*)>1;
c. SELECT COUNT(COUNT(codel))
FROM imprumuta
WHERE COUNT(*)>1;
d. SELECT COUNT(codel)
FROM imprumuta
ORDERBY BY codcarte
HAVING COUNT(*)>1;
60. Care este secventa corecta care afiseaza pentru fiecare domeniu de carte, numărul
cărŃilor din domeniu, media preŃurilor şi numărul total de exemplare
FAC
cod_fac# denumire adresa
care este secventa corecta pentru o interogare de uniune externa catre stanga, care sa afiseze toti profesorii si
denumirile facultatilor la care predau
care este secventa corecta pentru o subinterogare necorelata, care sa afiseze toate functiile pentru care nu
exista profesorii incadrati
a. SELECT cod_funct, nume_funct
FROM functii
WHERE cod_funct NOT IN
(SELECT DISTINCT cod_funct FROM
b. prof);
SELECT cod_funct, nume_funct
FROM functii
WHERE cod_funct NOT IN
c. SELECT DISTINCT cod_funct FROM prof;
SELECT cod_funct, nume_funct
FROM functii
WHERE cod_funct IN
63. Care(SELECT
este comandacod_funct
corecta careFROM
pentruprof);
fiecare facultate, se insereaza in tabelul TOTALURI(cod_fac,
nr_prof, total_sal_fac) numarul de profesori si suma salariilor pe care facultatea o plateste profesorilor sai?
a. INSERT TO TOTALURI
SELECT COD_FAC, COUNT(*) , SUM(SALARIU)
FROM PROF ORDER BY COD_FAC;
b. INSERT INTO TOTALURI
SELECT COD_FAC, COUNT(*) , SUM(SALARIU)
FROM PROF ;
c. INSERT INTO TOTALURI
SELECT COD_FAC, COUNT(*) ,
SUM(SALARIU) FROM PROF
GROUP BY COD_FAC;
d. INSERT INTO TOTALURI
SELECT COD_FAC, SUM(COD_PROF), SUM(SALARIU)
FROM PROF
GROUP BY COD_FAC;
64. Să se obŃină titlurile şi preŃurile cărŃilor mai scumpe decât cartea având titlul “Baze de date”, al cărui
autor este Popescu (self join).
a. DELETE salariu
FROM salariati
WHERE contract=’colaborare’;
b. UPDATE salariati
SET salariu IS null
WHERE contract=’colaborare’;
c. DROP salariu
FROM salariati
WHERE contract=’colaborare’;
d. UPDATE salariati
SET salariu=null
WHERE contract=’colaborare’;
78. Care este comanda corecta care afiseaza codul departamentelor, numele departamentelor si suma salariilor
pentru fiecare departament?
a. SELECT cod_departament, nume_departament, SUM(salariu)
FROM salariati s, departamente d
GROUP BY cod_departament, nume_departament;
b. SELECT cod_departament, nume_departament, SUM(salariu)
FROM salariati s, departamente d
WHERE s.cod_departament=d.cod_departament
GROUP BY cod_departament;
c. SELECT cod_departament, nume_departament,
SUM(salariu) FROM salariati s, departamente d
WHERE s.cod_departament=d.cod_departament
GROUP BY cod_departament, nume_departament;
d. SELECT cod_departament, nume_departament, SUM(salariu)
FROM salariati, departamente
WHERE s.cod_departament=d.cod_departament
GROUP BY cod_departament, nume_departament;
79. Care este comanda corecta care afiseaza numele salariatilor care castiga mai mult decat salariul
mediu pe
companie,
a. SELECT in ordine
nume crescatoare a salariului?
FROM salariati
WHERE salariu >AVG(salariu);
b. SELECT nume
FROM salariati
WHERE salariu > (SELECT AVG(salariu) FROM
salariati) ORDER BY salariu;
c. SELECT nume
FROM salariati
WHERE salariu > (SELECT AVG(salariu) FROM salariati
ORDER BY salariu);
d. SELECT nume
FROM salariati
WHERE salariu > (SELECT AVG(salariu) FROM salariati)
ORDER BY 1;
80. Care este comanda corecta care afiseaza toate functiile pe care nu lucreaza angajati?
a. SELECT cod_functie
FROM functii
WHERE cod_functie IN
(SELECT cod_functie FROM salariati WHERE cod_functie IS NOT NULL);
b. SELECT cod_functie
FROM functii
WHERE cod_functie NOT IN
(SELECT cod_functie FROM salariati WHERE cod_functie IS NULL);
c. SELECT cod_functie
FROM functii
WHERE cod_functie NOT IN
(SELECT cod_functie FROM salariati);
d. SELECT cod_functie
FROM functii
WHERE cod_functie NOT IN
(SELECT cod_functie FROM salariati WHERE cod_functie IS NOT
NULL);
Intrebări şi probleme la cursul de Baze de date, anul III,
toate formele de învăŃământ
PARTEA I. Concepte despre Bazele de date relaŃionale. Normalizare
Probleme
1. Să se normalizeze tabelul CURS_SUDENT
.
1.3 Este tabela CURS_SUDENT realizată la 1.2 în FN3? (JustificaŃi răspunsul)
PROFESOR
IdProf Nume Catedra IdTitlu Titlu Salariu
1 Popescu Marin Matematici 1 lector dr. 1300
2 Dragnea Ion Limbi straine 4 asistent 950
3 Iosif Irina Educatie fizica 3 lector 1100
4 Ilie Daniel Informatica 2 conferentiar dr. 1700
5 Savu Cristina Limbi straine 5 prepartor 680
6 Cristea George Fizica 6 profesor dr. 2150
7 Ene Horia Informatica 1 lector dr. 1300
Amintim că o tabelă este în FN3 dacă este în FN2 şi toate coloanele care nu fac
parte din cheia primară sunt mutual independente (depind direct de cheia primară şi
numai de ea)
3. Tabelele Profesor şi Titlu sunt în relaŃia 1:m (un Titlu corespunde la mai
multe cadre didactice).
Tabele de mai sus păstrează regulile de integritate?
Constrângere:
toate avioanele cu acelaşi nume au aceeaşi capacitate.
Persoana Vehicul
Eu R25 - W14 - R21
Tu 205
El R5 - 305
noi BX - 305 - R12 - R25
ATASAT_LA
COD_SALARIAT# JOB_COD NR_PROIECT# FUNCTIA SUM
A
S1 PROGRAMATOR P1 SUPERVIZOR 60
S1 PROGRAMATOR P2 CERCETATOR 25
S1 PROGRAMATOR P3 AUXILIAR 10
S3 VANZATOR P3 SUPERVIZOR 60
S5 INGINER P3 SUPERVIZOR 60
Intrebări
AlegeŃi răspunsurile corecte pentru fiecare din următoarele întrebări cu răspunsuri
multiple. Întrebările pot avea mai multe răspunsuri corecte.
1. SQL este
a. EXCEL
b. MySQL
c. PostgreSQL
d. Oracle Database
a. RelaŃii
b. Tabele
c. Vizualizări de utilizator
d. Diagrame ERD
e. RestricŃii
6. Printre tipurile de restricŃii care pot fi folosite în bazele de date se numără
a. NOTNULL
b. RelaŃie
c. Cheie primară
d. CHECK
e. Unicitate
a. Anomalia de inserare
b. Performante reduse
c. Anomalia de creare
d. Anomalia de ştergere
e. Anomalia de actualizare
8. Procesul de normalizare
9. Un identificator unic(cheie)
c. DependenŃele tranzitive
d. Atributele multivaloare
b. Grupurile repetitive
c. DependenŃele tranzitive
b. Grupurile repetitive
c. DependenŃele tranzitive
d. Atributele multivaloare
1.
Cod_valuta Number
Valuta Currency
Curs Number
2 euro 35.000
3 dolar 33.000
1 franc
5 lira
4
3.
A Number
E Date
4.
1.Deschideti aplicatia de baze de date.
2.Creati o baza de date noua in direcctorul My Documents. Salvati-o cu numele
dumneavoastra.
3.Creati o tabela cu urmatoarele campuri:
5.
Tara Text-dimensiune 20
Data_curenta Date/Time- Short Date
Nume_firma Texe-dimensiune 30
Cheie_primara Autonumber
6.
1.Deschideti aplicatia de baze de date.
2.Creati o baza de date noua si salvati-o in directorul My Documents.
3.Utilizati functia Help pentru a cauta informatii despre tabele.
4.Creati o tabela noua si denumiti-o Informatii.
5.Introduce-ti in tabela 3 atribute.
6.In tabela creata stabiliti primul camp ca fiind cheie primara.
7.Creati un raport asupra acestei tabele.
8.Grupati datele din raport in functie de al doilea atribut.
9.Salvati raportul cu numele Raport.
10.Inchideti baza de date creata.
7.
1.Deschideti aplicatia de baze de date.
2.Creati o baza de date noua datele dumneavoastra pe directorul C :
3.Afisati pe ecran bara de instrumente WEB.
4.Creati o tabela cu urmatoarele atribute :
Nr_Crt Autonumber
Cod Numeric Byte
Firma Text dimensiune 20
Adresa Text dimensiune 25
8.
1.Deschideti o aplicatie de baze de date
2.Creati o baza de date noua in directorul C :
3.Creati o tabela in care introduceti 5 campuri.Dintre acestea 2 vor fi de tip
Text,2 vor fi numerice si 1 de tip data calendaristica
4.Creati un formular nou asupra tabelei create anterior.
5.Cu ajutorul noului formular introduceti in tabela 5 inregistrari
6.Adaugati numele dumneavoastra in antetul formei.
7.Creati o interogare care sa contina numai campurile 1 si 2
8.Rulati interogarea creata.
9.Imprimati doar inregistrarile selectate din tabela creata
10.Salvati toate datele si inchideti aplicatia de baze de date
9.
1. Deschideti o aplicatie de baze de date.
2. Creati o baza de date noua in directorul My Documents.
3. Creati o tabela cu urmatoarele campuri:
Numar_intrare Number
Data_intrare Date
Cantitate_intrata Number
Denumire_produs Text
10.
1. Deschideti o aplicatie de baze de date.
2. Creati o baza de date noua in directorul My Documents.
3. Creati o tabela denumita Elevi ce va contine urmatoarele campuri:
Nume_elevi Text
Data_nasterii Date
Varsta Number - Integer
Nr_scoala Number - Integer
Nume Text
Clasa Number
Medie Number
Nr_scoala Number - Integer
11.
1. Deschideti aplicatia de baze de date.
2. creati o baza de date noua si salvati-o in directorul My Documents.
3. Utilizati functia Help pentru a cauta informatii despre tabele.
4. Creati o tabela noua si denumiti-o Informatii.
5. Introduceti in tabela 3 atribute.
6. in tabela creata, stabiliti primul camp ca fiind cheie primara.
7. Creati un raport asupra acestei tabele.
8. Grupati datele din raport in functie de al doilea atribut.
9. Salvati raportul cu numele de Raport.
10. Inchideti baza de date creata.
1. Deschideti baza de date 11.mdb.
2. Stergeti tabela Informatii din baza da date.
3. Deschideti tabela Produs si modificati dimensiunea atributului Cantitate.
4. Deschideti formularul Produs.
5. Cu ajutorul formularului selectati inregistrarea 3 si modificati Cantitatea la 250.
6. Utilizati comanda Undo pentru a reface operatia anterioara.
7. Modificati lungimea unei coloane in tabela Comenzi.
8. Utilizati instrumental de cautare, pentru a gasi inregistrarea cu Cod_produs 4.
9. Stergeti aceasta inregistrare.
10. Inchideti aplicatia de baze de date.
12.
1. Deschideti aplicatia de baze de date.
2. Creati o baza de date noua in directorul My Documents. Salvati-o cu numele
dumneavoastra.
3. Creati o tabela cu urmatoarele campuri:
13.
1. Deschideti aplicatia de baze de date.
2. Creati o baza de date noua cu numele baza de date pe C:\
3. In baza de date noua creata, construiti o tabela cu urmatoarele atribute :
Oras Text dimensiune 20
Data examinarii Date/Time Short Date
Nume Centru Text dimensiune 30
Numar curent Autonumber
14.
1. Deschideti aplicatia de baza de date.
2. Creati o baza de date noua si salvati-o in directorul My Documents.
3. Utilizati functia Help pentru a cauta informatii despre tabele.
4. Creati o tabela noua si denumiti-o Informatii.
5. Introduceti in tabele 3 atribute .
6. In tabela creata stabiliti primul camp ca fiind cheie primara .
7. Creati un raport asupra acestei tabele .
8. Grupati datele din raport in functie de al 2-lea atribut .
9. Salvati raportul cu numele Raport.
10. Inchideti baza de date creata .
15.
1. Deschideti aplicatia de baza de date .
2. Creati o baza de date noua cu numele dumneavoastra pe directorul C:
3. Afisati pe ecran bara de instrumente Database .
4. Creati o tabela cu urmatoarele atribute :
A Number
E Date
17.
1. Deschideti o aplicatie de baza de date .
2. Creati o baza de date noua in directorul C :
3. Creati o tabela in care introduceti 5 campuri . Dintre acestea doua vor fi de tip
Text ,doua vor fi numerice si unul de tip data calendaristica .
4. Creati un formular nou asupra tabelei create anterior .
5. Cu ajutorul noului formular introduceti in tabela 5 inregistrari .
6. Adaugati numele dumneavoastra in antetul formei .
7. Creati o interogare care sa contina numai campurile 1 si 2 .
8. Rulati interogarea creata .
9. Imprimati doar inregistrarile selectate din tabela creata .
10.Salvati toate datele si inchideti aplicatia de baza de date .
1. Deschideti baza de date 17.mdb
2. Stergeti tabela Date din baza de date .
3. Deschideti tabela Casete imprumutate si modificati tipul atributului
Nr_casete_imprumutate ca fiind Integer .
4. Deschideti un formular existent .
5. Cu ajutorul formei selectati intregistrarea 4 si modificati Nr_casete la 15 .
6. Utilizati comanda Undo pentru a reface operatia anterioara .
7. Modificati lungimea unei colane din tabela Produs .
8. Utilizati instrumentul de cautare , pentru a gasi inregistrarea cu valoare Desene
animate pentru atributul Tip_film .
9. Stergeti aceasta inregistrare .
10.Inchideti aplicatia de baza de date .
18.
1. Deschideti aplicatia de baze de date .
2. Creati o baza de date noua in directorul My Documents . Salvati-o cu
numele dumneavoastra .
3. Creati o tabela cu urmatoarele campuri :
4. Mutati atributul Numar Curent astfel incat sa devina primul atribut din tabela .
5. Atasati atributului Oras optiunea Indexed with Duplicates .
6. Creati o regula de validare pentru atributul Numar Curent , astfel incat sa nu
primeasca valori mai mari de 256 .
7. Introduceti in tabela creata 5 inregistrari .
8. Imprimati toate inregistrarile din tabela .
9. Salvati toate datele .
10.Inchideti aplicatia de baze de date .
20.
1. Deschideti aplicatia de baze de date
2. Creati o baza de date noua cu numele dumneavoastra pe C:/
3. In baza de date nou creata construiti o tabela cu urmatoarele atribute
Nume_depozit Text-dimensiune 20
Data_curenta Date/Time- Short Date
Nume_material Text- dimensiune 30
Cod_curent Autonumber
Întrebări şi Probleme
AlegeŃi răspunsurile corecte pentru fiecare din următoarele întrebări cu răspunsuri
multiple. Întrebările pot avea mai multe răspunsuri corecte.
1. SQL este
a. Un limbaj orientat spre obiecte
b. Un limbaj procedural
c. Un limbaj nonprocedural
d. Un limbaj declarativ
e. Un limbaj standard
9. InstrucŃiunile SQL
a. încep cu un cuvânt cheie reprezentând o comandă
b. Se termină cu un cuvânt cheie reprezentând o comandă
c. încep cu un delimitator, cum ar fi caracterul punct şi virgulă
d. Se termină un delimitator, cum ar fi caracterul punct şi virgulă
e. încep cu o paranteză deschisă
3. Operatorul BETWEEN
a. Specifică un domeniu de valori care include şi capetele
b. Poate fi rescris folosind operatorii <= şi NOT <=
c. Poate fi rescris folosind operatorii <= şi >=
d. Selectează rândurile adăugate în tabel într-un anumit interval de timp
e. Nu este inclus în standardul ISO/ANSI
Întrebări şi probleme
l. O subinterogare
a. Poate fi folosită pentru a selecta valorile care vor fi aplicate condiŃiilor din
clauza WHERE
b. Poate fi corelată sau necorelată
c. Reprezintă o cale puternică de calculare a coloanelor
d. Trebuie să nu fie încadrate în paranteze
e. Permite selectarea flexibilă a rândurilor
5. O uniune (Join)
a. Combină coloanele din două sau mai multe tabele în rezultatele unei singure
interogări
b. Combină rânduri din interogari multiple într-un singur set de rezultate
c. Este realizată ori de câte ori în clauza FROM sunt specificate mai multe tabele
d. Necesită folosirea unei clauze JOIN
e. Necesită o listă de tabele separate prin virgule în clauza FROM
interogărilor avansate
Întrebări şi Probleme
1. FuncŃiile SQL
a. Returnează un set de valori
b. Returnează o singură valoare
c. Pot fi folosite în clauza WHERE a unei instrucŃiuni SQL
d. Pot fi folosite ca pseudonime pentru numele tabelelor intr-o instr. SQL
e. Pot fi folosite în lista de coloane a unei instrucŃiuni SQL
2. FuncŃia REPLACE
a. Înlocuieşte un nume de tabel cu un nume de vizualizare
b. Înlocuieşte numele unei coloane cu pseudonimul coloanei
c. Înlocuieşte un şir de caractere dintr-o coloană cu un alt şir de caractere
d. Înlocuieşte toate valorile dintr-o coloană cu un alt set de valori
e. Înlocuieşte toate rândurile dintr-o vizualizare cu rânduri conŃinând date dintr-
un alt tabel
3. FuncŃia LTRIM
a. Elimină spaŃiile de la sfârşitul şirurilor de caractere
b. Elimină spaŃiile de la începutul şirurilor de caractere
c. Poate fi imbricată cu alte funcŃii
d. înlocuieşte valorile nule cu alte valori în şirurile de caractere
e. Elimină spaŃiile de la începutul şi de la sfârşitul şirurilor de caractere
4. FuncŃia CHAR
a. Este numită CHR în unele implementări SQL
b. Este identică cu funcŃia ASCII în unele implementări SQL
c. Returnează valoarea corespunzătoare unui caracter din setul de caractere ASCII
d. Returnează caracterul corespunzător unei valori
e. Transformă o valoare numerică într-un şir de caractere
5. FuncŃia SIGN
a. Returnează -l daca parametrul furnizat are valoare negativa
b. Returnează 0 dacă parametrul furnizat are valoarea zero
c. Returnează +1 dacă parametrul furnizat are o valoare pozitivă
d. Returnează 0 dacă parametrul furnizat are valoarea NULL
e. Returnează o valoare nulă dacă parametrul furnizat nu este un număr
6. FuncŃia CEILING
a. Rotunjeşte un număr prin adăugire până la primul număr întreg
b. Rotunjeşte un număr prin scădere până la primul număr întreg
c. Returnează întotdeauna un număr întreg
d. Returnează un număr întreg sau o valoare nulă
e. Este numită CEIL în unele implementări SQL
7. FuncŃia FLOOR
a. Rotunjeşte un număr prin adăugire până la primul număr întreg
b. Rotunjeşte un număr prin scădere până la primul număr întreg
c. Returnează întotdeauna un număr întreg
d. Returnează un număr întreg sau o valoare nulă
e. Este numită FLR în unele implementări SQL
8. Expresiile CASE
a. Permit executarea condiŃională a clauzelor dintr-o instrucŃiune SQL
b. Există sub două forme, respectiv statice şi dinamice
c. Exista sub două forme, respectiv cu căutare şi fara cautare
d. Există sub două forme, respectiv simple şi cu cautare
e. Există sub două forme, respectiv standard şi cu cautare
9. O instrucŃiune UPDATE
a. Trebuie să includă o clauză SET
b. Trebuie să furnizeze o nouă valoare pentru cel puŃin o coloană
c. Trebuie să includă o clauză WHERE
d. Poate atribui unei coloane valoarea unei alte coloane
e. Poate atribui unei coloane o listă de valori derivate dintr-o expresie
11. Clauza SET dintr-o instrucŃiune UPDATE poate atribui unei coloane o valoare
care este
a. O constantă
b. Numele unei alte coloane
c. O listă de valori
d. Orice expresie din care rezultă o singură valoare
e. Cuvântul cheie NULL
Atunci când se foloseste operatorul “+” , apare o eroare de tipul Type Mismatch (Nepotrivire de tip) in
cazul cand
a. ambii operanzi sunt valori numerice
b. ambii operanzi sunt siruri de caractere
c. un operand este valoare numerica si celalalt un sir de caractere
d. un operand este valoare numerica si celalalt de tipul date/time
Care din următoarele baze de date nu este RDBMS
a. Postage SQL
b. Oracle Database
c. My SQL
d. Microsoft SQL Server
e. Excel database
Care nu este un concept utilizat pentru a descrie formal-uzual-fizic elementele de baza ale organizarii
datelor
a. relatie-tablou-fisier
b. tuplu-linie-inregistrare
c. atribut-coloana-camp
d. domeniu-functie-functie
Cind se realizeaza un table cu Report View din tabele relationale, informatiile fiind grupate pe parte one
a relatiei si se opteaza pentru SUMMARY OPTION atunci:
a. se introduc calculele solicitate in banda de subsol de grup
b. se introduc calculele solicitate in banda de detaliu de grup
c. se introduc calculele solicitate in benzile de subsol de grup de subsol de raport
d. se introduc calculele solicitate in banda de detaliu de grup si subsol de grup
Cate reguli a emis Codd / Modelul relational conceput si dezvoltat de E.F. Codd cuprinde un set de
a. 25 reguli
b. 13 reguli
c. 100 reguli
d 15 reguli
Cand operatorii AND si OR sunt combinati in aceeasi clauza WHERE
a. Operatorul AND are prioritate mai mare decat operatorul OR
b. Sistemul DBMS returneaza un mesaj de eroare
c. Operatorul AND are prioritate mai mica decat operatorul OR
d. Parantezele, sunt obligatorii
Dacă tabelele dintr-o interogare nu sunt legate una de alta fie direct (în interogare), fie indirect (prin
legătură implicită, din fereastra Relationship), Acces afisează
a. Toate combinatiile de înregistrări (produs cartezian) dintre câmpurile tabelelor
b. Numai înregistrările din prima tabelă
c. Numai înregistrările din ultima tabelă
d. Nu afisează nimic
<!>Din ferestra Relationships la apasarea butonului Join Type se poate selecta modul in care vor fi
extrase datele din tabele, mod care nu poate fi:
a. numai acele înregistrari în care câmpurile din legatura coincid
b. toate înregistrarile din tabela principala si numai acele înregistrari din tabela corelata în care
câmpurile din legatura coincid.
c. toate înregistrarile din tabela corelata si numai acele înregistrari din tabela principala în care
câmpurile din legatura coincid.
d. toate inregistrarile din ambele tabele
<!>Din ferestra Relationships la apasarea butonului Join Type se poate selecta modul in care vor fi
extrase datele din tabele, mod care nu poate fi:
a. numai acele înregistrari în care câmpurile din legatura coincid
b. toate înregistrarile din tabela principala si numai acele înregistrari din tabela corelata în care
câmpurile din legatura coincid.
c. toate înregistrarile din tabela corelata si numai acele înregistrari din tabela principala în care
câmpurile din legatura coincid.
d. toate inregistrarile din ambele tabele
Expresiile nu se utilizează în
a. Definirea unui criteriu de selectie
b. Crearea unui câmp calculat
c. Actualizarea unor înregistrări într-o interogare
d. Definirea proprietătii Validation Text a unei tabele
Functia AVG(Expr):
a. include campuri de valoare NULL in calcul
b. poate fi folosita intr-o interogare
c. calculeaza media geometrica a datelor din acel camp
d. operanzii din Expr nu pot include o functie definita de utilizator.
Functiile SQL matematice standard NU includ :
-ROUND
-ABS
-CAST
-EXP
Functia LTRIM
a. Elimina spatiile de la sfarsitul sirurilor de caractere
b. Elimina spatiile de la inceputul sirurilor de caractere
c. Poate fi imbricata cu alte functii
d. Inlocuieste valorile nule cu alte valori in sirurile de caractere
e. Elimina spatiile de la inceputul si de la sfarsitul sirurilor de caractere
Integritatea referintiala este un sistem de reguli folosit de Acces pentru a se asigura ca:
a. relatiile intre tabele sunt valide
b. relatiile intre tabele nu se modica
c. relatiile intre tabele sunt valide si ca nu se sterg sau modica accidental datele in legatura
d. nu sunt definite relatii
O uniune de egalitate(equijoin):
a. este cunoscuta si sub numele de auto-uniune(slfjoin)
b. este cunoscuta si sub numele de uniune externa(outerjoin)
c. realizeaza intotdeauna legarea randurilor folosind o conditie de egalitate(=)
d. realizeaza intotdeauna legarea randurilor folosind o conditie de inegalitate(<>)
O cheie Primara nu poate fi setata: U click-dreaptape campul dorit sa fie cheie primarasi din meniul
afisat se apasa Primary Key sau U se selecteaza campul respectiv si se apasa butonul de Primary Key
meniul Design View,U se deschide fereastra de definire a unui index caruia i se adreseaza proprietatea
Primary la Yes.
a. cu click dreapta pe campul dorit sa fie cheie primara si din meniul afisat se apasa Primary Key.
b. daca se deschide fereastra de definire a unui index si se creeaza un index caruia i se seteaza
proprietatea Primary la Yes.
c. din FieldProprerties,Indexed,Yes(No Duplicates)
d. daca se selecteaza campul respectiv si se apasa butonul de Primary Key din meniul Design View.
O interogare incrucisata (Crosstab) este realizata dintr-o o interogare de selectie, din care se poate alege
a. toate campurile interogarii
b. cel mult 3 campuri pentru antet de linii, un camp pentru antet coloana si o functie aplicata
valorilor dintr-un camp
c. cal putin 3 campuri pentru antet de linii, si mai multe campuri entru antet coloana si o functie aplicata
valorilor dintr-un cimp
d. nu se poate realiza astfel de interogari
O forma (sau formular) reprezinta modalitatea de a
a. modifica date numai dintr-o singura tabela
b. modifica, adauga, sterge date din mai multe tabele
c. modifica date dintr-o singura interogare
d. modifica date dintr-o interogare si un tabel
O uniune de egalitate(equijoin):
a. este cunoscuta si sub numele de auto-uniune(slfjoin)
b. este cunoscuta si sub numele de uniune externa(outerjoin)
c. realizeaza intotdeauna legarea randurilor folosind o conditie de egalitate(=)
d. realizeaza intotdeauna legarea randurilor folosind o conditie de inegalitate(<>)
O interogare incrucisata (Crosstab) este realizata dintr-o interogare de selectie din care se poate alege:
a. toate campurile interogatorii
b. cel mult 3 campuri pt. antet de linii,un camp pt. antet coloana si o functie aplicata valorilor
dintr-un camp.
c. cel putin 3 campuri pt. antet de linii si mai multe campuri penru antet coloana si o functie aplicata
valorilor dintr-un camp.
d. nu se poate realiza astfel de interogari.
Pentru a crea un raport utilizând generatorul (Report Wizard) avem planul general cu optiunea implicita
a. Columnar
b. Tabular
c. Justified
Pentru a introduce câmpuri calculate într-un raport se foloseşte elemente din bara toolbox
a. Label Box Aa
b. Text Box ab
c. Check
d. Combo Box
Pentru aducerea in prima forma normala a unei relatii ne-normalizate se operatie nu se efectueaza ?
a. Grupurile repetitive sunt mutate intr-o noua relatie
b. Atributele multivaloare sunt mutate intr-o noua relatie
c. Atributele care sunt dependente tranzitiv sunt eliminate
d. Identificatorul unic al unei relatii originale este copiat in noua relatie
Pentru a introduce câmpuri calculate într-un raport se foloseste din bara toolbox:
a. Label Box Aa
b. Text Box ab
c. Check
d. Combo Box
Sintaxa corecta pentru eliminarea valorilor nule din rezultatele interogarii este
a. = NULL
b. NOT = NULL
c. <>NULL
d. IS NULL
e. IS NOT NULL
SQL NU este:
a. Un limbaj procedural
b. Un limbaj nonprocedural
c. Un limbaj declarativ
d. Un limbaj standard
Valorile NULL
a. pot fi folosite pentru reprezentarea datelor care lipsesc sau care nu sunt cunoscute
b. înseamnă acelaşi lucru ca şi spaţiile libere
c. sunt egale cu alte valori NULL
d. sunt întotdeauna permise în mod prestabilit
Pentru a crea un raport utilizand report Wizard avem planul general cu optiunea implicita
- am raspuns: tabular
Operatorul BETWEEN
a. Specifică un domeniu de valori care include si capetele
b. Poate fi rescris folosind operatorii <= si NOT <=
c. Selectează rândurile adăugate în tabel într-un anumit interval de timp
d. Nu este inclus în standardul ISO/ANSI
O instructiune DELETE nu
a. Poate include o listă optională de coloane
b. Poate include o clauză WHERE optională
c. Nu poate încălca restrictiile referentiale ale tabelului
d. Poate avea o instructiune SELECT internă, ca parte a clauzei WHERE
Access permite crearea unor relaţii logice sub forma unor legări între tabele
- temporale (la nivelul interogărilor) şi implicite (din fereastra Relationships)
Instructiune SQL prin care se cerea sa se stearga toti profesorii din tabel.
- DELETE profesori FROM tabel
table prof cod fac, cod prof,nume, prenume, salariu, cod functie
care este secventa corecta , pentru a modifica functia si salariu prof cu (cod_fac=2 cod_prof=1) din
lector(cod_funct=3, salariu 2000) la conferentiar(cod_funct=4, salriu=3000)?
-UPDATE PROF SET COD_FUNCT=4, SALARIU=3000
WHERE COD_FAC=2 AND COD_PROF=1;
-UPDATE PROF SELECT COD_FUNCT=4, SALARIU=3000
WHERE COD_FAC=2 AND COD_PROF=1;
-UPDATE PROF SET COD_FAC=2 AND COD_PROF=1
WHERE COD_FUNCT=4, SALARIU=3000;
2 tabele a. ca cel de la nr 12 b.functii
cod functii, den functii
care este secventa corecta pentru o subinterogare necorelata, care sa afiseze toate functiile pentru care nu
exista profesorii incadrati
-SELECT cod_funct, nume_funct
FROM functii
WHERE cod_funct NOT IN
(SELECT DISTINCT cod_funct FROM prof)
-SELECT cod_funct, nume_funct
FROM functii WHERE cod_funct NOT IN
SELECT DISTINCT cod_funct FROM prof
-SELECT cod_funct, nume_funct
FROM functii
WHERE cod_funct IN
(SELECT cod_funct FROM prof);
Pt. tabelul:
PROF cod_fac# cod_prof# nume prenume salariu
care este secvența corectă pt. a insera o înregistrare:
• INSERT INTO PROF VALUES (4, 3, ’POPA’, ’DAN’, 1234)
• INSERT INTO PROF VALUES (4, 5, POPA, DAN, 1234)
• INSERT INTO PROF (cod_prof, nume, prenume, salariu) VALUES (4, 3, ’POPA’, ’DAN’, 1234)
Pt. tabelul:
PROF cod_fac# cod_prof# nume prenume salariu
care este secvența corectă pt. a afișa toate facultățile pt. care COD_FAC=1 și salariu>=1200, sau
facultățile pt. care COD_FAC=3 și salariu<2000
• SELECT COD_FAC, COD_PROF, NUME, SALARIU, FROM PROF WHERE (COD_FAC=1
AND SALARIU>1200) OR (COD_FAC=3 AND SALARIU<2000)
Au mai fost 3 variante asemănătoare unde erau înlocuite AND cu OR
O interogare SQL din care trebuie selectati din tabelul PROF profesorii care au codul facultatii
(COD_FAC) egal cu 8
a. SELECT FROM PROF WHERE COD_FAC=8;
b. SELECT FROM PROF WHERE COD_FAC<>8;
c. SELECT FROM PROF WHERE COD_FAC IS 8; (asa imi aduc aminte aici, dar daca nu era IS era tot
o balarie)
Pentru tabelul PROF Cod_fac# | Cod_prof# | Nume | Pren | Salariu
Care este secventa corecta pentru a modifica salariile cu 10%, care nu contin valori NULL?
a. UPDATE PROF SET SALARIU = SALARIU*1.1
WHERE SALARIU NOT NULL;
b. UPDATE PROF SET SALARIU = SALARIU*1.1
WHERE SALARIU IS NOT NULL
c. UPDATE PROF SELECT SALARIU = SALARIU*1.1
WHERE SALARIU <> 0;
Dacă tabelele dintr-o interogare nu sunt legate una de alta fie direct (în interogare), fie indirect (prin
legătură implicită, din fereastra Relationship), Acces afișează
• Toate combinațiile de înregistrări (produs cartezian) dintre câmpurile tabelelor
• Numai înregistrările din prima tabelă
• Numai înregistrările din ultima tabelă
• Nu afișează nimic
Pentru aducerea in prima forma normala a unei relatii ne-normalizate ce operatie nu se efectueaza
Raspuns: nu mai tin minte cum era formulat ceva despre atribute dependent tranzitive, oricum era
singurul care nu avea legatura cu FN1
Tabelul PROF cu coloanele cod_fac, cod_prof, nume, ore, salariu se intreba care este secventa corecta
pentru a afisa suma salariilor tuturor profesorilor (de la toate facultatile)
Raspuns:
SELECT SUM(salariu) AS TotalSalarii
FROM PROF
GROUP BY
Se dadea tabelul FAC cu campurile cod_fac, denumire si adresa si se intreba care este varianta corecta
pentru introducerea unei noi inregistrari
Raspuns:
INSERT INTO FAC
(cod_fac, denumire, adresa)
SELECT VALUES (MAX(cod_fac)+1, 'o demunire', 'o adresa');
Operatorul LIKE
Raspuns: Foloseste caracterul procent drept caracter de inlocuire nepozitional
O interogare SQL prin care se solicita afisarea rotunjirii mediei salariilor profesorilor, cu 2 zecimale,
grupat dupa facultati.
Aici a fost ceva ciudat. O varianta era cu SORTED BY, una era cu expresia numerica fara o paranteza si
2 erau identice, si aici ma refer la semne de punctuatie, paranteze, spatii, etc.
Aceste 2 variante identice aveau si formatul corect din punctul meu de vedere:
SELECT ROUND(AVG(expresie numerica),2)AS salarii
FROM prof GROUP BY COD_FAC;
Care nu este un concept utilizat pentru a descrie formal-uzual-fizic elementele de baza ale organizarii
datelor:
raspuns: domeniu- functie-functie
Un sistem de gestiune al bazelor de date este:
raspuns : un produs software furnizat de un producator de baze de date
Numerele stocate in campuri nenumerice ale unei interogari sunt sortate:
raspuns: ca siruri de caractere
Care nu este restrictie (Tipuri de restrictii)
raspuns: relatie ( mai erau variantele primary key, not null, check)
Functia NOW() ...
raspuns: returneaza data si ora sistemului
Eliminarea valorilor nule ...
raspuns: IS NOT NULL
57. Instructiunile SQL ....
raspuns: incep cu un cuvant cheie si se termina cu caracterul;
58. Intr-un aranjament client server:
raspuns: componentele soft ale clientului SQL ruleaza pe client
O auto-uniune:
raspuns: autouniunea foloseste un singur tabel
extensiile procedurale ale limbajului sql includ:java,c++,php, oracle pl/sql
pt tabelul ...
raspuns INSERT INTO PROF(cod_prof nume, prenume, salariu) NAMES (4,3,POPA,DAN,1234)
nu este functie sql standard pt siruri de caractere:upper, lenght, lower, like
pt tabelul...
raspuns SELECT DISTINCT DENUMIRE FROM FAC WHERE 1000<(SELECT sum(salariu)
O uniune join --combina coloanele din doua sau mai multe tabele in rezultatul unei singure
interogari
un sistem dbms nu ofera serviciul- - mecanisme de securitate
un index poate fi creat pe urmat tipuri-- text number, currency sau date and time
daca relationarea tabelelor dintr-o interogare s-a facut prin definirea legaturilor implicite atunci:
- adaugarea lor intr-o interogare se face impreuna cu relatiile dintre ele
interogarea cu stergere sterge.. daca stergerile in cascada sint active
prin operatia de import nu se pot introduce in baza de date
- tabele de informare din baze de date in versiuni mai vechi..
prima forma normala rezolva anomaliile
- grupuri repetitive si atribute multivaloare
integritatea referentiala este un sistem de reguli folosit de acces pt a se asigura ca :
relatiile intre tabele sint valide
care nu este un concept utilizat pt a descrie formal- uzual- fizic
- domeniu-functie- functie
text boxurile unei forme create automat
- sint legate direct la mai multe tabele astfel incit orice modificare adusa valorilor din ele se
transmite..
Tabelul PROF cu coloanele cod_fac, cod_prof, nume, ore, salariu se intreba care este secventa corecta
pentru a afisa suma salariilor tuturor profesorilor :
SELECT SUM(salariu) AS TotalSalarii FROM PROF
Dacă o tabelă din baza de date cerută care a fost legată de o tabelă externă, se şterg
- se şterge şi legătura sa, nu însă şi fişierul extern de care a fost legat
LABORATOR 1 SQL
CERERI MONOTABEL
1. Analizaţi sintaxa simplificată a comenzii SELECT. Care dintre clauze sunt obligatorii?
SELECT { [ {DISTINCT | UNIQUE} | ALL] lista_campuri | *}
FROM [nume_schemă.]nume_obiect ]
[, [nume_schemă.]nume_obiect …]
[WHERE condiţie_clauza_where]
[GROUP BY expresie [, expresie …]
[HAVING condiţie_clauza_having] ]
[ORDER BY {expresie | poziţie} [, {expresie | poziţie} …] ]
2. Găsiţi eroarea din instrucţiunea următoare.
SELECT employee_id, last_name, salary * 12 salariu anual
FROM employees;
Obs: SALARIU ANUAL este un alias pentru câmpul care reprezintă salariul anual.
Dacă un alias conţine blank-uri, el va fi scris obligatoriu între ghilimele. Altfel, ghilimelele pot fi
omise. Alias-ul apare în rezultat, ca antet de coloană pentru expresia respectivă. Doar cele specificate între
ghilimele sunt case-sensitive, celelalte fiind scrise implicit cu majuscule.
Varianta 1:
SELECT employee_id, last_name, salary * 12 salariu_anual
FROM employees;
Varianta 2:
SELECT employee_id, last_name, salary * 12 " Salariu Anual "
FROM employees;
1
7. Să se afişeze codul angajatului, numele, codul job-ului, data angajării. Salvaţi instrucţiunea SQL într-un
fişier numit p1_14.sql.
Obs: Pentru salvarea ultimei comenzi SQL se utilizează comanda SAVE. Precizarea extensiei „.sql” a
fişierului nu este obligatorie.
SELECT employee_id, last_name, job_id, hire_date
FROM employees;
SAVE z:\…\ p1_14.sql
8. Reexecutaţi cererea folosind fişierul p1_14.sql.
START z:\…\ p1_14.sql
sau
@ z:\…\ p1_14.sql
9. Editaţi fişierul p1_14.sql, adăugând coloanelor câte un alias (cod, nume, cod job, data angajarii).
EDIT z:\…\ p1_14.sql
@ z:\…\ p1_14.sql
18. Să se afişeze numele şi data angajării pentru fiecare salariat care a fost angajat în 1987. Se cer 2 soluţii:
una în care se lucrează cu formatul implicit al datei şi alta prin care se formatează data.
3
Varianta1:
SELECT first_name, last_name, hire_date
FROM employees
WHERE hire_date LIKE („%87‟);
Varianta 2:
SELECT first_name, last_name, hire_date
FROM employees
WHERE TO_CHAR(hire_date, „YYYY‟)=‟1987‟;
Sunt obligatorii ghilimelele de la şirul „1987‟? Ce observaţi?
19. Să se afişeze numele şi job-ul pentru toţi angajaţii care nu au manager.
SELECT last_name, job_id
FROM employees
WHERE manager_id IS NULL;
20. Să se afişeze numele, salariul şi comisionul pentru toţi salariaţii care câştigă comisioane. Să se sorteze
datele în ordine descrescătoare a salariilor, iar pentru cei care au acelaşi salariu în ordine crescătoare a
comisioanelor.
SELECT last_name, salary, commission_pct
FROM employees
WHERE commission_pct IS NOT NULL
ORDER BY salary DESC, commission_pct ASC;
21. Să se listeze numele tuturor angajaţilor care au a treia litera din nume 'a'.
Obs: Pentru a forma măştile de caractere utilizate împreună cu operatorul LIKE cu scopul de a compara
şirurile de caractere, se utilizează:
% - reprezentând orice şir de caractere, inclusiv şirul vid;
_ (underscore) – reprezentând un singur caracter.
SELECT DISTINCT last_name
FROM employees
WHERE last_name LIKE '__a%';
4
30. Să se listeze numele tuturor angajaţilor care au 2 litere 'L' în nume şi lucrează în departamentul 30 sau
managerul lor este 123.
31. Să se afişeze numele, job-ul şi salariul pentru toţi salariaţii al căror job conţine şirul 'CLERK' sau 'REP' şi
salariul nu este egal cu 1000, 2000 sau 3000 $.
32. Să se afişeze numele, salariul şi comisionul pentru toţi angajaţii al căror salariu este mai mare decât de 5
ori valoarea comisionului (salary*commission_pct*5).
5
LABORATOR 2 - SQL
FUNCŢII SQL (single-row)
Funcţiile SQL sunt predefinite în sistemul Oracle şi pot fi utilizate în instrucţiuni SQL. Ele nu
trebuie confundate cu funcţiile definite de utilizator, scrise în PL/SQL.
Dacă o funcţie SQL este apelată cu un argument având un alt tip de date decât cel aşteptat, sistemul
converteşte implicit argumentul înainte să evalueze funcţia.
Dacă o funcţie SQL este apelată cu un argument null, atunci aceasta returnează valoarea null.
Singurele funcţii care nu urmează această regulă sunt CONCAT, NVL şi REPLACE.
Principalele funcţii SQL pot fi clasificate în următoarele categorii:
Funcţii single-row
Funcţii multiple-row (funcţii agregat)
Funcţiile single-row returnează câte o linie rezultat pentru fiecare linie a tabelului sau vizualizării
interogate. Aceste funcţii pot apărea în listele SELECT, clauzele WHERE, START WITH, CONNECT BY
şi HAVING.
2. Să se afişeze pentru fiecare angajat din departamentul 20 un şir de caractere de forma "Funcţia
salariatului {prenume} {nume} este {cod functie}". Să se afişeze prenumele cu iniţiala litera mare, iar
numele cu litere mari (Stephen KING), iar codul funcţiei să se afişeze cu litere mici.
3. Să se afişeze pentru angajatul cu numele 'HIGGINS' codul, numele şi codul departamentului. Cum se
scrie condiţia din WHERE astfel încât să existe siguranţa ca angajatul 'HIGGINS' va fi găsit oricum ar fi
fost introdus numele acestuia? Căutarea trebuie să nu fie case-sensitive, iar eventualele blank-uri care
preced sau urmează numelui trebuie ignorate.
UPPER(TRIM(last_name))='HIGGINS';
4. Să se afişeze pentru toţi angajaţii al căror nume se termină în 'n', codul, numele, lungimea numelui şi
poziţia din nume în care apare prima data litera 'a'. Asociaţi aliasuri coloanelor returnate de cerere.
SELECT employee_id, last_name, LENGTH(last_name), INSTR(UPPER(last_name), 'A')
FROM employees
WHERE SUBSTR(last_name,-1)='n';
5. Analizaţi următoarele funcţii aritmetice:
Funcţie Semnificaţie Exemplu
ROUND(1.6) = 2
Returnează valoarea rotunjită a expresiei
ROUND(1.4) = 1
până la n zecimale. Daca n este negativ sunt
ROUND (expresie [, n]) ROUND (1234.56,1) = 1234.6
rotunjite cifre din stânga virgulei. Valoarea
ROUND (1230.56, -2) = 1200
implicită pentru n este 0.
ROUND (1260.56, -2) = 1300
6. Să se afişeze detalii despre salariaţii care au lucrat un număr întreg de săptămâni până la data curentă.
MOD(ROUND(SYSDATE – hire_date), 7)=0;
7. Să se afişeze numele, salariul şi numărul de mii al salariului rotunjit la 2 zecimale pentru cei care nu au
salariul divizibil cu 1000.
8. Analizaţi următoarele operaţii pe expresii de tip dată calendaristică:
Tipul de date al
Operaţie Descriere
rezultatului
date -/+ number Date Scade/Adaugă un număr de zile dintr-o / la o dată.
date1 - date2 Number Întoarce numărul de zile dintre două date calendaristice.
date +/-
Date Scade/Adaugă un număr de ore la o / dintr-o dată calendaristică.
number/24
9. Să se afişeze data (luna, ziua, ora, minutul si secunda) de peste 10 zile.
SYSDATE+10
10. Să se afişeze numărul de zile rămase până la sfârşitul anului.
ROUND(TO_DATE(‟31-DEC-2009‟)-SYSDATE)
11. a. Să se afişeze data de peste 12 ore.
SYSDATE+12/24
b. Să se afişeze data de peste 5 minute.
SYSDATE+1/288
12. Analizaţi următoarele funcţii pentru prelucrarea datelor calendaristice:
Funcţie Semnificaţie Exemplu
SYSDATE Întoarce data şi timpul curent
Returnează numărul de luni dintre
data date1 şi data date2. Rezultatul
MONTHS_BETWEEN poate fi pozitiv sau negativ după cum ROUND(MONTHS_BETWEEN
(date1, date2) date1 este mai recentă sau nu faţă de (SYSDATE + 31, SYSDATE)) = 1
date2. Zecimalele reprezintă parţi
dintr-o luna!
Adaugă n luni la o data specificată. MONTHS_BETWEEN
ADD_MONTHS (date, n) Valoarea n trebuie să fie întreagă (ADD_MONTHS(SYSDATE, 3),
(pozitivă sau negativă). SYSDATE) = 3
NEXT_DAY('15-dec-2006','Monday')
Returnează data corespunzătoare
= '18-dec-2006'
NEXT_DAY (date, char) primei zile a săptămânii specificate
NEXT_DAY ('15-dec-2006',1)
(char) care urmează după date.
= '18-dec-2006'
13. Să se afişeze numele angajatului, data angajării şi data negocierii salariului, care a avut loc în prima zi de
Luni, după 6 luni de serviciu. Etichetaţi această coloană “Negociere”.
NEXT_DAY(ADD_MONTHS(hire_date, 6), „Monday‟)
14. Pentru fiecare angajat să se afişeze numele şi numărul de luni de la data angajării. Etichetaţi coloana
“Luni lucrate”. Să se ordoneze rezultatul după numărul de luni lucrate. Se va rotunji numărul de luni la
cel mai apropiat număr întreg.
SELECT last_name, ROUND(MONTHS_BETWEEN(SYSDATE, hire_date)) “Luni lucrate”
FROM employees
ORDER BY MONTHS_BETWEEN(SYSDATE, hire_date);
SELECT last_name, ROUND(MONTHS_BETWEEN(SYSDATE, hire_date)) “Luni lucrate”
FROM employees
ORDER BY “Luni lucrate”;
Atunci când în clauza FROM a unei comenzi SELECT apar mai multe tabele se realizează produsul
cartezian al acestora. De aceea numărul de linii rezultat creşte considerabil, fiind necesară restricţionarea
acestora cu o clauza WHERE.
Atunci când este necesară obţinerea de informaţii din mai multe tabele se utilizează condiţii de join.
Join-ul este operaţia de regăsire a datelor din două sau mai multe tabele, pe baza valorilor comune ale unor
coloane. Condiţiile de corelare utilizează de obicei coloanele cheie primară şi cheie externă.
Pentru claritatea şi eficienţa accesului la baza de date se recomandă prefixarea numelor coloanelor cu
numele tabelelor din care fac parte (tabel.coloana). De asemenea, există posibilitatea de a utiliza aliasuri pentru
tabelele din clauza FROM şi utilizarea lor în cadrul comenzii SELECT respective (alias.coloana). Această
identificare (prin 'tabel.coloana' sau 'alias.coloana') este obligatorie atunci când se face referinţă la o coloana ce
apare în mai mult de un tabel din clauza FROM.
Tipuri de join:
equijoin (se mai numeşte inner join sau simple join) - compunerea a două tabele diferite după o
condiţie ce conţine operatorul de egalitate.
SELECT last_name, department_name, location_id, e.department_id
FROM employees e, departments d
WHERE e.department_id = d.department_id;
Obs: Numele sau alias-urile tabelelor sunt obligatorii în dreptul coloanelor care au acelaşi nume în
mai multe tabele.
nonequijoin - compunerea a două relaţii tabele după o condiţie oarecare, ce NU conţine operatorul
de egalitate.
SELECT last_name, salary, grade_level
FROM employees, job_grades
WHERE salary BETWEEN lowest_sal AND highest_sal;
outerjoin - compunerea externă a două tabele diferite completând una dintre relaţii cu valori NULL
acolo unde nu există în aceasta nici un tuplu ce îndeplineşte condiţia de corelare. Relaţia completată
cu valori NULL este cea în dreptul căreia apare “(+)”. Operatorul (+) poate fi plasat în orice parte a
condiţiei de join, dar nu în ambele părţi. Full outer join = Left outer join UNION Right outer join.
SELECT last_name, department_name,location_id
FROM employees e, departments d
WHERE e.department_id(+) = d.department_id;
selfjoin - compunerea externă a unui tabel cu el însuşi după o condiţie dată.
SELECT sef.last_name, angajat.last_name
FROM employees sef, employees angajat
WHERE sef.employee_id = angajat.manager_id
ORDER BY sef.last_name;
1. Pentru fiecare angajat să se afişeze numele, codul şi numele departamentului.
SELECT last_name, e.department_id, department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id;
2. Să se afişeze numele angajatului, numele departamentului pentru toţi angajaţii care câştigă comision.
3. Să se listeze numele job-urile care există în departamentul 30.
SELECT DISTINCT job_title
FROM employees e, jobs j
WHERE e.job_id = j.job_id
AND department_id = 30;
4. Să se afişeze numele, job-ul şi numele departamentului pentru toţi angajaţii care lucrează în Seattle.
SELECT last_name, job_id, department_name
FROM employees e, departments d, locations s
WHERE e.department_id = d.department_id
AND d.location_id = s.location_id
AND city = „Seattle‟;
5. Să se afişeze numele, salariul, data angajării şi numele departamentului pentru toţi programatorii care
lucrează în America.
region_name = „Americas‟
job_title = „Programmer‟
6. Să se afişeze numele salariaţilor şi numele departamentelor în care lucrează. Se vor afişa şi salariaţii care nu
lucrează într-un departament (right outher join).
SELECT last_name, department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id(+);
7. Să se afişeze numele departamentelor şi numele salariaţilor care lucrează în ele. Se vor afişa şi
departamentele care nu au salariaţi (left outher join).
8. Să se afişeze numele, job-ul, numele departamentului, salariul şi grila de salarizare pentru toţi angajaţii.
9. Să se afişeze codul angajatului şi numele acestuia, împreună cu numele şi codul şefului său direct. Se vor
eticheta coloanele Ang#, Angajat, Mgr#, Manager. Să se salveze instrucţiunea într-un fişier numit p3_9.sql.
SELECT a.employee_id “Ang#”, a.last_name “Angajat”, b.employee_id “Mgr#”, b.last_name “Manager”
FROM employees a, employees b
WHERE a.manager_id = b. employee_id;
10. Să se modifice p3_9.sql pentru a afişa toţi salariaţii, inclusiv pe cei care nu au şef.
11. Să se afişeze numele salariatului şi data angajării împreună cu numele şi data angajării şefului direct pentru
salariaţii care au fost angajaţi înaintea şefilor lor. Se vor eticheta coloanele Angajat, Data_ang, Manager si
Data_mgr.
12. Pentru fiecare angajat din departamentele 20 şi 30 să afişeze numele, codul departamentului şi toţi colegii
săi (salariaţii care lucrează în acelaşi departament cu el). Se vor eticheta coloanele corespunzător.
SELECT a.last_name “Angajat”, a.department_id ”Departament”, b.last_name “Coleg”
FROM employees a, employees b
WHERE a.department_id = b.department_id
AND a.employee_id <> b.employee_id
AND a.department_id IN (20,30)
ORDER BY a.last_name;
13. Să se afişeze numele şi data angajării pentru salariaţii care au fost angajaţi după Fay.
SELECT last_name, hire_date
FROM employees
WHERE hire_date > (SELECT hire_date
FROM employees
WHERE last_name = „Fay‟);
sau
SELECT a.last_name, a.hire_date
FROM employees a, employees b
WHERE UPPER(b.last_name)=‟FAY‟ AND a.hire_date>b.hire_date;
14. Scrieţi o cerere pentru a afişa numele şi salariul pentru toţi colegii (din acelaşi departament) lui Fay. Se va
exclude Fay.
SELECT last_name, salary
FROM employees
WHERE last_name <> „Fay‟
AND department_id = (SELECT department_id
FROM employees
WHERE last_name = „Fay‟);
15. Să se afişeze codul departamentului, codul şi numele angajaţilor care lucrează în acelaşi departament cu cel
puţin un angajat al cărui nume conţine litera “T”. Să se ordoneze după codul departamentului.
SELECT employee_id, last_name, department_id
FROM employees
WHERE department_id IN (SELECT DISTINCT department_id
FROM employees
WHERE UPPER(last_name) LIKE „%T%‟)
ORDER BY department_id;
16. Să se afişeze numele şi salariul angajaţilor conduşi direct de Steven King.
SELECT last_name, salary
FROM employees
WHERE manager_id = (SELECT employee_id
FROM employees
WHERE UPPER(last_name) ='KING'
AND UPPER(first_name) ='STEVEN' );
17. Să se afişeze numele şi job-ul tuturor angajaţilor din departamentul „Sales‟.
SELECT last_name, job_id
FROM employees
WHERE department_id = (SELECT department_id
FROM departments
WHERE department_name ='Sales');
18. Să se afişeze numele angajaţilor, numărul departamentului şi job-ul tuturor salariaţilor al căror departament
este localizat în Seattle.
SELECT last_name, job_id, department_id
FROM employees
WHERE department_id IN (SELECT department_id
FROM departments
WHERE location_id = (SELECT location_id
FROM locations
WHERE city = „Seattle‟));
Rezolvaţi această problemă utilizând join-uri.
19. Să se afle dacă există angajaţi care nu lucrează în departamentul „Sales‟ şi al căror salariu şi comision
coincid cu salariul şi comisionul unui angajat din departamentul „Sales‟.
SELECT last_name, salary, commission_pct, department_id
FROM employees
WHERE (salary, commission_pct) IN (SELECT salary, commission_pct
FROM employees e, departments d
WHERE e.department_id = d.department_id
AND department_name = „Sales‟)
AND department_id <> (SELECT department_id
FROM departments
WHERE department_name = „Sales‟);
20. Scrieţi o cerere pentru a afişa numele, numele departamentului şi salariul angajaţilor care nu câştigă
comision, dar al căror manager coincide cu managerul unui angajat care câştigă comision.
SELECT last_name, department_name, salary
FROM employees e, departments d
WHERE e.department_id = d.department_id
AND e.manager_id IN (SELECT DISTINCT manager_id
FROM employees
WHERE commission_pct IS NOT NULL)
AND commission_pct IS NULL;
21. Scrieţi o cerere pentru a afişa angajaţii care câştigă mai mult decât oricare funcţionar. Sortaţi rezultatele
după salariu, în ordine descrescătoare.
SELECT last_name, salary, job_id
FROM employees
WHERE salary > (SELECT MAX(salary)
FROM employees
WHERE job_id LIKE '%CLERK')
ORDER BY salary DESC;
22. Să se afişeze codul, numele şi salariul tuturor angajaţilor care câştigă mai mult decât salariul mediu.
23. Să se afişeze pentru fiecare salariat angajat în luna martie numele său, data angajării şi numele jobului.
24. Să se afişeze pentru fiecare salariat al cărui câştig total lunar este mai mare decât 12000 numele său,
câştigul total lunar şi numele departamentului în care lucrează.
25. Să se afişeze pentru fiecare angajat codul său şi numele joburilor sale anterioare, precum şi intervalul de
timp în care a lucrat pe jobul respectiv.
26. Să se modifice cererea de la punctul 25 astfel încât să se afişeze şi numele angajatului, respectiv codul
jobului său curent.
27. Să se modifice cererea de la punctul 26 astfel încât să se afişeze şi numele jobului său curent.
28. Să se afişeze salariaţii care au acelaşi manager ca şi angajatul având codul 140.
29. Să se afişeze numele departamentelor care funcţionează în America.
LABORATOR 4 - SQL
Funcţii multiple-row (grup). Gruparea datelor.
Aceste tipuri de funcţii pot fi utilizate pentru a returna informaţia corespunzătoare fiecăruia dintre
grupurile obţinute în urma divizării liniilor tabelului cu ajutorul clauzei GROUP BY.
Pot apărea în clauzele SELECT, ORDER BY şi HAVING. Server-ul Oracle aplică aceste funcţii fiecărui
grup de linii şi returnează un singur rezultat pentru fiecare mulţime.
Exemple de funcţii grup: AVG, SUM, MAX, MIN, COUNT etc.
Tipurile de date ale argumentelor funcţiilor grup pot fi CHAR, VARCHAR2, NUMBER sau DATE.
Funcţiile AVG şi SUM, operează numai asupra valorilor numerice. Funcţiile MAX şi MIN pot opera asupra
valorilor numerice, caracter sau dată calendaristică.
Toate funcţiile grup, cu excepţia lui COUNT(*), ignoră valorile null. COUNT(expresie)
returnează numărul de linii pentru care expresia dată nu are valoarea null. Funcţia COUNT returnează un
număr mai mare sau egal cu zero şi nu întoarce niciodată valoarea null.
Când este utilizată clauza GROUP BY, server-ul sortează implicit mulţimea rezultată în ordinea
crescătoare a valorilor coloanelor după care se realizează gruparea.
Absenţa clauzei GROUP BY conduce la aplicarea funcţiei grup pe mulţimea tuturor liniilor tabelului.
În clauza GROUP BY se trec obligatoriu toate coloanele prezente în clauza SELECT, care nu sunt
argument al funcţiilor grup.
1. Să se afişeze cel mai mare salariu, cel mai mic salariu, suma şi media salariilor tuturor angajatilor. Etichetaţi
coloanele Maxim, Minim, Suma, respectiv Media. Să se rotunjească rezultatele.
SELECT MIN(salary) min, MAX(salary) max, SUM(salary) suma, ROUND(AVG(salary)) media
FROM employees;
2. Utilizând funcţia grup COUNT să se determine:
a. numărul total de angajaţi;
b. numărul de angajaţi care au manager;
c. numărul de manageri.
3. Să se afişeze diferenţa dintre cel mai mare şi cel mai mic salariu. Etichetaţi coloana “Diferenta”.
4. Să se listeze numărul de angajaţi din departamentul având codul 50.
5. Caţi angajaţi din departamentul 80 câştigă comision?
6. Să se selecteze valoarea medie şi suma salariilor pentru toţi angajaţii care sunt reprezentanţi de vânzări
(SA_MAN, SA_REP).
7. Să se selecteze data angajării primei persoane care a fost angajată de companie.
8. Să se afişeze numărul de angajaţi pentru fiecare job.
SELECT job_id, COUNT(employee_id) nr_angajati
FROM employees
GROUP BY job_id;
9. Să se afişeze minimul, maximul, suma şi media salariilor pentru fiecare departament.
10. Să se afişeze codul departamentului şi media salariilor pentru fiecare job din cadrul acestuia.
SELECT department_id, job_id, AVG(salary)
FROM employees
GROUP BY department_id, job_id;
11. a. Să se afişeze codul departamentelor pentru care salariul minim depăşeşte 5000$.
SELECT department_id, MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary)>5000;
1
b. Să se modifice cererea anterioară astfel încât să se afişeze şi oraşul în care funcţionează aceste
departamente.
12. Să se obţină codul departamentelor şi numărul de angajaţi al acestora pentru departamentele care au cel
puţin 10 angajaţi.
13. Să se obţină codul departamentelor şi suma salariilor angajaţilor care lucrează în acestea, în ordine
descrescătoare după sumă. Se consideră angajaţii care au comision şi departamentele care au mai mult de 5
angajaţi.
14. Să se obţină job-ul pentru care salariul mediu este minim.
SELECT job_id
FROM employees
GROUP BY job_id
HAVING AVG(salary) = (SELECT MIN(AVG(salary))
FROM employees
GROUP BY job_id);
15. Să se afişeze cel mai mare dintre salariile medii pe departamente.
16. a. Să se afişeze codul, numele departamentului şi suma salariilor pe departamente.
SELECT d.department_id, department_name,a.suma
FROM departments d, (SELECT department_id ,SUM(salary) suma
FROM employees
GROUP BY department_id) a
WHERE d.department_id =a.department_id;
17. a. Scrieţi o cerere pentru a afişa numele departamentului, numărul de angajaţi şi salariul mediu pentru
angajaţii din acel departament. Coloanele vor fi etichetate Departament, Nr. angajati, Salariu Mediu.
SELECT department_name “Departament”,
(SELECT COUNT(employee_id)
FROM employees
WHERE department_id = d.department_id ) ” Nr. angajati”,
(SELECT AVG(salary)
FROM employees
WHERE department_id = d.department_id) ”Salariu mediu”
FROM departments d;
b. Daţi o altă metodă de rezolvare pentru problema anterioară.
18. Să se creeze o cerere prin care să se afişeze numărul total de angajaţi şi, din acest total, numărul celor care
au fost angajaţi în 1997, 1998, 1999 şi 2000. Datele vor fi afişate în forma următoare:
Total 1997 1998 1999 2000
--------------------------------------------------------------
50 10 5 25 1
SUM(DECODE(TO_CHAR(hire_date,'yyyy'),1997,1,0))
2
Operatorii ROLLUP şi CUBE
Clauza GROUP BY permite gruparea liniilor selectate după valorile expresiilor precizate în aceasta.
Pentru fiecare grup, va fi returnată o singură linie de informaţie. Clauza GROUP BY poate produce grupări
superagregat utilizând extensiile CUBE sau ROLLUP.
ROLLUP grupează liniile selectate pe baza valorilor primelor n, n - 1, …, 0 expresii din
specificaţia GROUP BY şi returnează o singură linie pentru fiecare grup. ROLLUP creează grupări prin
deplasarea într-o singură direcţie, de la dreapta la stânga, de-a lungul listei de coloane specificate în
clauza GROUP BY. Apoi, se aplică funcţia agregat acestor grupări. Dacă sunt specificate n expresii în
operatorul ROLLUP, numărul de grupări generate va fi n + 1. Liniile care se bazează pe valoarea primelor
n expresii se numesc linii obişnuite, iar celelalte se numesc linii superagregat.
GROUP BY ROLLUP (expr_1, expr_2, …, expr_n) generează n+1 tipuri de linii, corespunzătoare
următoarelor grupări:
GROUP BY (expr_1, expr_2, …, expr_n-1, expr_n)
GROUP BY (expr_1, expr_2, …, expr_n-1)
…
GROUP BY (expr_1, expr_2)
GROUP BY (expr_1)
GROUP BY () – corespunzător absenţei clauzei GROUP BY şi deci, calculului funcţiilor grup din
cerere pentru întreg tabelul.
CUBE grupează liniile selectate pe baza valorilor tuturor combinaţiilor posibile ale expresiilor
specificate şi returnează câte o linie totalizatoare pentru fiecare grup. Acest operator este folosit pentru a
produce mulţimi de rezultate care sunt utilizate în rapoarte. În vreme ce ROLLUP produce subtotalurile
doar pentru o parte dintre combinaţiile posibile, operatorul CUBE produce subtotaluri pentru toate
combinaţiile posibile de grupări specificate în clauza GROUP BY, precum şi un total general.
Dacă există n coloane sau expresii în clauza GROUP BY, vor exista 2n combinaţii posibile
superagregat.
19. Să se afişeze codurile departamentelor în care lucrează cel puţin un angajat, iar pentru fiecare dintre acestea
şi pentru fiecare manager care lucrează în departamentul respectiv să se afişeze numărul de salariaţi. De
asemenea, să se afişeze numărul de salariaţi pentru fiecare departament indiferent de manager şi numărul
total de angajaţi din companie.
4
25. Modificaţi cererea anterioară astfel încât să se afişeze numele departamentelor, titlurile job-urilor şi
valoarea medie a salariilor, pentru:
- fiecare departament şi, în cadrul său pentru fiecare job;
- fiecare departament (indiferent de job);
- fiecare job(indiferent de departament);
- întreg tabelul.
Cum intervin coloanele în obţinerea rezultatului?
Să se afişeze ‟Dept‟, dacă departamentul a intervenit în agregare şi „Job‟, dacă job-ul a intervenit în agregare.
DECODE(GROUPING(department_name), 0, „Dept‟)
26. Utilizaţi cererea de la punctul 20.
a. Eliminaţi clauza WHERE din această cerere. Analizaţi rezultatul obţinut.
b. Modificaţi cererea obţinută astfel încât să se identifice dacă o valoare null din rezultat este stocată pe
una dintre coloanele manager_id sau department_id sau este produsă de operatorul CUBE.
27. Clauza GROUPING SETS. Permite obţinerea numai a anumitor grupări superagregat. Acestea pot fi
precizate prin intermediul clauzei:
5
LABORATOR 5 SQL
I. Limbajul de control al datelor (COMMIT, SAVEPOINT, ROLLBACK)
II. Limbajul de prelucrare a datelor (LMD). INSERT, UPDATE, DELETE.
SELECT *
FROM dept_***;
SAVEPOINT a;
SAVEPOINT b;
SELECT COUNT(*)
FROM dept_***;
ROLLBACK TO b;
1
SELECT COUNT(*)
FROM dept_***;
ROLLBACK TO a;
COMMIT;
SELECT *
FROM dept_***;
1. Să se creeze tabele emp_*** şi dept_*** (dacă nu este deja creat), având aceeaşi structură şi date ca şi
tabelele employees, respectiv departments.
2. Să se selecteze toate înregistrările din cele două tabele create anterior.
3. Ştergeţi toate înregistrările din cele 2 tabele create anterior. Salvati modificarile.
DELETE FROM emp_***;
...
COMMIT;
4. Să se listeze structura tabelului employees şi să se compare cu structura tabelului emp_***. Ce observaţi?
5. Sintaxa simplificată a comenzii INSERT
- pentru inserarea unei singuri linii:
INSERT INTO nume_tabel [(col1,col2,...)]
VALUES (expresie1, expresie2, ...);
- pentru inserarea liniilor rezultat ale unei comenzi SELECT:
INSERT INTO nume_tabel [(col1,col2,...)]
{comanda_SELECT};
Observatii:
- lista de coloane (dacă este precizată) trebuie să se potrivească ca număr şi tip de date cu lista de
expresii;
- în loc de tabel (nume_tabel), insererea se mai poate face si prin intermediul unei vizualizări;
- daca se omit coloane în lista de inserare, acestea primesc valoarea NULL sau valoarea implicită.
- posibile probleme la inserare:
- lipsa de valori pentru coloane NOT NULL,
- nepotrivirea listei de coloane cu cea de expresii,
- valori duplicate ce încalcă o constrângere de unicitate,
- încălcarea vreunei constrângeri de integritate referenţială,
- încălcarea unei constrângeri de tip CHECK,
- nepotrivire de tip de date,
- valoare prea mare pentru coloana respectivă.
- dacă se foloseşte expresia DEFAULT, atunci valoarea inserată este NULL sau valoarea implicită
setată la nivel de tabel.
6. Să se exemplifice câteva din erorile care pot să apară la inserare şi să se observe mesajul returnat de sistem.
- lipsa de valori pentru coloane NOT NULL (coloana department_name este NOT NULL)
INSERT INTO dept_*** (department_id, location_id)
VALUES (200, 2000);
- nepotrivirea listei de coloane cu cea de expresii
2
INSERT INTO dept_***
VALUES (200, 2000);
INSERT INTO dept_*** (department_id, department_name,location_id)
VALUES (200, 2000);
- nepotrivire de tip de date,
INSERT INTO dept_*** (department_id, location_id)
VALUES (‘D23’, 2000);
- valoare prea mare pentru coloană
INSERT INTO dept_*** (department_id, location_id)
VALUES (15000, 2000);
7. Copiaţi în tabelul emp_*** salariaţii (din tabelul employees) al căror comision depăşeşte 25% din salariu.
8. Creaţi tabele emp1_***, emp2_*** şi emp3_*** cu aceeaşi structură ca tabelul employees. Copiaţi din
tabelul employees:
- în tabelul emp1_*** salariaţii care au salariul mai mic decât 6000;
- în tabelul emp2_*** salariaţii care au salariul cuprins între 6000 şi 10000;
- în tabelul emp3_*** salariaţii care au salariul mai mare decât 10000.
Verificaţi rezultatele, apoi ştergeţi toate înregistrările din aceste tabele.
Obs. Clauza ALL determină evaluarea tuturor condiţiilor din clauzele WHEN. Pentru cele a căror valoare
este TRUE, se inserează înregistrarea specificată în opţiunea INTO corespunzătoare.
INSERT ALL
WHEN salary < =6000 THEN
INTO emp1_***
WHEN salary > = 6000 AND salary <= 10000 THEN
INTO emp2_***
ELSE
INTO emp3_***
SELECT * FROM employees;
3
Obs. Clauza FIRST determină inserarea corespunzătoare primei clauze WHEN a cărei condiţie este evaluată
TRUE. Toate celelalte clauze WHEN sunt ignorate.
10. Ştergeţi toate înregistrările din tabelele emp_*** şi dept_***. Inseraţi în aceste tabele toate înregistrările
corespunzătoare din employees, respectiv departments. Permanentizaţi modificările.
13. Eliminaţi angajaţii care nu aparţin unui departament valid. Anulaţi modificările.
UPDATE emp_***
SET salary = salary * 1.05;
ROLLBACK;
16. Schimbaţi jobul tuturor salariaţilor din departamentul 80 care au comision în 'SA_REP'. Anulaţi
modificările.
17. Să se promoveze Douglas Grant la manager în departamentul 20, având o creştere de salariu cu 1000$.
18. Să se modifice jobul şi departamentul angajatului având codul 114, astfel încât să fie la fel cu cele ale
angajatului având codul 205.
19. Schimbaţi salariul şi comisionul celui mai prost plătit salariat din firmă, astfel încât să fie egale cu
salariul si comisionul directorului.
UPDATE emp_***
SET (salary, commission_pct) = (SELECT salary, commission_pct
FROM emp_***
4
WHERE manager_id IS NULL)
WHERE salary = (SELECT MIN(salary)
FROM emp_***);
ROLLBACK;
20. Pentru fiecare departament să se mărească salariul celor care au fost angajaţi primii astfel încât să devină
media salariilor din companie.
21. Să se modifice valoarea emailului pentru angajaţii care câştigă cel mai mult în departamentul în care
lucrează astfel încât acesta să devină iniţiala numelui concatenată cu “_” concatenat cu prenumele.
Anulaţi modificările.
5
LABORATOR 6 SQL - LDD
Limbajul de definire a datelor (CREATE, ALTER, DROP)
Crearea tabelelor
CREATE TABLE [schema.]nume_tabel (
nume_coloana tip_de_date [DEFAULT1 expr], ...);
CREATE TABLE nume_tabel [(col1, col2...)]
AS subcerere;
1. Creaţi tabelul salariat_*** având următoarea structură:
Nume Caracteristici Tip
cod_ang NOT NULL NUMBER(4)
nume VARCHAR2(25)
prenume VARCHAR2(25)
functia VARCHAR2(20)
sef NUMBER(4)
Valoare implicită data
data_angajarii DATE
curentă
varsta NUMBER(2)
email CHAR(50)
salariu Valoare implicită 0 NUMBER(9,2)
1
Modificarea tabelelor
Constrângeri
17. Ştergeţi tabelul salariat_***, iar apoi recreaţi-l implementând toate constrângerile la nivel de
tabel.
Observaţie: Constrângerea de tip NOT NULL se poate declara doar la nivel de coloană.
3
Adăugarea constrângerilor ulterior creării tabelului, eliminarea, activarea sau dezactivarea
constrângerilor (ALTER TABLE)
- adaugă constrângeri
ALTER TABLE nume_tabel
ADD [CONSTRAINT nume_constr] tip_constr (coloana);
- elimină constrângeri
ALTER TABLE nume_tabel
DROP [CONSTRAINT nume_constr] tip_constr (coloana);
- activare/dezactivare constrângere
ALTER TABLE nume_tabel
MODIFY CONSTRAINT nume_constr ENABLE|DISABLE;
sau
ALTER TABLE nume_tabel
ENABLE| DISABLE nume_constr;
19. Inseraţi o nouă înregistrare în salariat_*** de forma:
cod nume prenume data_n functia sef data_ang email salariu cod_dep
11-JUN-
2 N2 P2 economist 1 Sysdate E2 2000 10
1960
Ce observaţi? Introduceţi înregistrarea dar specificând valoarea NULL pentru coloana sef.
20. Încercaţi să adăugaţi o constrângere de cheie externă pe cod_dep din salariat_***. Ce
observaţi?
21. Inseraţi o nouă înregistrare în departament_***. Apoi adăugaţi constrângerea de cheie externă
definită anterior.
cod_dep nume loc
10 Economic Bucuresti
22. Inseraţi noi înregistrări în salariat_***, respectiv în departament_***. Care trebuie să fie
ordinea de inserare?
cod nume prenume data_n functia sef data_ang email salariu cod_dep
11-JUN-
3 N3 P3 jurist 2 Sysdate E3 2500 20
1967
5
LABORATOR 7 SQL - LDD
Vizualizări. Secvenţe. Indecşi. Sinonime.
Definirea vizualizărilor
Vizualizările sunt tabele virtuale care sunt construite pe baza unor tabele sau vizualizări,
denumite tabele de bază. Ele nu conţin date ci sunt ca nişte imagini logice asupra datelor din tabelele
de bază. Sunt definite de o cerere SQL, de aceea mai sunt denumite şi cereri stocate.
Avantajele utilizării vizualizărilor:
- restricţionarea accesului la date;
- simplificarea unor cereri complexe;
- prezentarea de diferite imagini asupra datelor.
Vizualizările se pot fi simple sau complexe. Asupra vizualizărilor simple se pot realiza operaţii
LMD. Asupra vizualizărilor complexe nu sunt posibile operaţii LMD în toate cazurile decât dacă sunt
definiţi declanşatori de tip INSTEAD OF.
Caracteristici Simple Complexe
Număr de tabele de baza Un singur tabel Unul sau mai multe tabele
Conţine funcţii Nu Da
Conţine grupări de date Nu Da
1. Să se creeze vizualizarea v_emp_*** care să conţină codul şi numele salariaţilor din tabelul emp_***.
Să se afişeze conţinutul acesteia. Să se insereze o nouă înregistrare în această vizualizare. Ce
observaţi? Să se şteargă vizualizarea v_emp_***.
2. Să se creeze vizualizarea v_emp_*** care să conţină codul, numele, emailul, data angajării, salariul şi
codul jobului salariaţilor din tabelul emp_***. Să se analizeze structura şi conţinutul vizualizării. Să
se insereze o nouă înregistrare în această vizualizare. Să se verifice că noua înregistrare a fost inserată
şi în tabelul de bază.
Observaţie: Trebuie introduse neapărat în vizualizare coloanele care au constrângerea NOT NULL în
tabelul de bază (altfel, chiar dacă tipul vizualizării permite operaţii LMD, acestea nu vor fi posibile
din cauza nerespectării constrângerilor NOT NULL).
DESC v_emp_***
4. Să se şteargă angajatul având codul 400 din vizualizarea creată anterior. Ce efect va avea această
acţiune asupra tabelului de bază?
d) Adăugaţi tabelului emp_*** constrângerea de cheie externă care referă tabelul dept_***, apoi
verificaţi ce coloane din vizualizarea v_emp_dept_*** sunt actualizabile.
7. a) Să se creeze vizualizarea v_emp30_*** care să conţină numele, emailul, data angajării, salariul,
codul jobului şi codul departamentului celor care lucrează în departamentul 30. În această
vizualizare nu se va permite modificarea sau inserarea liniilor ce nu sunt accesibile ei. Daţi un nume
constrângerii.
CREATE VIEW v_emp30_*** AS
SELECT employee_id, last_name, email, hire_date, salary, job_id,
department_id
FROM emp_***
WHERE department_id=30
WITH CHECK OPTION CONSTRAINT ck_option1_***;
DESCRIBE v_emp30_***
UPDATE v_emp30_***
SET department_id =20
WHERE employee_id = 11;
8. Să se creeze o vizualizare (v_dept_***) asupra tabelului dept_*** să nu permită efectuarea nici unei
operaţii LMD. Testaţi operaţiile de inserare, modificare şi ştergere asupra acestei vizualizări.
Obs: Coloana TEXT este de tip LONG. În cazul selectării unei coloane de tip LONG trebuie utilizată
comanda SET LONG n pentru a seta numărul de caractere afişate.
Definirea secvenţelor
O secvenţă este un obiect al bazei de date ce permite generarea de numere întregi unice cu scopul de a
fi folosiţi ca valori pentru cheia primară sau coloane numerice unice. Secvenţele sunt independente de
tabele.
Sintaxa comenzii CREATE SEQUENCE este:
CREATE SEQUENCE nume_secvenţă
[INCREMENT BY n]
[START WITH valoare_start]
[ {MAXVALUE valoare_maximă | NOMAXVALUE} ]
[ {MINVALUE valoare_minimă | NOMINVALUE} ]
[ {CYCLE | NOCYCLE} ]
[ {CACHE n | NOCACHE} ];
- INCREMENT BY specifică diferenţa dintre valorile succesive ale secvenţei (valoare implicită 1).
- START WITH specifică primul număr care va fi generat de secvenţă (valoare implicită 1).
- MAXVALUE, MINVALUE precizează valoarea maximă, respectiv minimă pe care o poate genera
secvenţa. Opţiunile NOMAXVALUE, NOMINVALUE sunt implicite. NOMAXVALUE specifică
valoarea maximă de 1027 pentru o secvenţă crescătoare şi -1 pentru o secvenţă descrescătoare.
NOMINVALUE specifică valoarea minimă 1 pentru o secvenţă crescătoare şi -1026 pentru o secvenţă
descrescătoare.
- CYCLE şi NOCYCLE specifică dacă secvenţa continuă să genereze numere după obţinerea valorii
maxime sau minime. NOCYCLE este opţiunea implicită.
- CACHE n precizează numărul de valori pe care server-ul Oracle le prealocă şi le păstrează în
memorie. În mod implicit, acest număr de valori este 20. Opţiunea CACHE pemite accesul mai rapid la
valorile secvenţei care sunt păstrate în memorie. Aceste valori sunt generate la prima referinţă asupra
secvenţei. Fiecare valoare din secvenţă se furnizează din secvenţa memorată. După utilizarea ultimei
valori prealocate secvenţei, următoarea solicitare a unei valori determină încărcarea unui alt set de
numere în memorie. Pentru a nu fi prealocate şi reţinute în memorie astfel de valori, se utilizează
opţiunea NOCACHE.
Pseudocoloanele NEXTVAL şi CURRVAL permit utilizarea secvenţelor.
- nume_secv.NEXTVAL returnează următoarea valoare a secvenţei, o valoare unică la fiecare
referire. Trebuie aplicată cel puţin o dată înainte de a folosi CURRVAL;
- nume_secv.CURRVAL returnează valoarea curentă a secvenţei.
Pseudocoloanele NEXTVAL şi CURRVAL se pot utiliza în:
- lista SELECT a comenzilor ce nu fac parte din subcereri;
- lista SELECT a unei cereri ce apare într-un INSERT;
- clauza VALUES a comenzii INSERT;
- clauza SET a comenzii UPDATE.
Pseudocoloanele NEXTVAL şi CURRVAL nu se pot utiliza:
- în lista SELECT a unei vizualizări;
- într-o comandă SELECT ce conţine DISTINCT, GROUP BY, HAVING sau ORDER BY;
- într-o subcerere în comenzile SELECT, UPDATE, DELETE;
- în clauza DEFAULT a comenzilor CREATE TABLE sau ALTER TABLE.
Ştergerea secvenţelor se realizează cu ajutorul comenzii DROP SEQUENCE.
DROP SEQUENCE nume_secv;
10. Să se creeze o secvenţă care are pasul de incrementare 10 şi începe de la 10, are ca valoare maximă
10000 şi nu ciclează.
CREATE SEQUENCE sec_***
INCREMENT BY 10
START WITH 10
MAXVALUE 10000
NOCYCLE;
11. Să se modifice toate liniile din tabelul emp_***, regenerând codul angajaţilor astfel încât să utilizeze
secvenţa sec_emp***. Să se anuleze modificările.
UPDATE emp_***
SET employee_id = sec_emp***.NEXTVAL;
ROLLBACK;
12. Să se introducă un nou salariat în tabelul emp_*** folosindu-se pentru codul salariatului secvenţa
creată.
INSERT INTO emp_*** (employee_id,last_name,email,hire_date,job_id)
VALUES(sec_emp***.NEXTVAL,'x','x',sysdate,'x');
Definirea indecşilor
Un index este un obiect al unei scheme utilizator care este utilizat de server-ul Oracle pentru a mări
performanţele unui anumit tip de cereri asupra unui tabel.
Indecşii:
- evită scanarea completă a unui tabel la efectuarea unei cereri;
- reduc operaţiile de citire/scriere de pe disc utilizând o cale mai rapidă de acces la date şi anume
pointeri la liniile tabelului care corespund unor anumite valori ale unei chei (coloane);
- sunt independenţi de tabelele pe care le indexează, în sensul că dacă sunt şterşi nu afectează
conţinutul tabelelor sau comportamentul altor indecşi;
- sunt menţinuţi şi utilizaţi automat de către server-ul Oracle;
- sunt şterşi odată cu eliminarea tabelului asociat.
Indecşii pot fi creaţi :
- automat: la definirea unei constrângeri PRIMARY KEY sau UNIQUE;
- manual: cu ajutorul comenzii CREATE INDEX.
Se creează un index atunci când:
- o coloană conţine un domeniu mare de valori;
- o coloană conţine un număr mare de valori null;
- una sau mai multe coloane sunt folosite des în clauza WHERE sau în condiţii de join în programele
de aplicaţii;
- tabelul este mare şi de obicei cererile obţin mai puţin de 2%-4% din liniile tabelului;
- tabelul nu este modificat frecvent.
Sintaxa comenzii CREATE INDEX:
CREATE [UNIQUE] INDEX nume_index
ON tabel (coloana1 [, coloana2…]);
Modificarea unui index se face prin comanda ALTER INDEX.
Eliminarea unui index se face prin comanda: DROP INDEX nume_index;
14. Să se creeze un index neunic, emp_last_name_idx_***, asupra coloanei last_name din tabelul
emp_***.
15. Să se creeze indecşi unici asupra codului angajatului (employee_id) şi asupra combinaţiei last_name,
first_name, hire_date.
16. Creaţi un index neunic asupra coloanei department_id din emp_*** pentru a eficientiza joinurile
dintre acest tabel şi dept_***.
Definirea sinonimelor
Pentru a simplifica accesul la obiecte se pot asocia sinonime acestora.
Crearea unui sinonim este utilă pentru a evita referirea unui obiect ce aparţine altui utilizator
prefixându-l cu numele utilizatorului şi pentru a scurta numele unor obiecte cu numele prea lung.
Comanda pentru crearea sinonimelor este:
CREATE [PUBLIC] SYNONYM nume_sinonim
FOR obiect;
Eliminarea sinonimelor se face prin comanda DROP SYNONYM nume_sinonim;
17. Creaţi un sinonim public se_*** pentru tabelul emp_***.
18. Creaţi un sinonim pentru vizualizarea v_dept_***.
19. Utilizând sinonimele create anterior, afişaţi informaţii depre salariţi şi despre departamente.
SELECT table_name
FROM user_tables
ORDER BY table_name;
2. Definiţiile şi numele constrângerilor:
SELECT view_name
FROM user_views;
5. Informaţii referitoare la secvenţe:
SELECT index_name
FROM user_ind_columns;
administrator
întreprindere
a
administratorul c procesor c administratorul
bazei de date schema aplicaţiilor
DESCRIERE
conceptuală
b
f d
g e
procesor dicţionarul procesor
schema datelor schema
internă externă
l i
sistem
PRELUCRARE
program
de aplicaţii
alocare extern
h h
m
programator
aplicaţie utilizatori
memorii
secundare
Multibaze de date
Diferite departamente ale unei organizaţii mai mari pot folosi diferite
sisteme de gestiune. Cu toate că fiecare sistem este dezvoltat pentru a
satisface nevoile propriului său departament, informaţiile cu care lucrează
pot fi utile şi altor departamente. De aceea, pentru ca organizaţia să
funcţioneze bine, trebuie să existe o modalitate globală da a vedea datele
din fiecare sistem. Există două caracteristici ale unor astfel de sisteme care
fac acceasarea datelor în acest mediu integrat greoaie, uneori chiar
imposibilă:
• autonomie – fiecare SGBD are o autonomie completă, ceea ce
înseamnă că fiecare manager are control deplin asupra sistemului;
• eterogenitate – sistemele pot opera pe diferite platforme, cu diferite
modele de date şi limbajele de interogare.
Una dintre soluţiile folosite pentru a depăşi dificultăţile întâmpinate în
respectarea autonomiei şi a eterogenităţii este utilizarea sistemelor multibaze
de date.
20
Un sistem multibaze de date (SMB) este alcătuit din mai multe sisteme
de baze de date privite integrat, în care se construiesc una sau mai multe
scheme globale pe baza schemelor fiecărei baze de date componente, astfel
încât să se poată realiza accesul uniform şi integrat la fiecare din bazele de
date componente. Fiecare schemă globală este construită pe baza unui model
particular de date. De exemplu, se poate construi o schemă globală ce are la
bază modelul relaţional pentru utilizatorii care sunt familiarizaţi cu acest
model, dar se poate construi o schemă globală bazată pe modelul orientat
obiect pentru utilizatorii bazelor de date orientate obiect.
Pentru o schemă globală dată, un sistem multibaze de date constă din
sistemele componente împreună cu un sistem front-end, care suportă un
singur model de date şi un singur limbaj de interogare. Principalele sarcini ale
sistemului front-end sunt gestionarea schemei globale şi procesarea cererilor
globale.
Un avantaj major al acestui model, faţă de altele, este faptul că o
singură interogare poate accesa date din mai multe baze de date într-un mod
integrat, fără să afecteze nici o aplicaţie care este scrisă utilizând una dintre
bazele de date componente.
Sursa 1 Metadate
Date operationale
Date cu nivel
mare de agregare
Utilitare
Administrator Administrator OLAP
FLUX incarcare date cereri
INTERN
FLUX
Date cu nivel EXTERN
mic de agregare FLUX
ASCENDENT
Date detaliate Utilitare
SGBD Data mining
Sursa n
Date operationale Administrator Depozit de date
Utilitare pentru
Arhive/ date FLUX accesul
backup DESCENDENT utilizatorilor finali
• simplitate;
• independenţa de platformă;
• interfaţa grafică cu utilizatorul;
• acces transparent în reţea;
• standardizare (HTML standard de facto).
Arhitectura de calcul în reţea a sistemului Oracle (NCA Network
Computing Architecture) se axează în principal pe furnizarea
extensibilităţii pentru mediile distribuite. Arhitectura este construită pe
baza tehnologiei CORBA pentru manipularea obiectelor. Este o structură
three tier care se bazează pe utilizarea de:
• cartuşe de software care permit utilizatorilor să adauge
funcţionalităţi individuale în aplicaţii (cartuşele pot fi construite
în Java, C/C++, Visual Basic, SQL şi pot fi conectate la oricare
din cele 3 straturi);
• protocoale deschise şi interfeţe standardizate care permit
comunicarea între cartuşe (distribuite într-o reţea) prin
intermediul unui program magistrală (ICX);
• clienţi extensibili, server-e de aplicaţie, server-e de baze
de date;
• dezvoltarea şi administrarea integrată a cartuşelor.
Un cartus utilizeaza un limbaj de definire a interfetelor (IDL)
pentru a putea fi identificat de alte obiecte intr-un sistem distribuit. De
exemplu, PL/SQL este un astfel de cartus.
HTTP
2.1. Preliminarii
Una dintre cele mai cunoscute abordări ale modelării semantice (cu
siguranţă una dintre cele mai utilizate) este cea bazată pe modelul entitate-
relaţie (E/R). Acesta a fost introdus de către Peter.P. Chen în 1976 şi rafinat
de atunci în diverse moduri de către acesta şi de mulţi alţi cercetători, ca un
model de date conceptual, pentru a uşura proiectarea bazelor de date. Pentru
reprezentarea grafică a modelului sunt utilizate diagramele E/R, care sunt
modele neformalizate pentru reprezentarea unui model, unui sistem din lumea
reală.
Diagramele E/R constituie o tehnică de reprezentare a structurii logice a
bazei de date, într-o manieră grafică. Aceste diagrame oferă un mijloc simplu şi
inteligibil de comunicare a caracteristicilor importante ale designului unei
anumite baze de date.
Diagrama E/R este un model de date conceptual de nivel înalt,
independent de platforma hardware utilizată şi de tipul SGBD-ului. Modelul
este constituit din concepte care descriu structura bazei de date şi tranzacţiile de
regăsire sau reactualzare asociate.
Popularitatea modelului E/R ca modalitate de abordare a proiectării
bazelor de date poate fi atribuită în principal tehnicii de realizare a diagramelor
E/R. Această tehnică, ca şi modelul E/R însuşi, a evoluat de-a lungul timpului
datorită noilor problematici care au apărut în proiectarea bazelor de date.
Studiu de caz
Exemplele din acest capitol se referă la proiectarea unui model de date ce
furnizează informaţii despre prezentări de modă, evenimente care reprezintă
momente importante în lumea caselor de modă.
Vom prezenta modelul de date, restricţiile pe care trebuie să le respecte şi
vom încerca, într-o manieră didactică, să construim diagrama E/R
corespunzătoare. Vom considera, în abordarea iniţială, anumite situaţii care nu
sunt optime, în sensul că pot genera redundanţă, anomalii la reactualizări sau nu
permit rezolvarea anumitor interogări asupra modelului. Vom încerca să arătăm
care sunt deficienţele modelului, situaţiile care le-au generat şi cum pot fi
corectate (parţial sau total) anomaliile respective.
Modelul de date va gestiona informaţii legate de organizarea şi
funcţionarea prezentărilor de modă. Există firme organizatoare care se ocupă de
buna desfăşurare a acestor prezentări. O firmă organizatoare poate fi contactată
prin angajaţi specializaţi pe diferite domenii (financiar, social, publicitate,
securitate, sisteme de iluminare, coregrafie, sisteme de sonorizare, cazare,
primiri/plecări aeroport etc.).
Firme specializate sunt angajate pentru soluţionarea problemelor legate
de securitate, publicitate, asigurări, iar restul problemelor sunt rezolvate cu
salariaţii proprii ai caselor de modă şi a firmei organizatoare. Modalităţile de
securitate, asigurări, publicitate proprii caselor de modă, modelelor sau
agenţiilor de modele nu intră în proiectarea modelului.
Prezentările pot fi sponsorizate, considerându-se doar informaţiile
referitoare la persoane (fizice sau juridice) care au contribuit efectiv la
finanţarea prezentărilor de modă. Mai exact, nu sunt incluşi sponsorii posibili.
La aceste evenimente participă case de modă, care prezintă vestimentaţii
concepute de creatorii casei respective. Creatorii pot fi cei care concep
vestimentaţia (designeri) sau cei care o realizează efectiv, incluzând croitori,
lucrători care se ocupă cu broderia sau cu realizarea diverselor accesorii.
În cadrul prezentării de modă, vestimentaţiile sunt purtate de manechine
care aparţin anumitor agenţii de modele. Casele de modă angajează modele care
să le prezinte vestimentaţiile cu prilejul acestor evenimente. Modelul de date
prezintă şi un istoric al activităţii manechinelor (în cadrul diverselor agenţii).
Casele de modă angajează pentru o prezentare stilişti care se ocupă cu
machiajul şi coafura modelelor.
De asemenea, modelul analizează informaţii legate de localizarea şi
accesarea firmelor de publicitate, a persoanelor de contact din firmele
organizatoare, a caselor de modă, a agenţiilor şi a modelelor, a sponsorilor, a
societăţilor de asigurare şi a firmelor care asigură securitatea evenimentelor.
Modelul de date respectă anumite restricţii de funcţionare.
• Casele de modă pot fi organizatori de prezentări.
• Chiar dacă o casă de modă este organizator, ea apelează la serviciile
unei firme specializate în organizarea unor astfel de evenimente.
60 PROIECTAREA BAZELOR DE DATE
• Un model sau un stilist este angajat (temporar) pentru o prezentare, de
o singură casă de modă.
• O casă de modă poate angaja mai multe modele şi mai mulţi stilişti
pentru o prezentare.
• Orice prezentare de modă are un organizator unic, care poate apela la
serviciile altor instituţii specializate (securitate, asigurări, publicitate).
• Pentru organizator s-a considerat un singur cont în/din care se pot face
plăţile.
• O casă de modă poate avea mai mulţi designeri, dar un designer poate
lucra pentru o singură casă de modă.
• Pentru contactarea unei persoane fizice sau juridice s-a considerat câte
un singur număr de telefon fix, telefon mobil, fax şi o singură adresă de
mail.
• Pentru localizarea unei persoane fizice sau juridice s-a considerat o
singură adresă de bază.
• Sunt luaţi în considerare doar angajaţii firmei de pază şi protecţie care
participă efectiv la asigurarea securităţii prezentărilor de modă.
• Creatorii de accesorii pot fi angajaţi permanenţi ai unei case de modă.
Dacă pentru anumite vestimentaţii sunt necesare accesorii create de
specialişti care nu aparţin casei de modă, aceştia vor fi consideraţi
angajaţi special pentru evenimentul respectiv.
• S-a considerat că proprietarul unei case de modă fie este unic, fie, dacă
sunt mai mulţi, va fi considerat drept proprietar cel care deţine numărul
maxim de acţiuni.
Entitate
Entitatea este un obiect sau un concept, care este semnificativ pentru
modelul real analizat. O entitate poate fi dependentă (slabă), existenţa sa
depinzând de altă entitate sau independentă (tare), caz în care ea nu depinde de
existenţa altei entităţi.
Entitatea poate fi persoană, loc, concept, activitate etc. Prin urmare, ea
poate fi un obiect cu existenţă fizică, reală sau poate fi un obiect cu existenţă
conceptuală, abstractă.
Pentru o analiză didactică a problematicii abordate, construirea
diagramelor E/R, se vor considera şi aspecte ale modelului real analizat, care nu
apar în diagrama finală.
Pentru modelul de date referitor la prezentările de modă, structurile
PUBLICITATE, ORGANIZATOR, PERS_CONTACT, PREZENTARE,
SPONSOR, FIRMA_PUB, CASA_MODA, CREATOR, VESTIMENTATIE,
MODEL, ACCESORIU, LOCALIZARE, AGENTIE, ISTORIC, FIRMA_SEC,
ANGAJAT_SEC,SOCIETATE_ASIG, ANGAJAT_TEMP, INFO_CONTACT,
LOCATIE reprezintă entităţi.
Observaţii
• Entităţile devin tabele în modelele relaţionale.
• În general, entităţile se scriu cu litere mari.
Modelarea entitate-relaţie 61
Relaţie
Relaţia (asocierea) este o comunicare între două sau mai multe entităţi. O
valoare a unei relaţii este o comunicare între valorile entităţilor pe care le leagă.
Relaţia exprimă un raport care există între aceste entităţi. Gradul unei
relaţii este dat de numărul de entităţi participante într-o relaţie (de exemplu,
relaţie binară, ternară, cvadruplă, n-ară).
Existenţa unei relaţii este subordonată existenţei entităţilor pe care le
leagă. Între două entităţi pot exista mai multe relaţii.
O relaţie în care aceeaşi entitate participă mai mult decât o dată în diferite
roluri defineşte o relaţie recursivă. Uneori, aceste relaţii sunt numite unare.
Observaţii
• În modelul relaţional, relaţiile devin tabele speciale sau coloane
speciale care referă chei primare.
• Relaţiile sunt verbe, dar nu orice verb este o relaţie.
• Pentru fiecare relaţie este important să se dea o descriere detaliată.
• În aceeaşi diagramă pot exista relaţii diferite cu acelaşi nume. În acest
caz, ele sunt diferenţiate de către entităţile care sunt asociate prin
relaţia respectivă.
• Pentru fiecare relaţie trebuie stabilită cardinalitatea (maximă şi
minimă) relaţiei, adică numărul de tupluri ce aparţin relaţiei.
Asupra entităţilor participante într-o relaţie pot fi impuse constrângeri
care trebuie să reflecte restricţiile care există în lumea reală asupra relaţiilor. O
clasă de constrângeri, numite constrângeri de cardinalitate, este definită de
numărul de înregistrări posibile pentru fiecare entitate participantă (raport de
cardinalitate). Cel mai întâlnit tip de relaţii este cel binar, iar în acest caz
rapoartele de cardinalitate sunt, în general, one-to-one (1:1), one-to-many (1:n)
sau many-to-many (m:n).
De exemplu, în modelul analizat este definită relaţia organizeaza care
leagă entităţile ORGANIZATOR şi PREZENTARE, relaţie care poate fi scrisă
sub forma ORGANIZATOR_organizeaza_PREZENTARE, pentru a percepe mai
uşor asocierile existente. Relaţia are cardinalitatea minimă 1:1 şi cardinalitatea
maximă 1:n.
Vom prezenta relaţiile modelului de date, dând o descriere completă a
fiecăreia. De fapt, denumirile acestor legături sunt sugestive, reflectând
64 PROIECTAREA BAZELOR DE DATE
conţinutul acestora şi entităţile pe care le leagă. Pentru fiecare relaţie se va
preciza cardinalitatea minimă şi maximă.
FIRMA_PUB_face_PUBLICITATE = relaţie care leagă entităţile FIRMA_PUB
şi PUBLICITATE, reflectând legătura dintre acestea (ce publicitate face o
anumită firmă de publicitate). Ea are cardinalitatea minimă 1:1 (o firmă de
publicitate trebuie să realizeze cel puţin o publicitate şi o publicitate trebuie
făcută de cel puţin o firmă de publicitate) şi cardinalitatea maximă 1:n (o firmă
de publicitate poate asigura mai multe publicităţi, iar o publicitate poate fi
făcută de o singură firmă specializată).
PUBLICITATE_se_face_PREZENTARE = relaţie care leagă entităţile
PUBLICITATE şi PREZENTARE, reflectând legătura dintre acestea (pentru o
prezentare, ce publicitate se face). Relaţia are cardinalitatea minimă 1:1 şi
cardinalitatea maximă 1:n.
ORGANIZATOR_are_PERS_CONTACT = relaţie dintre ORGANIZATOR şi
PERS_CONTACT, reflectând legătura dintre acestea (ce persoane din firma
organizatoare pot fi contactate pentru soluţionarea diverselor probleme). Ea are
cardinalitatea minimă 1:1 şi cardinalitatea maximă 1:n.
FIRMA_SEC_are_ANGAJAT_SEC = relaţie dintre entităţile FIRMA_SEC şi
ANGAJAT_SEC, reflectând legătura dintre acestea (ce angajaţi, implicaţi în
acţiunea de pază a prezentărilor de modă, au firmele de securitate). Ea are
cardinalitatea minimă 1:1 şi cardinalitatea maximă 1:n.
ANGAJAT_SEC_paza_PREZENTARE = relaţie de tip many-to-many dintre
entitatea PREZENTARE şi ANGAJAT_SEC, reflectând legătura dintre acestea
(ce angajaţi ai firmei de securitate asigură buna desfăşurare a prezentărilor de
modă). Ea are cardinalitatea minimă 1:1 şi cardinalitatea maximă m:n.
SOC_ASIG_asigura_PREZENTARE = relaţie dintre entitatea PREZENTARE şi
SOC_ASIG, reflectând legătura dintre acestea (ce societate este angajată pentru
asigurarea diverselor aspecte din cadrul prezentării de modă). Ea are
cardinalitatea minimă 1:1 şi cardinalitatea maximă 1:n.
CASA_MODA_participa_PREZENTARE = relaţie de tip many-to-many dintre
entităţile CASA_MODA şi PREZENTARE (ce case de modă participă la
prezentări). Ea arată şi dacă respectivele case participă, sau nu, ca organizator la
prezentari. Relaţia are cardinalitatea minimă 1:1 şi cardinalitatea maximă m:n.
CASA_MODA_lucreaza_CREATOR = relaţie dintre entităţile CASA_MODA şi
CREATOR (la ce case de modă lucrează creatorii). Relaţia are cardinalitatea
minimă 1:1 şi cardinalitatea maximă 1:n.
CREATOR_creeaza_VESTIMENTATIE = relaţie dintre entităţile CREATOR şi
VESTIMENTATIE (ce creatori realizează vestimentaţiile). Relaţia are
cardinalitatea minimă 1:0 şi cardinalitatea maximă1:n.
Modelarea entitate-relaţie 65
INFO_CONTACT
1
FIRMA_PUB are
1 1
are M(1) PERS_CONTACT
face ORGANIZATOR 1
1 M(1)
M(1) are
M(1)
PUBLICITATE
1
organizeaza LOCALIZARE
1 asigura participa
SOC ASIG
M(1)
CASA_MODA primeste
prezinta 1
lucreaza
ANGAJAT_TEMP
M(1)
1 CREATOR MODEL 1(0) ISA 1
1 1 1 M(1)
creeaza prezinta
lucreaza_la
M(1) M(0) 1
face VESTIMENTATIE M(1) are AGENTIE
1 1
are refera
M(0) M(0)
M(0) ACCESORIU ISTORIC M(1)
Entitate-relaţie UML
Tip entitate Clasă
Asociere (relaţie) Asociere (relaţie)
Entitate Obiect
Cardinalitate Multiplicitate
Model conceptual de Diagramă de clase
date
DEPARTAMENT
SARCINA
lucreaza_in conduce
apartine_la
atasat_la
SALARIAT PROIECT
Observaţii:
• Entităţile devin tabele în modelele relaţionale.
• În general, entităţile se scriu cu litere mari.
• Entităţile sunt substantive, dar nu orice substantiv este o entitate.
• Pentru fiecare entitate este obligatoriu să se dea o descriere
detaliată.
• Nu pot exista, în aceeaşi diagramă, două entităţi cu acelaşi nume,
sau o aceeaşi entitate cu nume diferite.
Cheia primară este un identificator unic în cadrul entităţii, făcând
distincţie între valori diferite ale acesteia.
2
Cheia primară:
• trebuie să fie unică şi cunoscută la orice moment;
• trebuie să fie controlată de administratorul bazei;
• trebuie să nu conţină informaţii descriptive, să fie simplă, fără
ambiguităţi;
• să fie stabilă;
• să fie familiară utilizatorului.
SALARIAT PROIECT
cod_salariat nr_proiect
nume M(0) atasat_la M(0) descriere
prenume data_initiala buget_alocat
sex
functia
salariu 1
1 M(0)
apartine_la
conduce lucreaza_in
1(0) 1 M
DEPARTAMENT SARCINA
cod_departament nr_proiect
nume nr_sarcina
nr_cladire data_inceperii
stare
Diagrama E/R.
4
SALARIAT
cod_salariat PROIECT
nume job_cod nr_proiect
atasat_la descriere
ISA M(0) M(0) buget_alocat
AGENT_TERITORIAL
zona data_initiala
1 1(0) comision functia 1
PROGRAMATOR apartine_la
ISA
limbaj
nivel 1(0)
1 1(0)
M(1)
SARCINA
1 M(0) 1(0) nr_proiect
nr_sarcina
data_inceperii
conduce lucreaza_in stare
casatorit
1(0) 1
DEPARTAMENT
cod_departament
nume
nr_cladire
Diagrama E/R.
6
CITITOR
CARTE M(1) M(0)
codec#
codel# imprumuta nume
titlu dep
autor
pret
nrex
1 DOMENIU
M(0)
coded#
apartine intdom
7
FRAME
SALARIAT nr_publicatie#
cod_salariat# nr_capitol#
nume job tip nr_frame#
M(1) M(0)
CAPITOL
TEHNOREDACTOR 1 M(0) nr_publicatie#
ISA nr_capitol#
tip_editor
1 1(0)
1 realizează
M(1)
cuprinde
1
ISA
1 1(0) REDACTOR_SEF 1 M(0) PUBLICATIE
experienta coordoneaza nr_publicatie#
stil
limba
SANTIER
CONTRACTANT nr_santier#
cod_contractant# specialitate
adresa sef
telefon
cont 1
executa
banca
tip_contractant M(0)
executa
SUBANTREPENOR LUCRARE
nume 1 M( cod_obiectiv#
nume_adm 1) cod_lucrare#
functie_adm adresa
1 ISA 1(0) M(1)
INVESTITOR necesita
tip_investitor
1
investeste_in
PERS_FIZICA OBIECTIV_
nume INVESTITIE
1 M(1) cod_obiectiv#
prenume
ISA
bi denumire
1 ISA 1(0) adresa
1
atasat_la
PERS_JURIDICA 1
tip_juridic
incheie CONTRACT
ISA nume
nr_contract#
functie
1 M(1) tip_contract
data_avans
petrecut_in EVENIMENT
PUNCT
gasita_in
stantata_cu
ARTICOL publicata MONEDA STANTA
inclusa_in
pastrata_la
TEZAUR MUZEU
Completaţi cardinalitatea!
SCOALA CLIENT
cod_scoala# cod_client#
INSTRUCTOR EXAMEN
cod_instructor# cod_examen#
EXAMINATOR
MASINA cod_examinator#
cod_masina#
ECHIPA
Cod_echipa# M(1) sustine M(1) SPONSOR
Nume Cod_sponsor#
Oras Nume
joaca
M(1)
MECI
Tara#
Nr_etapa#
Cod_meci#
M(1)
apartine_de
ETAPA
Tara
Nr_etapa
M(1)
atasata_la
CAMPIONAT
Tara#
11
Modelul relaţional
Modelul relaţional a fost conceput şi dezvoltat de E.F. Codd. El este
un model formal de organizare conceptuală a datelor, destinat reprezentării
legăturilor dintre date, bazat pe teoria matematică a relaţiilor. Modelul
relaţional este alcătuit numai din relaţii şi prin urmare, orice interogare
asupra bazei de date este tot o relaţie.
Calităţi:
• este simplu;
• riguros din punct de vedere matematic;
• nu este orientat spre sistemul de calcul.
Modalităţi pentru definirea unui SGBD relaţional:
• prezentarea datelor în tabele supuse anumitor operaţii de tip
proiecţie, selecţie, reuniune, compunere, intersecţie etc.
• un sistem de baze de date ce suportă un limbaj de tip SQL –
Structured Query Language;
• un sistem de baze de date care respectă principiile modelului
relaţional introdus de E.F. Codd.
Caracteristicile unui model relaţional:
• structura relaţională a datelor;
• operatorii modelului relaţional;
• regulile de integritate care guvernează folosirea cheilor în model.
Aceste trei elemente corespund celor trei componente ale ingineriei
software: informaţie, proces, integritate.
Structura datelor
Definirea noţiunilor de domeniu, relaţie, schemă relaţională, valoare
null şi tabel vizualizare (view).
Conceptele utilizate pentru a descrie formal, uzual sau fizic
elementele de bază ale organizării datelor sunt date în următorul tabel:
Formal Uzual Fizic
relaţie tablou fişier
tuplu linie înregistrare
atribut coloană câmp
domeniu tip de dată tip de dată
12
Fie schemele relaţionale R1(P1, S1) şi R2(S1, S2), unde P1 este cheie
primară pentru R1, S1 este cheie secundară pentru R1, iar S1 este cheie
primară pentru R2. În acest caz, vom spune că S1 este cheie externă (cheie
străină) pentru R1.
Modelul relaţional respectă trei reguli de integritate structurală.
Regula 1 – unicitatea cheii. Cheia primară trebuie să fie unică şi
minimală.
Regula 2 – integritatea entităţii. Atributele cheii primare trebuie
să fie diferite de valoarea null.
Regula 3 – integritatea referirii. O cheie externă trebuie să fie ori
null în întregime, ori să corespundă unei valori a cheii primare
asociate.
Proiectarea modelului relaţional (exemple curs!)
Transformarea entităţilor
Entităţile independente devin tabele independente. Cheia
primară nu conţine chei externe.
Entităţile dependente devin tabele dependente. Cheia primară a
entităţilor dependente conţine cheia primară a entităţii de care
depinde (cheie externă) plus unul sau mai multe atribute
adiţionale.
Subentităţile devin subtabele. Cheia externă se referă la
supertabel, iar cheia primară este această cheie externă (cheia
primară a subentităţii PROGRAMATOR este cod_salariat care
este o cheie externă).
Transformarea relaţiilor
Relaţiile 1:1 şi 1:n devin chei externe. Relaţia conduce devine
coloană în tabelul DEPARTAMENT, iar relaţia lucreaza_in
devine coloană în tabelul SALARIAT. Simbolul „ד indică
plasamentul cheii externe, iar simbolul „ד exprimă faptul că
această cheie externă este conţinută în cheia primară. Relaţia 1:1
plasează cheia externă în tabelul cu mai puţine linii.
Relaţia m:n devine un tabel special, numit tabel asociativ, care
are două chei externe pentru cele două tabele asociate. Cheia
primară este compunerea acestor două chei externe plus
eventuale coloane adiţionale. Tabelul se desenează punctat.
15
Transformarea atributelor
Un atribut singular devine o coloană.
Atributele multiple devin tabele dependendente ce conţin cheia
primară a entităţii şi atributul multiplu. Cheia primară este o
cheie externă, plus una sau mai multe coloane adiţionale.
Entităţile devin tabele, iar atributele lor devin coloane în aceste
tabele. Ce devin atributele relaţiilor? Pentru relaţii 1:1 şi 1:n,
atributele relaţiilor vor aparţine tabelului care conţine cheia
externă, iar pentru relaţii m:n şi de tipul trei, atributele vor fi
plasate în tabelele asociative.
SALARIAT
cod_salariat#
PROIECT
nr_proiect#
DEPARTAMENT
cod_departament#
SARCINA
nr_proiect#
nr_sarcina#
atasat_la
SALARIAT cod_salariat# PROIECT
cod_salariat# nr_proiect# nr_proiect#
TELEFON
cod_salariat#
SALARIAT nr_telefon#
cod_salariat#
SALARIAT
cod_salariat# PROIECT
salariu job_cod nr_proiect#
nume ATASAT_LA descriere
sex AGENT_TERITORIAL cod_salariat# buget_alocat
zona nr_proiect#
comision functie
PROGRAMATOR
limbaj
nivel
apartine_la
CONTRACTANT
cod_contractant#
adresa
telefon
cont
banca tip_contractant
LUCRARE ŞANTIER
SUBANTREPENOR cod_lucrare# nr_şantier#
executa
nume executa cod_obiectiv# specialitate şef
nume_adm
funcţie_adm
necesita
INVESTITOR
tip_investitor OBIECTIV_INVESTITIE
cod_obiectiv#
denumire
PERS_FIZICA
adresa
investeste_in
nume
prenume
bi
atasat_la
CONTRACT
PERS_JURIDICA nr_contract#
tip_contract
tip_juridic data_avans
nume incheie
functie
19
REALIZEAZA FRAME
SALARIAT cod_salariat# nr_publicatie#
cod_salariat# nr_publicatie# nr_capitol#
nume job nr_capitol# nr_frame#
nr_frame# tip
GRAFICIAN
tip include
TEHNOREDACTOR CAPITOL
tip_editor scrie nr_publicatie#
nr_capitol#
REDACTOR_SEF dimensiune
experienta
coordoneaza cuprinde
PUBLICATIE
TELEFON LIMBA nr_publicatie#
cod_salariat# cod_salariat# stil
nr_telefon# limba_cun#
Algebra relaţională
Limbajul de definire a datelor (LDD) precizează entităţile, relaţiile
dintre ele, atributele, structura atributelor, cheile, constrângerile, prin
urmare defineşte structura obiectelor bazei de date (schema bazei).
Limbajul de prelucrare a datelor (LMD) dintr-o bază de date
relaţionale cuprinde aspecte referitoare la introducerea, eliminarea,
modificarea şi căutarea datelor.
• Introducerea datelor – permite adăugarea de tupluri la o relaţie.
Tuplurile pot fi introduse de utilizator sau pot fi obţinute din alte
relaţii existente în baza de date.
• Eliminarea datelor – permite ştergerea tuplurilor ce satisfac
condiţii date.
• Modificarea datelor – permite reactualizarea tuplurilor ce
satisfac condiţii date cu noi valori ale atributelor sau cu rezultate
ale unor operaţii aritmetice efectuate asupra unor valori existente.
• Căutarea datelor – permite găsirea tuplurilor sau a unor părţi ale
tuplurilor ce satisfac condiţii date.
Modelul relaţional oferă două mulţimi de operatori pe relaţii:
• algebra relaţională (filtrele se obţin aplicând operatori specializaţi
asupra uneia sau mai multor relaţii din cadrul bazei relaţionale);
• calculul relaţional (filtrele se obţin cu ajutorul unor formule
logice pe care tuplurile rezultatului trebuie să le satisfacă).
rezultatele sunt relaţii ieşirea unei operaţii poate deveni intrare pentru
alta) posibilitatea imbricării expresiilor în algebra relaţională).
Operatorii algebrei relaţionale sunt:
• operatori tradiţionali pe mulţimi (UNION, INTERSECT,
PRODUCT, DIFFERENCE);
• operatori relaţionali speciali (PROJECT, SELECT, JOIN,
DIVISION).
Calculul relaţional reprezintă o adaptare a calculului predicatelor la
domeniul bazelor de date relaţionale. Ideea de bază este de a identifica o
relaţie cu un predicat. Pe baza unor predicate iniţiale, prin aplicarea unor
operatori ai calculului cu predicate (conjuncţia, disjuncţia, negaţia,
cuantificatorul existenţial şi cel universal) se pot defini noi relaţii.
Calculul relaţional p o ate să fie orientat pe tuplu ri sau o rientat p e
domenii.
Echivalenţa dintre algebra relaţională şi calculul relaţional a fost
demonstrată de J.D.Ullman. Această echivalenţă arată că orice relaţie
posibil de definit în algebra relaţională poate fi definită şi în cadrul calcului
relaţional, şi reciproc.
Operatorii (unari sau binari) algebrei relaţionale realizează
următoarele funcţii:
• SELECT (selecţie) – extrage tupluri ce satisfac o condiţie specificată;
• PROJECT (proiecţie) – extrage atributele specificate;
• DIFFERENCE (diferenţă) – extrage tupluri care apar într-o relaţie, dar
nu apar în cealaltă;
• PRODUCT (produs cartezian) – generează toate perechile posibile de
tupluri, primul element al perechii fiind luat din prima relaţie, iar cel de-
al doilea element din cealaltă relaţie;
• UNION (reuniune) – reuneşte două relaţii;
• INTERSECT (intersecţie) – extrage tupluri care apar în ambele relaţii;
• DIVISION (diviziune) – extrage valorile atributelor dintr-o relaţie, care
apar în toate valorile atributelor din cealaltă relaţie;
• JOIN (compunere) – extrage tupluri din mai multe relaţii corelate:
• NATURAL JOIN (compunere naturală) – combină tupluri din două
relaţii, cu condiţia ca atributele comune să aibă valori identice;
• SEMI-JOIN (semi-compunere) – selectează tupluri ce aparţin unei
singure relaţii, care sunt corelate cu tupluri din cea de a doua relaţie;
22
Operatorul PROJECT
Proiecţia este o operaţie unară care elimină anumite atribute ale unei
relaţii producând o submulţime „pe verticală“ a acesteia. Suprimarea unor
atribute poate avea ca efect apariţia unor tupluri duplicate, care trebuie
eliminate.
Prin proiecţie se construieşte dintr-o relaţie R, o nouă relaţie:
a) ştergând din R atributele care nu sunt menţionate în parametrii
proiecţiei;
b) eliminând dublurile care apar după ştergere.
Pentru a reprezenta operatorul proiecţie sunt utilizate diferite notaţii:
Π A1, ..., Am (R) PROJECT (R, A1 , ..., Am)
R[A1 , ..., Am ]
unde A1 , A 2 , ..., Am sunt parametrii proiecţiei relativ la relaţia R.
Exemplu. Să se obţină o listă ce conţine numele, prenumele şi sexul
angajaţilor.
1. Proiecţie în algebra relaţională:
Rezultat = PROJECT(SALARIAT, nume, prenume, sex)
2. Proiecţie cu dubluri în SQL:
SELECT nume, prenume, sex
FROM salariat;
3. Proiecţie fără dubluri în SQL:
SELECT DISTINCT nume, prenume, sex
FROM salariat;
23
Operatorul SELECT
Selecţia (restrictia) este o operaţie unară care produce o submulţime
pe „orizontală“ a unei relaţii R. Această submulţime se obţine prin
extragerea tuplurilor din R care satisfac o condiţie specificată.
Sunt utilizate diferite notaţii:
σ condiţie (R) R[condiţie]
SELECT(R, condiţie) RESTRICT(R, condiţie).
Exemplu. Să se obţină informaţii complete despre angajaţii de sex
masculin.
1. Selecţie în algebra relaţională:
Rezultat = SELECT(SALARIAT, sex = ‘m’)
2. Selecţie în SQL:
SELECT *
FROM salariat
WHERE sex = ’m’;
Operatorul UNION
Reuniunea a două relaţii R şi S este mulţimea tuplurilor aparţinând
fie lui R, fie lui S, fie ambelor relaţii.
Sunt utilizate notaţiile:
R∪S
UNION(R, S)
OR(R, S)
APPEND(R, S).
Exemplu. Să se obţină lista cu numele persoanelor fizice şi a
subantreprenorilor.
SELECT nume
FROM subantreprenor
UNION
SELECT nume
FROM pers_fizica;
24
Operatorul DIFFERENCE
Diferenţa a două relaţii R şi S este mulţimea tuplurilor care aparţin
lui R, dar nu aparţin lui S. Diferenţa este o operaţie binară necomutativă
care permite obţinerea tuplurilor ce apar numai într-o relaţie.
Sunt utilizate diferite notaţii:
R–S
DIFFERENCE(R, S)
REMOVE(R, S)
MINUS(R, S).
Exemplu. Să se obţină lista cu numărul contractului, tipul
contractului, valoarea investiţiei şi durata lucrării pentru contractele de
subantrepriză pentru care valoarea investiţiei nu depăşeşte 60000$.
1. Diferenţă în algebra relaţională:
R=PROJECT(SELECT(CONTRACT, tip_contract=T),
nr_contract, tip_contract, val_investitie, durata_lucrare);
S=PROJECT(SELECT(CONTRACT, val_investitie > 60000),
nr_contract, tip_contract, val_investitie, durata_lucrare);
Rezultat = DIFFERENCE(R, S)
2. Diferenţa în SQL:
SELECT nr_contract,tip_contract,
val_investitie,durata_lucrare
FROM contract
WHERE tip_contract
MINUS
SELECT nr_contract,tip_contract,
val_investitie,durata_lucrare
FROM contract
WHERE val_investitie>60000;
Evident diferenţa se poate referi la tabele diferite! Implementaţi
cererea prin care se listează toate oraşele în care se află o filială, dar nici o
proprietate.
Operatorul INTERSECT
Intersecţia a două relaţii R şi S este mulţimea tuplurilor care aparţin
şi lui R şi lui S. Operatorul INTERSECT este un operator binar, comutativ,
derivat:
25
R ∩ S = R – (R – S)
R ∩ S = S – (S – R).
Sunt utilizate diferite notaţii:
INTERSECT(R, S)
R∩S
AND(R, S).
În anumite dialecte SQL există operator special (INTERSECT), care
realizează această operaţie. Operatorii INTERSECT şi DIFFERENCE pot
fi simulaţi în SQL (în cadrul comenzii SELECT) cu ajutorul opţiunilor
EXISTS, NOT EXISTS, IN, != ANY.
Exemplu. Utilizând tabelele agent_teritorial şi programator să se
obţină lista codurilor salariaţilor care sunt programatori, dar care lucrează şi
ca agenţi teritoriali.
1. Intersecţie în algebra relaţională:
R = PROJECT(AGENT_TERITORIAL, cod_salariat);
S = PROJECT(PROGRAMATOR, cod_salariat),
Rezultat = INTERSECT(R, S).
2. Intersecţie în SQL:
SELECT cod_salariat
FROM agent_teritorial
INTERSECT
SELECT cod_salariat
FROM programator;
3. Simularea intersecţiei în SQL:
SELECT cod_salariat
FROM programator p
WHERE EXISTS
(SELECT cod_salariat
FROM agent_teritorial a
WHERE p.cod_salariat=a.cod_salariat);
Operatorul PRODUCT
Fie R şi S relaţii de aritate m, respectiv n. Produsul cartezian al lui R
cu S este mulţimea tuplurilor de aritate m + n unde primele m componente
formează un tuplu în R, iar ultimele n componente formează un tuplu în S.
Sunt utilizate diferite notaţii:
26
R×S
PRODUCT(R, S)
TIMES(R, S).
Exemplu. Să se obţină lista tuturor posibilităţilor de investiţie în
diverse obiective de către o firmă care este persoană juridică.
1. Produs cartezian în algebra relaţională:
R = PROJECT(PERS_JURIDICA, nume, cod_contractant);
S = PROJECT(OBIECTIV_INVESTITIE, denumire);
Rezultat = PRODUCT(R, S).
2. Produs cartezian în SQL:
SELECT cod_contractant, nume, denumire
FROM obiectiv_investitie, pers_juridica;
Operatorul DIVISION
Diviziunea este o operaţie binară care defineşte o relaţie ce conţine
valorile atributelor dintr-o relaţie care apar în toate valorile atributelor din
cealaltă relaţie.
Sunt utilizate diferite notaţii:
DIVIDE(R, S)
DIVISION(R, S)
R ÷ S.
Diviziunea conţine acele tupluri de dimensiune n – m la care, adăugând
orice tuplu din S, se obţine un tuplu din R.
Operatorul diviziune poate fi exprimat formal astfel:
R(n) ÷ S(m) = {t(n-m) ∀ s ∈ S, (t, s) ∈ R} unde n > m şi S ≠ ∅.
Operatorul DIVISION este legat de cuantificatorul universal (∀) care
nu există în SQL. Cuantificatorul universal poate fi însă simulat cu ajutorul
cuantificatorului existenţial (∃) utilizând relaţia:
∀x P(x) ≡ ¬ ∃ x ¬ P(x).
Prin urmare, operatorul DIVISION poate fi exprimat în SQL prin
succesiunea a doi operatori NOT EXISTS.
Exemplu. Să se obţină codurile salariaţilor ataşaţi tuturor proiectelor
pentru care s-a alocat un buget egal cu 1000.
1. Diviziune în algebra relaţională:
27
Operatorul JOIN
Operatorul de compunere (uniune) permite regăsirea informaţiei din
mai multe relaţii corelate. Operatorul combină produsul cartezian, selecţia
şi proiecţia.
Operatorul θ-JOIN
Operatorul θ-JOIN combină tupluri din două relaţii (nu neapărat
corelate) cu condiţia ca valorile atributelor specificate să satisfacă o
anumită condiţie specificată explicit în cadrul operaţiei.
Operatorul θ-JOIN este un operator derivat, fiind o combinaţie de
produs scalar şi selecţie:
JOIN(R, S, condiţie) = σ condiţie (R × S)
Exemplu. Să se afişeze pentru fiecare salariat, codul acestuia şi grila
sa de salarizare.
SELECT empno, level
FROM salgrade, emp
WHERE sal BETWEEN losal AND hisal;
Exemplu. Să se obţină informaţii despre contractanţi (codul şi banca)
şi obiectivele de investiţie asociate acestora (denumire, număr certificat de
urbanizare) cu condiţia ca obiectivele să nu fie la aceeaşi adresă ca şi
contractanţii.
29
Operatorul SEMI-JOIN
Operatorul SEMI-JOIN conservă atributele unei singure relaţii
participante la compunere şi este utilizat când nu sunt necesare toate
atributele compunerii. Operatorul este asimetric.
Tupluri ale relaţiei R care participă în compunerea (naturală sau
θ-JOIN) dintre relaţiile R şi S.
SEMI-JOIN este un operator derivat, fiind o combinaţie de proiecţie
şi compunere naturală sau proiecţie şi θ-JOIN:
SEMIJOIN(R, S) = ΠM (JOIN(R, S))
SEMIJOIN(R, S, condiţie) = Π M (JOIN(R, S, condiţie)),
unde am notat prin M atributele relaţiei R.
Exemplu. Să se obţină informaţii referitoare la persoanele fizice
(nume, buletin) care investesc în obiective cu caracter recreativ.
1. Operatorul SEMI-JOIN în algebra relaţională:
R = SELECT(OBIECTIV_INVESTITIE, denumire = ’cabana’ OR
denumire = ’casa de vacanta’)
S = JOIN(PERS_FIZICA, R)
Rezultat = PROJECT(S, nume, buletin).
2. Operatorul SEMI-JOIN în SQL:
SELECT nume,bi
FROM pers_fizica a,obiectiv_investitie b
WHERE a.cod_contractant = b.cod_contractant
AND (denumire=’cabana’)OR (denumire= ’casa
de vacanta’);
30
Ideea generală:
cerere arbore algebric (nu este unic) plan de executie optimizare
Un plan de execuţie implică o secvenţă de paşi pentru evaluarea cererii
(în mod obişnuit, fiecare pas din planul de execuţie corespunde unei operaţii
relaţionale) precum şi metoda care va fi folosită pentru evaluarea operaţiei.
De obicei, pentru o operaţie relaţională dată, există mai multe metode ce pot
fi folosite pentru evaluarea acesteia.
Două planuri de execuţie diferite care au întotdeauna acelaşi rezultat se
numesc echivalente. Planuri de execuţie echivalente pot avea diferite
costuri. Scopul optimizării cererilor este de a găsi, printre diversele planuri
de execuţie echivalente, pe acela de cost minim. Într-un sistem centralizat,
costul evaluării unei cereri este suma a două componente, costul I/O
(transferuri de date) şi costul CPU (verificare de condiţii, operaţii join etc.).
33
NORMALIZAREA RELAŢIILOR
În procesul modelării unei baze de date relaţionale, o etapă importantă
o reprezintă normalizarea relaţiilor conceptuale (Codd, 1972), adică
obţinerea de relaţii „moleculare“fără a pierde nimic din informaţie pentru a
elimina:
• redundanţa;
• anomaliile reactualizării informaţiilor.
Tehnica normalizării permite obţinerea unei scheme conceptuale
rafinate printr-un proces de ameliorare progresivă a unei scheme conceptuale
iniţiale a bazei de date relaţionale. După fiecare etapă de ameliorare, relaţiile
bazei de date ating un anumit grad de perfecţiune, deci se află într-o anumită
formă normală. Trecerea unei relaţii dintr-o formă normală în alta, presupune
eliminarea unei anumit tip de dependenţe nedorite, care sunt transformate în
dependenţe admisibile, adică dependenţe care nu provoacă anomalii.
39
Dependenţe funcţionale
O relaţie universală este o relaţie ce grupează toate atributele care
modelează sistemul real cercetat. Fie E, mulţimea dependenţelor
considerate de proiectantul bazei pentru o schemă relaţională sau pentru o
relaţie universală. Plecând de la o mulţime de proprietăţi formale ale
dependenţelor, proprietăţi considerate drept reguli de deducţie (axiome),
poate fi obţinută mulţimea maximală de dependenţe asociate lui E. Această
mulţime defineşte închiderea lui E.
Fie E mulţimea dependenţelor unei relaţii şi p 1, p 2, ..., p r, r ≥ 1,
proprietăţi formale ale acestor dependenţe. Dacă există o mulţime E′, astfel
încât orice dependenţă a mulţimii E este derivabilă din E′ prin aplicarea
proprietăţilor p 1, p2 , ..., pr , atunci mulţimea E′ defineşte acoperirea lui E
pentru proprietăţile p1 , p 2, ..., p r.
E′ este o acoperire minimală pentru E, dacă nu există nici o
submulţime proprie, nevidă a lui E′ care să fie o acoperire pentru E.
40
localitate
W#
calitate
varsta
regiune
tara
data cantitate
D#
nume
localitate
W#
calitate
varsta
43
regiune
tara
data cantitate
D#
nume
2. Graful dependenţelor funcţionale pentru schema relaţională
OBIECTIV_INVESTITIE. Dependentele sunt deduse din regulile impuse de
beneficiar!
aria_construita
denumire
nr_certificat_urbanizare
cod_obiectiv# adresa
nr_aut_construtie
nr_contract cod_contractant
Necesitatea normalizării
Constrângere:
toate avioanele cu acelaşi nume au aceeaşi capacitate.
Datorită dependenţei introduse pot exista: anomalii la inserare,
modificare sau ştergere, redundanţă în date, probleme de reconexiune.
44
Relatia universala
FN1
FN2
FN3
BCNF
FN4
FN5
AVION2
A# Nume Localitate
1 AIRBUS PARIS
2 AIRBUS PARIS
3 AIRBUS LONDRA
4 CAR PARIS
5 B707 LONDRA
6 B707 LONDRA
Varianta 2
Persoana Prima Doi Trei Patru
Eu R25 W14 R21
Tu 205
El R5 305
Noi BX 305 R12 R25
Varianta 3 (4 tabele)
Masina 31 (similar se definesc Masina_32, Masina_33, Masina_34)..
Persoana Vehicul
Eu R25
Tu 205
El R5
Noi BX
Masina_34
Persoana Vehicul
Noi R25
atasat_2a
Cod_salariat# Nr_proiect# Functia Suma
S1 P1 Supervizor 60
S1 P2 Cercetator 25
S1 P3 Auxiliar 10
S3 P3 Supervizor 60
48
S5 P3 Supervizor 60
atasat_2b
Cod_salariat# Job_cod
S1 Programator
S3 Vanzator
S5 Inginer
K1 K2
K X1 X2
X3
50
K1 K2
X
Exemplu:
ADRESA(cod_parsoana#, telefon#, adresa)
cod_persoana
adresa
55
telefon
x y z
x y' z'
x y z'
x y' z
tupluri <x, y, z> şi <x, y′, z′>, se obţine y = y′. Prin urmare în relaţie apar
tuplurile <x, y′, z> şi <x, y, z′> şi deci X →→ Y (MVD).
Fie W, V, X, Y şi Z submulţimi de atribute ale unei scheme relaţionale
R. Fiind dată o mulţime T de multidependenţe există o mulţime completă
de axiome (Ax1–Ax8) care permit obţinerea tuturor multidependenţelor ce
se pot deduce din mulţimea T:
Ax1. Dacă Y ⊂ X, atunci X → Y.
Ax2. Dacă X → Y, atunci X ∪ Z → Y ∪ Z.
Ax3. Dacă X → Y şi Y → Z, atunci X → Z.
Ax4. Dacă X →→ Y, atunci X →→ R – {X ∪ Y}.
Ax5. Dacă X →→ Y şi V ⊂ W, atunci W ∪ X →→ V ∪ Y.
Ax6. Dacă X →→ Y şi Y →→ Z, atunci X →→ (Z – Y).
Ax7. Dacă X → Y, atunci X →→ Y.
Ax8. Dacă X →→ Y, Z → W, W ⊂ Y şi Y ∩ Z = ∅, atunci X → W.
O multidependenţă elementară este o multidependenţă care are
părţi stângi şi drepte minimale (nu există X′ ⊂ X şi Y′ ⊂ Y a.i. X′ →→ Y′).
Formal, relaţia R este în a patra formă normală dacă şi numai dacă:
• R este în BCNF;
• orice dependenţă multivaloare este o dependenţă funcţională.
O relaţie BCNF este în FN4 dacă pentru orice multidependenţă
elementară de forma X →→ Y, X este o supercheie a lui R. Aducerea
relaţiilor în FN4 presupune eliminarea dependenţelor multivaloare atunci
când sunt mai mult de una în cadrul unei relaţii.
Regula de descompunere în relaţii FN4. Fie R(X, Y, Z) o schemă
relaţională care nu este în FN4 şi fie X →→ Y o multidependenţă
elementară care nu este de forma „CHEIE →→ atribut“. Această relaţie
este descompusă prin proiecţie în două relaţii:
R = JOIN(ΠX∪Y (R), ΠX∪Z (R)).
Aplicând recursiv această regulă, se obţin relaţii FN4.
Exemplu. Fie relaţia INVESTITIE(cod_contractant#, denumire,
telefon) şi presupunem că un investitor poate avea mai multe numere de
telefon şi că poate investi în mai multe obiective. Între atributele relaţiei
există multidependenţele:
cod_contractant# →→ denumire;
cod_contractant# →→ telefon.
58
Exemplu.
Fie schema relaţională:
EXECUTANT(nr_santier#, cod_obiectiv#, cod_lucrare#, data_inceput,
data_sfarsit). Un şantier poate executa mai multe lucrări referitoare la
acelaşi obiectiv sau poate executa o lucrare pentru un obiectiv în intervale
de timp distincte. Se presupune că mai multe şantiere pot executa aceeaşi
lucrare, în acelaşi interval de timp sau în intervale de timp distincte.
Relaţia, datorită dependenţelor formulate anterior, nu este în FN5. Ea
se poate desface prin proiecţie în trei relaţii:
EX1(nr_santier#, cod_obiectiv#, cod_lucrare#);
EX2(nr_santier#, data_inceput, data_sfarsit);
EX3(cod_obiectiv#, cod_lucrare#, data_inceput, data_sfarsit).
Sunt evidente relaţiile:
EXECUTANT ≠ JOIN(EX1, EX2),
EXECUTANT ≠ JOIN(EX1, EX3),
EXECUTANT ≠ JOIN(EX2, EX3),
EXECUTANT = JOIN(JOIN(EX1, EX2), EX3).
Concluzii:
1. FN1 → FN2 elimină redundanţele datorate dependenţei netotale
a atributelor care nu participă la o cheie, faţă de cheile lui R. Se
suprimă dependenţele funcţionale care nu sunt totale.
2. FN2 → FN3 elimină redundanţele datorate dependenţei
tranzitive. Se suprimă dependenţele funcţionale tranzitive.
3. FN3 → BCNF elimină redundanţele datorate dependenţei
funcţionale. Se suprimă dependenţele în care partea stângă nu
este o supercheie.
4. BCNF → FN4 elimină redundanţele datorate multidependenţei.
Se suprimă toate multidependenţele care nu sunt şi dependenţe
funcţionale.
61
ANSI, IBM, Microsoft, Borland, etc. Din păcate, lipsa unui standard unic
SQL are drept consecinţe creşterea costurilor programelor de gestiune a
bazelor de date şi îngreunarea întreţinerii arhitecturilor client/server.
Un grup de specialişti în baze de date s-au reunit sub numele SAG
(SQL Access Group) cu scopul de a construi un limbaj SQL comun şi de a
realiza pentru fiecare dialect un program de conversie din dialect în SQL, şi
invers.
Rezultatul a fost că în:
• 1992, Microsoft a lansat ODBC (Open Database Connectivity)
care este o mulţime de primitive bazate pe activitatea lui SAG;
• 1994 Borland a lansat IDAPI (Integrated Database Application
Programming Interface) care este o bibliotecă de funcţii SQL ce
se pot integra într-un program gazdă.
Limbaje algebrice
În abordarea algebrică, o relaţie este considerată ca o mulţime de
tupluri, iar o bază de date este considerată ca o mulţime de relaţii pe care
sunt definiţi operatorii algebrici.
Există două tipuri de operatori algebrici: mulţime (intersecţie,
reuniune, diferenţă, produs cartezian) şi relaţionali (proiecţie, selecţie,
diviziune, compunere). Operatorii selecţie, proiecţie, produs cartezian,
reuniune şi diferenţă sunt ireductibili şi sunt consideraţi drept operatori de
bază, iar operatorii intersecţie, diviziune şi compunere pot fi deduşi din
operatorii anteriori şi sunt consideraţi operatori derivaţi.
Operatorii limbajului algebric permit exprimarea unor cereri
nerecursive. Dacă cererea este recursivă este necesar un operator special şi
anume închiderea tranzitivă a unei relaţii.
SEQUEL (Structured English as a Query Language) este un
limbaj algebric definit pentru prototipul relaţional SYSTEM–R. Operaţia
fundamentală a limbajului este SELECT, care are forma generală clasică.
Operatorii clasici UNION, INTERSECTION, DIFFERENCE şi
INCLUSION sunt implementaţi în limbaj. SEQUEL este singurul limbaj
relaţional care are integrată închiderea tranzitivă. Limbajul permite
reactualizări asupra bazelor (UPDATE, INSERT, DELETE) şi calculul
unor funcţii elementare (COUNT, SUM, AVG, MAX, MIN). Conceptul de
partiţionare a fost de asemenea introdus în SEQUEL şi realizat cu ajutorul
clauzelor GROUP BY şi HAVING.
O extensie comercială a acestui limbaj, adoptată de aproape toate
SGBD şi considerată drept standard în prelucrarea datelor relaţionale, este
SQL.
69
Limbaje predicative
Limbajele predicative se bazează pe calculul predicatelor. Cererile
sunt exprimate sub forma unor mulţimi de tupluri sau valori pentru care se
specifică, sub forma unor predicate, proprietăţile pe care trebuie să le
îndeplinească.
QUEL este un limbaj predicativ orientat pe tupluri, utilizat de
sistemul INGRES. Limbajul QUEL poate fi utilizat independent sau inclus
în limbajul de programare C. Limbajul este caracterizat de:
• declararea unei variabile tuplu pentru fiecare relaţie (prin
RANGE),
• absenţa cuantificatorilor în expresii,
• utilizarea unor operatori speciali pe mulţimi,
• integrarea operaţiilor aritmetice.
Exemplu.
Să se listeze numele cititorilor care au împrumutat cărţi scrise de
Cioran.
RANGE OF a IS carte
RANGE OF b IS cititor
RANGE OF v IS imprumuta
RETRIEVE b.nume
WHERE (b.codec = v.codec)
AND (v.codel = a.codel)
AND (a.autor = ’Cioran’)
Limbajul acceptă comenzi de inserare (APPEND), reactualizare
(REPLACE), suprimare (DELETE), precum şi funcţii de calcul (MAX, MIN,
SUM, COUNT, AVG). Cuantificatorul existenţial este reprezentat implicit
prin declaraţia RANGE, iar cuantificatorul universal este simulat cu ajutorul
funcţiei COUNT.
Exemplu.
Să se listeze numele cititorilor care au împrumutat toate cărţile din
bibliotecă scrise de Cioran.
RANGE OF a IS carte
RANGE OF b IS cititor
RANGE OF v IS imprumuta
RETRIEVE b.nume
WHERE
COUNT (v.codel
WHERE (b.codec=v.codec)
70
AND (a.codel=v.codel)
AND (a.autor=’Cioran’))
=
COUNT (a.codel WHERE (a.autor=’Cioran’))
Algebric:
R1 = SELECT(carte, autor = 'Popa')
R2 = SELECT(carte, titlu = Geometrie')
R3 = R1 ∪ R2
Rezultat = PROJECT (R3, codel)
SEQUEL:
SELECT codel
FROM carte
WHERE autor = ’Popa’
OR titlu = ’Geometrie’
QBE:
Carte Codel Titlu Autor Pret Nrex Coded
P.X 'Popa'
P.Y 'Geometrie'
Exemplu.
Numele cititorilor care au împrumutat cel putin o carte scrisa de
Cioran.
Algebric:
R1 = PROJECT(cititor, codec, nume)
R2 = SELECT(carte, autor = 'Cioran')
R3 = PROJECT(R2, codel)
R4 = PROJECT(imprumuta, codel, codec)
R5 = JOIN(R4, R3, codel)
R6 = JOIN(R5, R1, codec)
Rezultat = PROJECT(R6, nume)
QBE:
Cititor Codec Nume Dep
Y P.X
SELECT codec
FROM imprumuta
WHERE codel IS IN
SELECT codel
FROM carte
WHERE autor = ’Cioran’
Exemplu.
Să se obţină o relaţie având numele rezultat, ce conţine toate cărţile
scrise de Cioran care au preţul mai mare de 150000.
VAR rezultat: abc;
…
BEGIN
rezultat:=[];
FOR EACH x IN carte DO
IF(x.autor = ’Cioran’) AND (x.pret >= 150000)
THEN rezultat:=rezultat + [x]
END;
Relaţia rezultat poate fi construită şi direct prin atribuirea:
rezultat := [EACH (x) IN carte:
(x.autor = ’Cioran’) AND (x.pret >= 150000)];
PROIECTAREA BAZELOR DE DATE
RELAŢIONALE
3.1. Preliminarii
1
Modelul relaţional, deşi are unele imperfecţiuni, a fost adoptat în
ultimele decenii de majoritatea programatorilor din domeniu, tocmai datorită
acestor trei calităţi: este simplu, riguros din punct de vedere matematic şi nu
este orientat spre sistemul de calcul.
Definirea unui SGBD relaţional impune analizarea caracteristicilor pe
care trebuie să le prezinte un model de date pentru a fi considerat relaţional.
Există diferite modalităţi pentru a defini acest concept:
• prezentarea datelor în tabele supuse anumitor operaţii de tip
proiecţie, selecţie, reuniune, compunere, intersecţie etc. (definiţie
simplă);
• un sistem de baze de date ce suportă un limbaj de tip SQL –
Structured Query Language (definiţie practică);
• un sistem de baze de date care respectă principiile modelului
relaţional introdus de E.F. Codd (definiţia folosită cel mai
frecvent).
E.F. Codd a publicat un set de 13 reguli, numite reguli de fidelitate, în
raport cu care un SGBD poate fi apreciat ca relaţional. Ulterior, cele 13
reguli de fidelitate ale lui Codd au fost extinse la un număr de 100. Trebuie
remarcat că nu există un SGBD care respectă toate regulile definite de Codd.
Nu trebuie să apreciem un SGBD ca fiind relaţional sau nu, ci măsura în care
acesta este relaţional, deci numărul regulilor de fidelitate pe care le respectă.
2
• existenţa unor structuri de date simple,
• minimizarea redundanţei,
• supleţea în comunicarea cu utilizatorul neinformatician etc.
Ca limite ale modelului relaţional pot fi menţionate:
• rămâne totuşi redundanţă,
• ocupă spaţiu,
• apar fenomene de inconsistenţă,
• nu există mecanisme pentru tratarea optimă a cererilor recursive,
• nu lucrează cu obiecte complexe,
• nu există mijloace perfecţionate pentru exprimarea constrângerilor
de integritate,
• nu realizează gestiunea cunoştinţelor etc.
Un model relaţional este caracterizat de trei elemente:
3
Tipurile pot fi oricât de simple sau de complexe. Se pot distinge tipuri
de date ale căror valori sunt numere, şiruri, date calendaristice, înregistrări
audio sau video, hărţi, puncte geometrice etc.
Orice tip de date este scalar (atomic, încapsulat) sau nescalar. Tipul
nescalar are componente vizibile utilizatorului şi direct accesibile.
Trebuie făcută distincţia între un tip şi reprezentarea sa fizică,
deoarece tipurile sunt legate de model, iar reprezentarea fizică este un aspect
legat de implementare.
Fie D 1 , D 2 , ..., D n domenii finite, nu neapărat disjuncte. Produsul
cartezian D1 × D2 × ... × Dn al domeniilor D 1, D 2, ..., Dn este definit de
mulţimea tuplurilor (V1, V2, ..., Vn ), unde V1 ∈ D1 , V2 ∈ D 2, ..., Vn ∈ Dn .
Numărul n defineşte aritatea tuplului.
O relaţie R pe mulţimile D1 , D2 , ..., Dn este o submulţime a produsului
cartezian D 1 × D2 × ... × D n, deci este o mulţime de tupluri. Există un alt mod
de a defini relaţia, şi anume ca o mulţime finită de funcţii. Asociem fiecărui
domeniu D i un atribut A i şi definim relaţia R = {f 1 , f 2 , ..., f m}, unde
fi : {A1, A2, ..., An } → D1 ∪ D 2 ∪ ... ∪ Dn şi fi (Aj ) ∈ D j pentru orice valori ale
lui i şi j. În această definiţie nu mai este restricţionată ordinea.
Definirea unei relaţii ca o mulţime de tupluri sau ca o mulţime de funcţii
se referă la mulţimi care variază în timp (se adaugă, se şterg sau se modifică
elemente). Pentru a caracteriza o relaţie este necesară existenţa unui element
invariant în timp, iar acest invariant este dat de structura relaţiei (schema
relaţională). Mulţimea numelor atributelor corespunzătoare unei relaţii R
defineşte schema relaţională a relaţiei respective. Vom nota schema
relaţională prin R(A1, A2, ..., An ).
De exemplu, pentru modelul de date analizat în această lucrare,
VESTIMENTATIE(cod_vestimentatie, cod_designer, cod_model,
cod_prezentare, denumire, valoare, descriere) reprezintă o schemă relaţională.
Putem reprezenta o relaţie printr-un tabel bidimensional în care fiecare
linie corespunde unui tuplu şi fiecare coloană corespunde unui domeniu din
produsul cartezian. O coloană corespunde unui atribut. Numărul atributelor
defineşte gradul relaţiei, iar numărul de tupluri din relaţie defineşte
cardinalitatea relaţiei.
Bazele de date relaţionale sunt percepute de către utilizatori ca o
mulţime de tabele. Tabelul reprezintă structura logică dintr-un sistem
relaţional, nu structura fizică. La nivel fizic, sistemul poate stoca datele în
diferite moduri, folosind fişiere secvenţiale, indexări, înlănţuiri de pointeri etc.,
cu condiţia să poată realiza corespondenţa dintre reprezentarea stocată şi
tabelele de la nivelul logic.
4
Bazele de date relaţionale respectă principiul informaţiei (principiul
reprezentării uniforme), care afirmă că întregul conţinut informaţional al bazei
este reprezentat într-un mod unic, şi anume, ca valori explicite ale celulelor
unui tabel. Această modalitate de reprezentare este singura disponibilă, la nivel
logic, într-un sistem relaţional.
Când se inserează tupluri într-o relaţie, de multe ori valoarea unui
atribut este necunoscută sau nu este aplicabilă tuplului respectiv. Pentru a
reprezenta valoarea acestui atribut a fost introdusă o valoare convenţională
în relaţie, şi anume null. De fapt, null nu reprezintă o valoare, ci absenţa
uneia. Un null nu este acelaşi lucru cu o valoare numerică egală cu zero sau
cu un şir de caractere vid. Zerourile şi spaţiile libere (şirul vid) sunt valori,
pe când null semnifică absenţa unei valori. Prin urmare, null trebuie tratat în
mod diferit faţă de alte valori şi trebuie înţeles că termenul „valoare nulă“
este depreciativ.
Evident, este necesară o aritmetică şi o logică (polivalentă) nouă
(fig.3.1) care să cuprindă acest element. De exemplu, ce valoare are „10 >
null“ ? Răspunsul este null. În general, rezultatul operaţiilor aritmetice sau
logice este null când unul din operanzi este null. Prin urmare, „null = null“
are valoarea null, iar ¬ null este null.
Întroducerea null-urilor în modelul relaţional constituie o problemă
controversată, deşi Codd tratează null ca parte integrantă a modelului. Alţii
consideră această abordare greşită şi prematură. Trebuie remarcat că nu toate
sistemele relaţionale acceptă null-urile.
T T F Null T T T T
F F F F F T F Null
5
Dacă baza de date conţine tabele reale depuse pe disc, o vizualizare
este virtuală deoarece datele pe care le conţine nu sunt în realitate memorate
într-o bază de date. Este memorată numai definiţia vizualizării. Vizualizarea
nu este definită explicit, ca relaţiile de bază, prin mulţimea tuplurilor
componente, ci implicit, pe baza altor relaţii obţinute prin intermediul unor
expresii relaţionale. Stabilirea efectivă a tuplurilor care compun vizualizarea
se realizează prin evaluarea expresiei atunci când utilizatorul se referă la
acest tabel.
Utilizarea vizualizărilor este avantajoasă, deoarece:
• asigură securitatea tabelului iniţial (care este protejat de ştergeri,
modificări etc.) prin capacitatea de a ascunde datele;
• permit vizualizarea simultană a aceloraşi date de către diverşi
utilizatori;
• sunt concise, punând la dispoziţie capacităţi „macro“;
• asigură independenţa logică faţă de date (imunitatea programelor
de aplicaţie faţă de modificările din structura logică a bazei de
date).
Există totuşi limitări în utilizarea acestor tabele, în special legate de
problema reactualizării. De exemplu, coloanele calculate nu pot fi
reactualizate. De asemenea, inserarea, reactualizarea şi ştergerea nu sunt, în
general, recomandate şi sunt permise numai cu anumite restricţii care sunt
specifice fiecărui SGBD. De exemplu, Oracle9i rezolvă problema dificilă a
reactualizării vizualizărilor, în anumite situaţii, utilizând o clasă specială de
declanşatoare (TRIGGER de tip INSTEAD OF).
6
Prin urmare, o cheie a unei relaţii R este o mulţime K de atribute,
astfel încât:
(1) pentru orice două tupluri t 1 , t 2 ale lui R ⇒ t 1 (K) ≠ t 2 (K);
(2) nu există nicio submulţime proprie a lui K având proprietatea (1).
Fiecare relaţie are cel puţin o cheie. Dacă există diferite chei posibile,
ele se numesc chei candidat. Una dintre cheile candidat va fi aleasă pentru a
identifica efectiv tupluri şi ea va primi numele de cheie primară. Cheia
primară nu poate fi reactualizată. Restul cheilor candidat vor purta numele de
chei alternative sau secundare. Atributele care reprezintă cheia primară pot fi
subliniate sau urmate de semnul „#“.
O cheie identifică linii şi este diferită de un index care localizează
liniile. O cheie secundară este folosită ca index pentru a accesa tupluri. Un
grup de atribute din cadrul unei relaţii care conţine o cheie a relaţiei poartă
numele de supercheie.
Fie schemele relaţionale R1(P1, S1) şi R2(S1, S2), unde P1 este cheie
primară pentru R1, S1 este cheie secundară pentru R1, iar S1 este cheie
primară pentru R2. În acest caz, vom spune că S1 este cheie externă (cheie
străină) pentru relaţia R1.
De exemplu, cod_casa_moda este cheie externă pentru relaţia
CREATOR şi este cheie p irmară p entru relaţia CASA_ MODA. Cheia
primară poate conţine cheia externă. De exemplu, relaţia ACCESORIU are
cheia primară formată din atributele cod_accesoriu şi cod_vestimentatie, iar
atributul cod_vestimentatie fiind cheie primară în relaţia
VESTIMENTATIE, devine cheie externă în relaţia ACCESORIU.
Modelul relaţional respectă trei reguli de integritate structurală.
7
mai dificil de optimizat de către sistem şi, de asemenea, sunt executate doar
atunci când apare evenimentul specificat (declanşator).
Declanşatorii trebuie utilizaţi cu precauţie, sau deloc, dacă există o
modalitate alternativă de rezolvare a problemei respective. Ei pot crea
probleme practice datorită fenomenului „declanşatori în cascadă“ (lanţ de
declanşatori). De asemenea, dacă acelaşi eveniment determină pornirea mai
multor declanşatori diferiţi, atunci ordinea în care pornesc poate fi
importantă sau poate fi chiar nedefinită. Există posibilitatea ca un
declanşator să se declanşeze singur, recursiv. Dacă sunt disponibile, soluţiile
declarative sunt de preferat celor procedurale.
8
3.3. Proiectarea modelului relaţional
9
3.3.1. Transformarea entităţilor
10
şi cod_prezentare. Practic, în acest caz, este preferabil să fie
introdusă o cheie primară artificială.
11
LIMBA INFO_CONTACT
ORGANIZATOR
are ×
PERS CONTACT
face ×
are
PUBLICITATE×
organizeaza LOCALIZARE
FIRMA_SEC LOCATIE
se_face
are
are
×
ANGAJAT_SEC PAZA × × FINANTEAZA SPONSOR
PREZENTARE
×
asigura PARTICIPA
SOC ASIG
are refera
×
× ACCESORIU ISTORIC ×
12
Cele patru tipuri de tabele (independente, dependente, subtabele şi
asociative) se deosebesc prin structura cheii primare (figura 3.2.).
În figura 3.3 este prezentată diagrama conceptuală pentru proiectarea
modelului relaţional comentat. Ea a fost construită din diagrama E/R prin
adăugarea tabelelor asociative şi prin marcarea cheilor externe.
În continuare va fi prezentată modalitatea efectivă de trecere de la
diagrama entitate-relaţie la diagrama conceptuală pentru modelul de date
real analizat în capitolul 2.
Entităţile independente PERS_CONTACT, ORGANIZATOR,
PREZENTARE, PUBLICITATE, SPONSOR, FIRMA_PUB,
CASA_MODA, CREATOR, ANGAJAT_TEMP, ACCESORIU,
LOCALIZARE, FIRMA_SEC, ANGAJAT_SEC, SOCIETATE_ASIG,
INFO_CONTACT, AGENTIE, LOCATIE devin tabele independente.
Cheile primare ale fiecărei entităţi au fost specificate în capitolul 2.
Entităţile dependente ISTORIC şi ACCESORIU, care intervin în
model, devin tabele dependente, iar cheile primare au fost specificate în
capitolul 2.
Subentitatea MODEL devine subtabel, având aceeaşi cheie primară cu
superentitatea ANGAJAT_TEMP, adică atributul cod_angajat.
Relaţiile de tip one-to-one şi one-to-many devin chei externe.
Relaţia PERS_CONTACT_are_LOCALIZARE devine cheie externă în
tabelul PERS_CONTACT. Dacă restricţia că o persoană de contact are o
singură localizare este eliminată, atunci cardinalitatea relaţiei devine 1:n, iar
atributul cod_pers_contact devine cheie externă în tabelul LOCALIZARE.
Toate comentariile anterioare rămân valabile şi pentru entităţile
FIRMA_PUB, FIRMA_SEC, PREZENTARE, ORGANIZATOR,
CASA_MODA, SPONSOR, SOC_ASIG, CREATOR, LOCATIE,
ANGAJAT_TEMP şi AGENTIE, care sunt legate de entitatea
LOCALIZARE, permiţând astfel localizarea tuturor structurilor modelului.
Relaţia PERS_CONTACT_are_INFO_CONTACT devine cheie externă în
tabelul PERS_CONTACT. Dacă restricţia că pentru o persoană de contact
există o singură posibilitate de contactare este eliminată, atunci
cardinalitatea relaţiei devine 1:n, iar atributul cod_pers_contact devine cheie
externă în tabelul INFO_CONTACT. Toate comentariile anterioare rămân
valabile şi pentru entităţile FIRMA_PUB, FIRMA_SEC,
ANGAJAT_TEMP, PREZENTARE, ORGANIZATOR, CASA_MODA,
SPONSOR, SOC_ASIG, CREATOR, LOCATIE şi AGENTIE, care sunt
legate de entitatea INFO_CONTACT, permiţând astfel accesarea tuturor
structurilor modelului.
13
Relaţia FIRMA_PUB_face_PUBLICITATE devine cheie externă în tabelul
PUBLICITATE.
Relaţia PUBLICITATE_se_face_pentru_PREZENTARE devine cheie
externă în tabelul PUBLICITATE.
Relaţia ORGANIZATOR_are_PERS_CONTACT devine cheie externă în
tabelul PERS_CONTACT.
Relaţia FIRMA_SEC_are_ANGAJAT_SEC devine cheie externă în tabelul
ANGAJAT_SEC.
Relaţia SOC_ASIG_asigura_PREZENTARE devine cheie externă în tabelul
PREZENTARE.
Relaţia CASA_MODA_lucreaza_CREATOR devine cheie externă în tabelul
CREATOR.
Relaţia CREATOR_creeaza_VESTIMENTATIE devine cheie externă în
tabelul VESTIMENTATIE.
Relaţia VESTIMENTATIE_are_ACCESORIU devine cheie externă în tabelul
ACCESORIU.
Relaţia MODEL_prezintă_VESTIMENTATIE devine cheie externă în tabelul
VESTIMENTATIE.
Relaţia CREATOR_face_ACCESORIU devine cheie externă în tabelul
ACCESORIU.
Relaţia PREZENTARE_prezinta_VESTIMENTATIE devine cheie externă în
tabelul VESTIMENTATIE.
Relaţia PREZENTARE_are_LOCATIE devine cheie externă în
PREZENTARE.
Relaţia MODEL_lucreaza_AGENTIE devine cheie externă în tabelul
MODEL.
Relaţia MODEL_are_ISTORIC devine cheie externă în tabelul ISTORIC.
Relaţia ISTORIC_refera_AGENTIE devine cheie externă în tabelul
ISTORIC.
Relaţiile de tip many-to-many devin tabele asociative, având două
chei externe pentru cele două tabele asociate.
Relaţia ANGAJAT_SEC_paza_PREZENTARE devine tabel asociativ
(PAZA).
SPONSOR_finanteaza_PREZENTARE devine tabel asociativ
(FINANTEAZA).
CASA_MODA_participa_PREZENTARE devine tabel asociativ
(PARTICIPA).
Relaţiile de tipul trei (adică cele care leagă cel puţin trei entităţi)
devin tabele asociative, având chei externe pentru fiecare dintre tabelele
asociate.
14
Relaţia primeste, care leagă entităţile ANGAJAT_TEMP, PREZENTARE şi
CASA_MODA, devine tabel asociativ (PRIMESTE). În acest caz, s-a
considerat o cheie primară artificială (atributul cod_primeste). Tabelul
asociativ are drept chei externe atributele: cod_angajat, cod_casa_moda şi
cod_prezentare.
Atributele multiple devin tabele dependendente ce conţin cheia
primară a entităţii şi atributul multiplu.
Atributul limba_cunoscuta este multiplu (relativ la entitatea
PERS_CONTACT) şi va genera tabelul dependent LIMBA. Acesta va avea
drept cheie primară atributele cod_pers_contact şi limba_cunoscuta. Tabelul
mai conţine trei atribute ce reprezintă nivelul de cunoaştere (scris, citit,
vorbit) a limbii.
Atributele entităţilor devin coloane în tabelele corespunzătoare. Pentru
relaţii 1:1 şi 1:n, atributele relaţiilor vor aparţine tabelului care conţine cheia
externă, iar pentru relaţii m:n şi de tipul trei, atributele vor fi plasate în
tabelele asociative.
Tabelul asociativ PRIMESTE va avea ca atribute, pe lângă cele ce constituie
cheia primară, suma, data_achitare, cont, banca.
Schemele relaţionale corespunzătoare diagramei conceptuale din
figura 3.3. sunt următoarele:
MODEL(cod_angajat#, cod_agentie, inaltime, nr_pantof, info)
ANGAJAT_TEMP(cod_angajat#, nume, prenume, data_nastere,
nationalitate, sex, cod_localizare, cod_info_acces, tip)
PUBLICITATE(cod_publicitate#, cod_firma_pub, cod_prezentare, tip,
nume, suma, observatii)
FIRMA_PUB(cod_firma_pub#, nume, info, director, observatii,
cod_localizare, nume_pers_contact, cod_info_acces)
ORGANIZATOR(cod_organizator#, denumire, banca, cont, cod_info_acces,
informatii, cod_localizare)
PERS_CONTACT(cod_pers_contact#, cod_organizator, nume, prenume,
directie, cod_localizare, cod_info_acces)
PREZENTARE(cod_prezentare#, denumire, data_start, data_final,
cod_soc_asig, cod_organizator, cod_locatie)
LOCATIE(cod_locatie#, denumire, tip, cod_localizare, cod_info_acces,
capacitate)
SPONSOR(cod_sponsor#, tip, nume, info, cod_localizare, cod_info_acces)
15
CASA_MODA(cod_casa_moda#, nume, cifra_afaceri, proprietar, director,
istoric, data_creare, cod_localizare, cod_info_acces)
CREATOR(cod_creator#, nume, prenume, data_nastere, data_angajare, tip,
mod_angajare, info, cod_casa_moda, cod_localizare, cod_info_acces)
VESTIMENTATIE(cod_vestimentatie#, denumire, valoare, descriere,
cod_creator, cod_model, cod_prezentare)
ACCESORIU(cod_vestimentatie#, cod_accesoriu#, cod_creator, descriere,
tip, valoare)
AGENTIE(cod_agentie#, nume, data_creare, director, cifra_afaceri, info,
cod_localizare, cod_info_acces)
ISTORIC(cod_model#, data_angajare#, data_final, cod_agentie, conditii)
LOCALIZARE(cod_localizare#, adresa, cod_postal, oras, tara)
INFO_CONTACT(cod_info_acces#, telefon_fix, telefon_mobil, mail, fax)
FIRMA_SEC(cod_firma_sec#, nume_firma, tip_servicii, director,
cod_localizare, cod_info_acces, observatii)
ANGAJAT_SEC(cod_angajat#, nume, prenume, data_nastere, specializare,
nivel, observatii, cod_info_acces, cod_firma_sec)
PAZA(cod_angajat#, cod_prezentare#, tip_paza, dotare, observatii)
SOC_ASIG(cod_soc_asig#, conditii, suma, director, observatii,
cod_localizare, nume_pers_contact_firma, cod_info_acces)
PARTICIPA(cod_prezentare#, cod_casa_moda#, tip, data)
FINANTEAZA(cod_sponsor#, cod_prezentare#, suma, banca, cont_emitent,
data_emitere, cod_ordin_plata)
PRIMESTE(cod_primeste#, cod_angajat, cod_prezentare, cod_casa_moda,
data_achitare, suma, cont, banca)
LIMBA(cod_pers_contact#, limba_cunoscuta#, niv_scris, niv_citit,
niv_vorbit)
16
3.4. Regulile lui Codd
17
Regulile pot fi organizate în următoarele cinci domenii de
funcţionalitate: reguli fundamentale, reguli structurale, reguli de integritate,
reguli de prelucrare a datelor şi reguli privind independenţa datelor.
Regula 1 – regula gestionării datelor. Un SGBD relaţional trebuie să
fie capabil să gestioneze o bază de date prin posibilităţile sale relaţionale.
Practic, nicio implementare curentă de SGBD nu respectă această regulă,
deoarece implementările conţin atât caracteristici relaţionale cât şi
nerelaţionale.
Regula 2 – regula reprezentării informaţiei. Într-o bază de date
relaţională, informaţia este reprezentată la nivel logic sub forma unor
tabele ce poartă numele de relaţii. Este regula cea mai importantă şi
conform lui Codd, un SGBD care nu respectă această regulă, nu poate fi
considerat relaţional. Chiar şi meta-datele, conţinute în catalogul de sistem,
trebuie să fie stocate ca relaţii.
Regula 3 – regula accesului garantat la date. Fiecare valoare dintr-o
bază de date relaţională trebuie să poată fi adresată în mod logic printr-o
combinaţie formată din numele relaţiei, valoarea cheii primare şi numele
atributului.
Regula 4 – regula reprezentării informaţiei necunoscute. Un sistem
relaţional trebuie să permită utilizatorului definirea unui tip de date numit
„null“ pentru reprezentarea unei informaţii necunoscute la momentul
respectiv. Într-un SGBD relaţional trebuie să putem face diferenţa între
valoarea zero, un şir vid de caractere şi o valoare necunoscută.
Regula 5 – regula dicţionarelor de date. Asupra descrierii bazelor de
date (informaţii relative la relaţii, vizualizări, indecşi etc.) trebuie să se
poată aplica aceleaşi operaţii ca şi asupra datelor din baza de date.
Descrierea bazei de date este reprezentată la nivel logic sub forma unor
tabele care pot fi accesate în acelaşi mod ca şi datele efective. Prin urmare
există un singur limbaj de prelucrare atât a meta-datelor, cât şi a datelor.
Regula 6 – regula limbajului de interogare. Trebuie să existe cel puţin
un limbaj pentru prelucrarea bazei de date. În general, toate implementările
SQL respectă această regulă. Limbajul permite utilizatorilor să definească
relaţii şi vizualizări, să prelucreze datele interactiv sau prin intermediul
programului, să regăsească informaţia şi să o poată actualiza, să verifice şi să
corecteze datele de intrare, să implementeze constrângeri, să stabilească
limite pentru tranzacţii etc.
Regula 7 – regula de actualizare a vizualizării. Un SGBD trebuie să
poată determina dacă o vizualizare poate fi actualizată şi să stocheze
rezultatul interogării, ce defineşte vizualizarea, într-un dicţionar de tipul
18
unui catalog de sistem. Trebuie să existe un mecanism prin care să se poată
determina dacă anumite vizualizări pot fi actualizate sau nu. Regula
stabileşte că toate vizualizările care sunt teoretic reactualizabile pot fi
reactualizate şi de către sistemul de gestiune. Nu au fost încă descoperite
condiţiile pentru identificarea tuturor vizualizărilor care pot fi teoretic
reactualizate.
Regula 8 – regula limbajului de nivel înalt. Capacitatea de tratare a
unei relaţii de bază sau a unei vizualizări ca pe un singur operand se aplică
atât pentru operaţiile de regăsire a datelor, cât şi asupra operaţiilor de
inserare, actualizare şi ştergere a datelor. Un SGBD relaţional nu trebuie să
oblige utilizatorul să caute într-o relaţie, tuplu cu tuplu, pentru a regăsi
informaţia dorită. Operaţiile de prelucrare a datelor pot să fie aplicate atât în
mod interactiv cât şi prin program, într-un limbaj gazdă.
Regula 9 – regula independenţei fizice a datelor. Programele de
aplicaţie şi activităţile utilizatorilor nu depind de modul de depunere a
datelor sau de modul de acces la date. Într-un SGBD relaţional trebuie să se
separe aspectul fizic al datelor (stocare sau acces la date) de aspectul logic al
datelor.
Regula 10 – regula independenţei logice a datelor. Programele de
aplicaţie trebuie să fie transparente la modificările de orice tip efectuate
asupra datelor. Orice modificare efectuată asupra unei relaţii nu trebuie să
afecteze operaţiile de prelucrare a datelor.
Regula 11 – regula independenţei datelor din punct de vedere al inte-
grităţii. Regulile de integritate trebuie să fie definite într-un sublimbaj
relaţional de date, nu în programul de aplicaţie. SQL permite definirea de
restricţii privind integritatea datelor şi stocarea lor în catalogul de sistem. Cu
cât sunt mai multe constrângeri de integritate care pot fi întreţinute mai
degrabă de către SGBD, decât în cadrul fiecărui program aplicaţie, cu atât
garantarea calităţii datelor este mai bună.
Regula 12 – regula independenţei datelor din punct de vedere al
distribuirii. Distribuirea datelor pe mai multe calculatoare dintr-o reţea de
comunicaţii de date nu trebuie să afecteze programele de aplicaţie. ANSI-
SQL nu menţionează regula în specificaţiile sale, deoarece este destul de
greu de respectat. De observat că regula nu cere ca SGBD-ul să accepte o
bază de date distribuite pentru a fi relaţional, dar stabileşte că limbajul de
interogare va rămâne acelaşi atunci când se va introduce această capacitate,
iar datele vor fi distribuite.
19
Regula 13 – regula versiunii procedurale a unui SGBD. Orice
componentă procedurală a unui SGBD trebuie să respecte aceleaşi restricţii
de integritate ca şi componenta relaţională. De exemplu, dacă în partea de
prelucrare a datelor a limbajului relaţional valoarea dintr-o coloană este de
tipul not null, orice altă metodă procedurală de accesare a acestei coloane nu
trebuie să permită introducerea unui null în această coloană. Prin urmare,
regulile de integritate exprimate într-un limbaj relaţional de un anumit nivel
nu pot fi distruse de un limbaj de nivel inferior.
Deoarece regulile lui Codd sunt prea severe pentru a fi respectate de
un SGBD operaţional, s-au formulat criterii minimale de definire a unui
SGBD relaţional.
Un SGBD este minimal relaţional dacă:
• toate datele din cadrul bazei sunt reprezentate prin valori în tabele;
• nu există pointeri observabili de către utilizator;
• sistemul suportă operatorii relaţionali de proiecţie, selecţie şi
compunere naturală, fără limitări impuse din considerente interne.
Un SGBD este complet relaţional dacă este minimal relaţional şi
satisface în plus condiţiile:
• sistemul suportă restricţiile de integritate de bază (unicitatea cheii
primare, constrângerile referenţiale, integritatea entităţii);
• sistemul suportă toate operaţiile de baza ale algebrei relaţionale.
20
4. NORMALIZAREA RELAŢIILOR
4.1. Preliminarii
În procesul modelării unei baze de date relaţionale, o etapă importantă o
reprezintă normalizarea relaţiilor conceptuale. Aceasta presupune obţinerea de
relaţii „moleculare“, fără a pierde nimic din informaţie, având scopul de a
elimina redundanţa şi anomaliile reactualizării informaţiilor. Tehnica
normalizării permite determinarea unei scheme conceptuale rafinate, printr-un
proces de ameliorare progresivă a unei scheme conceptuale iniţiale a bazei de
date relaţionale. După fiecare etapă de ameliorare, relaţiile bazei de date ating
un anumit grad de perfecţiune, deci se află într-o anumită formă normală.
Trecerea unei relaţii dintr-o formă normală în alta presupune eliminarea unui
anumit tip de dependenţe nedorite, care sunt transformate în dependenţe
admisibile, adică dependenţe care nu provoacă anomalii.
Procesul de ameliorare progresivă a schemei conceptuale trebuie să
satisfacă următoarele cerinţe:
• să garanteze conservarea datelor, adică în schema conceptuală
finală trebuie să figureze toate datele din cadrul schemei iniţiale;
• să garanteze conservarea dependenţelor dintre date, adică în
schema finală fiecare dependenţă trebuie să aibă determinantul şi
determinatul în schema aceleiaşi relaţii;
• să reprezinte o descompunere minimală a relaţiilor iniţiale, adică
nici una din relaţiile care compun schema finală nu trebuie să fie
conţinută într-o altă relaţie din această schemă.
Există două metode pentru a modela baze de date relaţionale fără
anomalii sau pierderi de informaţie.
• Schema descompunerii pleacă de la o schemă relaţională
universală care conţine toate atributele bazei de date. Schema se
descompune prin proiecţii succesive în subrelaţii. Descompunerea
se opreşte atunci când continuarea ei ar duce la pierderi de
informaţie. Algoritmii de descompunere se bazează, în general, pe
descrierea formală a dependenţei dintre atribute.
• Schema sintezei pleacă de la o mulţime de atribute independente.
Utilizând proprietăţi de semantică şi legături între atribute se pot
compune noi relaţii, astfel încât acestea să nu sufere de anumite
anomalii pe care dorim să le evităm. Algoritmii de sinteză se
bazează în general pe teoria grafurilor pentru a reprezenta
legăturile între atribute.
21
4.2. Dependenţe funcţionale
22
Fie X, Y, Z, W mulţimi de atribute ale unei scheme relaţionale R şi fie
următoarele reguli de inferenţă (axiome) prin care noi dependenţe
funcţionale pot fi deduse din cele date:
Ax1 – reflexivitate. X → X. Mai general, dacă Y ⊆ X, atunci X → Y.
Ax2 – creşterea determinantului. Pot fi considerate trei formulări echi-
valente pentru această axiomă.
1. Dacă X → Y şi X ⊆ Z, atunci Z → Y.
2. Dacă X → Y şi W ⊆ Z, atunci X ∪ Z → Y ∪ W.
3. Dacă X → Y atunci X ∪ Z → Y ∪ Z.
Ax3 – tranzitivitate. Dacă X → Y şi Y → Z, atunci X → Z.
23
2. Anomalie la inserţie. Dacă se doreşte includerea unei prezentări
de modă, care va incepe în luna aprilie şi va avea denumirea
„veselie“, atunci perechea (veselie, aprilie) poate fi inserată în
relaţia VP doar dacă se defineşte o nouă valoare pentru cheia
primară.
3. Anomalie la ştergere. Dacă este ştearsă înregistrarea pentru care
codul prezentării are valoarea 4, atunci se pierde informaţia că
prezentarea având denumirea „iarna“ a început în luna martie.
4. Anomalie la modificare. Dacă se modifică luna de început a
prezentării „primavara“ de la mai la februarie, atunci costul
modificării este mare pentru a modifica toate înregistrările, iar
dacă se modifică doar o înregistrare atunci constrângerea nu va
mai fi verificată.
Anomaliile au apărut datorită dependenţei funcţionale (constrângerii)
introduse anterior.
Normalizarea are drept scop: suprimarea redundanţei logice, evitarea
anomaliilor la reactualizare, rezolvarea problemei reconexiunii. Există o
teorie matematică a normalizării al cărei autor este E.F. Codd. Soluţia lui
E.F. Codd este construirea unor tabele standard (forme normale).
Normalizarea este procesul reversibil de transformare a unei relaţii, în
relaţii de structură mai simplă. Procesul este reversibil în sensul că nicio
informaţie nu este pierdută în timpul transformării. O relaţie este într-o formă
normală particulară dacă ea satisface o mulţime specificată de constrângeri.
Procesul normalizării se realizează plecând de la o relaţie universală ce
conţine toate atributele sistemului de modelat, plus o mulţime de anomalii.
Orice formă normală se obţine aplicând o schemă de descompunere.
24
Prima formă normală (FN1)
25
Pentru un tabel R care se descompune prin proiectie în mai multe tabele: R1,
R2, … Rn, conditia de descompunere fără pierdere de informatie presupune
ca în urma operatiei de compunere naturală a tabelelor R1, R2, … Rn să se
obtină tabelul R.
În SQL:
26
Exemplu
Fie schema relaţională PARTICIPA (cod_prezentare#,
cod_casa_moda#, tip, data, data_start, data_final, denumire)
Alt Exemplu:
27
A2 C2 P1 Ionescu 596322 09.10.04 camasa 400000 3
A2 C2 P3 Ionescu 596322 C2 09.10.04 tricou 200000 2
A2 C2 P2 Ionescu 596322 09.10.04 pantaloni 800000 1
A1 C3 P3 Popescu 415355 10.10.04 tricou 200000 3
A3 C4 P1 Marinescu 546229 C4 10.10.04 P1 camasa 400000 1
a) redundante în date:
- informatia (P1, camasa, 400000) este specificata de 3 ori
- informatia (A1, Popescu, 415355) este specificata de 3 ori
- informatia (A2, Ionescu, 196322) este specificata de 3 ori
- s. a. m. d.
b) anomalii la actualizare:
- anomalie la insertie
Dacă magazinul achizitionează un nou articol (P4, pantofi, 980000)
informatia nu poate fi introdusă în tabel (un nou tuplu) pentru că s-ar
introduce o valoare Null în cheia primară (cod_comanda).
- anomalie la stergere
Dacă este anulat articolul P2 în cadrul comenzii C2 se pierde informatia
referitoare la numele si costul articolului respectiv.
- anomalie la modificare
Dacă se modifică numărul de telefon al unui client, modificarea trebuie
facută în toate tuplurile (liniile) unde apare numele acelui client.
În tabelul VANZARI există următoarele dependente functionale în
care determinantul nu este cheie a tabelului:
28
Forma normală 3 (FN3)
Intuitiv, o relaţie R este în a treia formă normală dacă şi numai dacă:
• relaţia R este în FN2;
• fiecare atribut care nu este cheie (nu participă la o cheie) depinde
direct de cheia primară.
Fie R o relaţie, X o submulţime de atribute ale lui R şi A un atribut al
relaţiei R. A este dependent tranzitiv de X dacă există Y astfel încât X → Y şi
Y → A (unde A nu aparţine lui Y şi Y nu determină pe X). De exemplu, dacă
au loc dependenţele K 1 , K 2 , K 3 → A1 şi K 1 , K 2 , A1 → A 2 , atunci K 1 , K 2 , K 3
→ K 1 , K 2 , A 1 şi K 1 , K 2 , A 1 → A 2 . Prin urmare, A2 este dependent tranzitiv
de K 1 , K 2 , K 3 .
Formal, o relaţie R este în a treia formă normală dacă şi numai dacă:
• relaţia R este în FN2;
• fiecare atribut care nu este cheie (nu participă la o cheie) nu este
dependent tranzitiv de nicio cheie a lui R.
A doua condiţie interzice utilizarea dependenţelor funcţionale tranzitive
în cadrul relaţiei R.
Prin urmare, o relaţie este în FN3 dacă şi numai dacă fiecare
atribut care nu este cheie depinde de cheie, de întreaga cheie şi numai de
cheie.
Pentru a obţine o relaţie FN3 se poate aplica regula de descompunere
Casey-Delobel. Fie relaţia R(K, X 1 , X 2 , X3 ), unde atributul X 2 depinde
tranzitiv de K, iar K este cheia primară a lui R. Presupunem că K → X 1 →
X2 . Din cauza dependenţei funcţionale X1 → X 2 care arată că R nu este în
FN3, se înlocuieşte R (fără pierdere de informaţie) prin două proiecţii R1(K,
X1 , X 3 ) şi R2(X 1 , X2 ).
Dependenţa tranzitivă poate fi mai complexă. Fie K 1 o parte a cheii K.
Tranzitivitatea poate fi de forma K → Y → X 2 unde Y = {K 1 , X 1 }. În acest
caz, R poate fi descompusă în R1(K, X1 , X 3 ) şi R2(K 1 , X 1 , X2 ).
Algoritm AFN3 (aducerea unei relaţii FN2 în FN3 prin eliminarea
dependenţelor funcţionale tranzitive)
1. Pentru fiecare dependenţă funcţională tranzitivă se transferă
atributele implicate în dependenţa tranzitivă într-o nouă relaţie.
2. Se determină cheia primară a fiecărei noi relaţii create la pasul 1.
3. Se introduc în relaţia iniţială, în locul atributelor transferate, cheile
primare determinate la pasul 2.
29
4. Se reanalizează relaţia iniţială. Dacă în cadrul ei există noi
dependenţe tranzitive, atunci se face transfer la pasul 1, altfel
procesul de aducere la FN3 s-a terminat.
Exemplu
Fie schema relaţională PREZENT(cod_prezentare#, data_start,
data_final, denumire, cod_locatie, capacitate, cod_info_acces).
Pentru relaţia PREZENT sunt adevărate dependenţele:
{cod_prezentare} → {data_start, data_final, denumire, cod_locatie}
{cod_locatie} → {capacitate, cod_info_acces}
Relaţia PREZENT este în FN2, dar nu este în FN3 deoarece atributele
capacitate, cod_info_acces depind indirect de cheia primară, prin
intermediul atributului cod_locatie.
Pentru a obţine o relaţie în FN3 se aplică regula Casey-Delobel şi
relaţia PREZENT se proiectează în două relaţii, prin eliminarea
dependenţelor funcţionale tranzitive.
PREZENT1(cod_prezentare#, data_start, data_final, denumire, cod_locatie)
PREZENT2(cod_locatie#, capacitate, cod_info_acces)
30
cealaltă va avea schema formată din toate atributele relaţiei
iniţiale, mai puţin Y.
4. Se reiau paşii 1, 2, 3 pentru relaţiile obţinute la pasul 3.
Exemplu
Se consideră relaţia FINANTEAZA1, ce leagă entităţile
PREZENTARE şi SPONSOR. Ea are cardinalitatea many to many şi va
genera un tabel asociativ. Se presupune că acest tabel are schema
relaţională:
FINANTEAZA1(cod_prezentare#, cod_sponsor#, nume_prezentare,
cod_ordin_plata).
Pentru exemplul analizat se presupune că numele prezentărilor sunt
unice. Prin urmare, în orice moment fiecare prezentare are un cod unic şi
un nume unic. Cheile candidat sunt {cod_prezentare, cod_sponsor},
respectiv {nume_prezentare, cod_sponsor}.
Între atributele relaţiei există dependenţele:
{cod_prezentare, cod_sponsor} → {cod_ordin_plata}
{cod_prezentare} → {nume_prezentare}
Tabelul nu este în BCNF deoarece conţine doi determinanţi,
cod_prezentare şi nume_prezentare, care nu sunt chei candidat pentru
tabelul respectiv. Ambele atribute sunt determinanţi deoarece fiecare îl
determină pe celălalt.
Soluţia problemei constă în divizarea relaţiei în două proiecţii
conform tehnicii Casey-Delobel.
PREZENTARE(cod_prezentare#, nume_prezentare)
FINANTEAZA(cod_prezentare#, cod_sponsor#, cod_ordin_plata)
31
cod_pers# →→ limba_cunoscuta
cod_pers# →→ nr_telefon.
Pentru a aduce relaţia PERS_CONTACT (care este în BCNF) în FN4,
aceasta se va diviza în două proiecţii :
PERS_CONTACT1(cod_pers#, limba_cunoscuta)
PERS_CONTACT1(cod_pers#, nr_telefon).
Exemplu
Se consideră o relaţie ce conţine informaţii despre creatori,
vestimentaţiile create de aceştia şi accesoriile corespunzătoare. Se consideră
schema relaţională CREARE(cod_vestimentatie#, cod_creator#,
cod_accesoriu#).
Se presupune că fiecare creator poate crea una sau mai multe
vestimentaţii. Fiecare vestimentaţie poate fi creată de unul sau mai mulţi
creatori. Similar, fiecare creator este responsabil de crearea unuia sau a mai
multor accesorii, iar fiecare accesoriu este creat de unul sau mai mulţi
creatori. Fiecare accesoriu apare în una sau mai multe vestimentaţii, iar
fiecărei vestimentaţii i se ataşează unul sau mai multe accesorii.
Mai mult chiar, dacă creatorul C creează vestimentaţia V, iar
accesoriul A este ataşat lui V, iar C este este responsabil de A, atunci C
creează accesoriul A pentru vestimentaţia V.
Ţinând seama de constrângerile impuse modelului se obţin
dependenţele:
{cod_vestimentatie#, cod_creator#} → {cod_accesoriu}
{cod_vestimentatie#, cod_accesoriu#} → {cod_creator}
{cod_accesoriu#, cod_creator#} → {cod_vestimentatie}.
Datorită dependenţelor formulate anterior, relaţia nu este în FN5. Ea
se poate rupe prin proiecţie în trei relaţii:
CREARE1(cod_vestimentatie#, cod_creator#)
32
CREARE2(cod_vestimentatie#, cod_accesoriu#)
CREARE3(cod_creator#, cod_accesoriu#).
În acest caz, sunt evidente relaţiile:
CREARE ≠ JOIN(CREARE1, CREARE2)
CREARE ≠ JOIN(CREARE1, CREARE3)
CREARE ≠ JOIN(CREARE2, CREARE3)
CREARE = JOIN(JOIN(CREARE1, CREARE2), CREARE3).
Concluzii:
1. FN1 → FN2 elimină redundanţele datorate dependenţei netotale a
atributelor care nu participă la o cheie, faţă de cheile lui R. Se
suprimă dependenţele funcţionale care nu sunt totale.
2. FN2 → FN3 elimină redundanţele datorate dependenţei tranzitive.
Se suprimă dependenţele funcţionale tranzitive.
3. FN3 → BCNF elimină redundanţele datorate dependenţei
funcţionale. Se suprimă dependenţele în care partea stângă nu este
o supercheie.
4. BCNF → FN4 elimină redundanţele datorate multidependenţei. Se
suprimă toate multidependenţele care nu sunt şi dependenţe
funcţionale.
5. FN4 → FN5 elimină redundanţele datorate dependenţei ciclice. Se
suprimă toate join-dependenţele care nu sunt implicate de o cheie.
6. BCNF, FN4 şi FN5 corespund la regula că orice determinant este
o cheie, dar de fiecare dată dependenţa cu care se defineşte deter-
minantul este alta şi anume dependenţa funcţională,
multidependenţa sau join-dependenţa.
7. Descompunerea unei relaţii FN2 în FN3 conservă datele şi
dependenţele, pe când descompunerea unei relaţii FN3 în BCNF
şi, respectiv, a unei relaţii BCNF în FN4 conservă doar datele.
33
Limbajul de interogare a datelor(DQL)
Limbajul SQL de interogare a datelor (DQL – Data Query
Language) include o singură comandă SELECT, care este cea mai
folosită pentru a obţine date din baza de date, astfel încât acestea să fie
prelucrate de o anumită aplicaţie sau să fie afişate. Rezultatul unei
instrucţiuni SELECT, numit şi set de rezultate, este returnat sub forma
unui tabel. Deoarece SQL este un limbaj neprocedural, se specifică
rezultatele pe care le doriţi să le obţineţi, nu şi modul lor de obţinere.
1
Eliminarea duplicatelor se poate realiza folosind clauza
DISTINCT. Dacă nu se specifică parametrul DISTINCT, parametrul ALL
este implicit şi are ca efect afişarea dublurilor.
Simbolul “*” permite selectarea tuturor atributelor din
tabelele asupra cărora se execută cererea. Atributele sau expresiile din
lista clauzei SELECT pot conţine alias-uri, care vor reprezenta numele
câmpurilor respective în cadrul tabelului furnizat ca rezultat de
instrucţiunea SELECT.
Clauza WHERE poate fi folosită pentru a impune anumite
condiţii liniilor din care se vor extrage atributele specificate în clauza
SELECT.
Clauza GROUP BY grupează înregistrările după anumite
câmpuri; în cazul prezenţei acestei clauze, clauza HAVING poate impune
restricţii suplimentare asupra rezultatului final.
Ordonarea înregistrărilor se poate face cu ajutorul clauzei
ORDER BY. Cu ajutoru l p arametrilor ASC şi DESC se p o ate sp ecifica
ordonarea crescătoare, respectiv descrescătoare a înregistrărilor. Pentru o
secvenţă crescătoare valorile null sunt afişate ultimele. Dacă nu se face
nici o specificaţie, atunci ordinea de returnare este la latitudinea server-
ului.
2
Dacă în interiorul alias-ului apare un spaţiu liber sau caractere
speciale, atunci alias-ul trebuie scris între ghilimele.
SELECT dateres–dataim ”numar zile”
FROM imprumuta;
Sortarea rezultatelor
3
FROM FILM
ORDER BY MPAA_RATING_COD, COD_GEN_FILM ;
Observaţie:
Oracle va afişa titlu de coloana la dimensiunea maximă a valorilor
din coloana(de ex. dacă în coloana RATING val cea mai mare este de 5
caractere, interogarea va afişa RATIN). În noua versiune de SQL produs
de Oracle, iSQL*Plus, nu mai prescurtează.
Exemplu :
SELECT titlu, autor, pret, coded as domeniu
from carte
order by coded, autor;
4
Utilizarea clauzei WHERE pentru filtrarea rezultatelor
- Operatori de comparare
- Operatori conjuctivi
- Operatori logici
- Operatori aritmetici
Operatori de comparare
5
Operator Descriere
= Egal cu
< Mai mic decât
<= Mai mic sau egal
> Mai mare decât
>= Mai mare sau egal
!= Diferit de
<> Diferit de (standard ANSI)
6
• Să se obţină titlurile şi numărul de exemplare ale cărţilor care au
nrex>100 ;
SELECT titlu, nrex
FROM carte
WHERE nrex>100;
Operatori conjunctivi
7
• Să se afişeze toate filmele pentru care categoria RATING este PG-
13 sau preţul de vânzare cu amănuntul pentru formatul DVD este
19.99 sau mai mic, în ordinea crescătoare a preţurilor.
Operatori logici
8
IS NULL
Operatorul IS NULL este folosit pentru a determina dacă o valoare
este nulă.
Exemple:
• Să se găsească toate conturile de clienţi active, adică toate conturile
pentru care coloana DATA– TERMINATA conţine o valoare nulă:
SELECT ID_CONT_CLIENT
FROM CONT_CLIENT
WHERE DATA_INCHEIERE IS NULL;
BETWEEN
Operatorul BETWEEN este folosit pentru a determina dacă o
valoare se încadrează într-un interval special. Intervalul este specificat
folosind o valoare minimă şi o valoare maximă, fiind un interval inclusiv,
ceea ce înseamnă că include şi valori specificate.
Exemple:
• Să se afişeze toate filmele cu preţul de vânzare cu amănuntul pentru
formatul DVD între 14.99 şi 19.99, ordonate crescător după preţ.
SELECT TITLU_FILM, PRET_VANZARE_DVD
FORM FILM
WHERE PRER_VANZARE_DVD BETWEEN 14.99 AND 19.99
ORDER BY PRER_VANZARE_DVD;
9
Tabelul DUAL se află în schema SYS şi poate fi accesat de către
toţi utilizatorii. Tabelul este util atunci când se afişează valoarea unei
constante, pseudocoloane sau expresii care nu este construită pe baza
datelor vreunui tabel. În general, tabelul DUAL este utilizat pentru a
completa sintaxa instrucţiunii SELECT, întrucât clauzele SELECT şi
FROM sunt obligatorii.
Să se afişeze data şi ora curentă.
SELECT TO_CHAR(SYSDATE,’DD/MM/YY HH24:MI:SS’)
FROM DUAL;
LIKE
Operatorul LIKE este folosit pentru a compara o valoare de tip
caracter cu un tipar*(pattern), returnând valoarea logică “adevărat” dacă
valoarea de tip caracter se încadrează în tipar şi “fals" în caz contrar.
Pentru definirea tiparului pot fi folosite două caractere de înlocuire:
• Liniuţa de subliniere (_) - Caracterul liniuţă de subliniere poate fi
folosit drept caracter de înlocuire poziţional, ceea ce înseamnă că se
potriveşte cu orice caracter aflat pe poziţia respectivă în şirul de
caractere evaluat.
• Procent (%) - Simbolul procent (%) poate fi folosit drept caracter
de înlocuire nepoziţional, ceea ce înseamnă că se potriveşte cu
orice număr de caractere, indiferent de lungime, reprezentând orice
secvenţă de zero sau mai multe caractere, şi „_“, reprezentând un
singur caracter.
Exemple de tipare:
Tipar Interpretare
Now% Se potriveşte cu orice şir de caractere care incepe cu
„Now".
N_w Se potriveşte cu orice şir de caractere format din
exact trei caractere, care începe cu „N" şi se termină
cu „w".
10
%N -w% Se potriveşte cu orice şir de caractere care conţine
litera „N", urmată de orice alt caracter, urmat de litera
„w" (1a începutul, la sfârşitul sau undeva în mijlocul
şirului de caractere)
%Now% Se potriveşte cu orice şir de caractere care conţine
„Now" (1a inceput, la sfârşit sau în mijloc).
%Now Se potriveşte cu orice şir de caractere care se termină
cu „Now".
Exemple
Să se afişeze cartile ale căror titlu conţine cuvântul „Baza“, sau
pentru care al treilea caracter din autor este „p“.
SELECT titlu, autor
FROM carte
WHERE titlu LIKE '%Baza%' OR autor LIKE '__p%';
11
IN
Operatorul IN este folosit pentru a determina dacă o valoare face
parte dintr-o listă de valori. Lista poate fi specificată ca valori literale,
folosind o listă de valori separate prin virgule şi încadrate între paranteze,
sau poate fi selectată din baza de date folosind o subselecţie (o
subinterogare), care este o interogare în cadrul unei alte interogări.
12
EXISTS
13
Operatori aritmetici
Op Desc
erator riere
+ Adun
are
- Scăd
ere
* Înmu Ca şi în cazul operatorilor
lţire conjunctivi, dacă se amestecă
/ Împă operatorii aritmetici în aceeaşi
rţire instrucţiune SQL fără a folosi
paranteze, ordinea în care sunt
evaluate operaţiile este determinată de prioritatea predefinită. Din fericire,
prioritatea operatorilor din SQL este cea pe care o folosim în operaţiile
matematice obişnuite.
Exemple de utilizare a operatorilor aritmetici:
• Cât v-ar costa să cumpăraţi copiile VHS şi DVD ale filmului The Last
Samurai?
SELECT PRET_VANZARE_VHS + PRET_VANZARE _DVD
AS COST
FROM FILM
WHERE TITLU_FILM = 'The Last Samurai';
• Cât v-ar costa aceeaşi achiziţie dacă aţi avea un bon valoric de 8 ron?
SELECT (PRET_VANZARE _VHS + PRET_VANZARE _DVD) - 8
AS COST
FROM FILM
WHERE TITLU_FILM = 'The Last Samurai';
• Dacă taxele sunt de 8.25% (0.0825), cât reprezintă taxele de vânzare
din costul achiziţiei anterioare?
SELECT (PRET_VANZARE _VHS+ PRET_VANZARE _DVD) *
0.0825 AS TAX
FROM FILM
WHERE TITLU_FILM = 'The Last Samurai';
• Care este costul mediu pentru o copie a filmului The Last Samurai?
SELECT (PRET_VANZARE_VHS+PRET_VANZARE _DVD) / 2
AS AVG_COST
14
FROM FILM
WHERE TITLU_FILM = 'The Last Samurai'
15
SELECT 'Client' || NUME_PERSOANA||
' ' || NUME_FAMILIE_PERSOANA AS SALUT_CLIENT
FROM PERSOANA;
Aceeaşi soluţie, modificată pentru a funcţiona în Microsoft SQL
Server :
SELECT ‚Client' + NUME_PERSOANA +
' ' + NUME_FAMILIE_PERSOANA AS SALUT_CLIENT
FROM PERSOANA;
<nume angajat> castiga <salariu> lunar, dar doreste <salariu de 3
ori mai mare>
SELECT last_name||'castiga'||salary||'lunar, dar doreste'||salary*3 "salariul
ideal"
FROM employees;
UPPER
Funcţia UPPER este deseori folosită în condiţiile WHERE.
Funcţia UPPER transformă literele dintr-un şir de caractere în litere mari.
Numerele şi caracterele speciale sunt lăsate ca stare.
Exemple:
• Să se afişeze comediile (COD_GEN_FILM = 'Comdy') scriind
titlurile cu majuscule.
SELECT UPPER(TITLU_FILM) AS TITLU_FILM
FROM FILM
WHERE COD_GEN_FILM = 'Comdy';
LOWER
Funcţia LOWER este inversa funcţiei UPPER — transformă
literele dintr-un * de caractere în litere mici.
Exemple de utilizare a funcţiei LOWER:
• Să se afişeze comediile (GEN_COD_FILM = 'Comedy') scriind
titlurile cu minuscule.
SELECT LOWER(TITLU_FILM) AS TITLU_FILM
16
FROM FILM
WHERE GEN_COD_FILM = 'Comedy';
SUBSTR
17
LENGTH
Funţii matematice
Funcţiile matematice manipulează valori numerice, în conformitate
cu regulile matematicii.
ROUND
Funcţia ROUND rotunjeşte o valoare la un număr specificat
de zecimale. Valoarea numerică este furnizată prin primul parametru, iar
numărul de zecimale prin cel de-al doilea. În continuare este prezentat
formatul general al funcţiei ROUND.
ROUND (expresie numerică, număr de poziţii zecimale)
• Care este costul mediu al unei copii a filmului The Last Samurai,
rotunjit la două zecimale?
SELECT ROUND((PRET_VANZARE_VHS +
PRET_VANZARE _DVD) / 2, 2) AS AVG_COST
FROM FILM
WHERE TITLU_FILM = 'The Last Samurai';
18
des întâlnite. Pentru toate, sintaxa generală este aceeaşi:
NUME_FUNCTIE (expresie)
Funcţie Descriere
ABS Valoarea absolută a unui număr dat
COS Cosinusul trigonometric al unui unghi specificat în radiani
EXP Valoarea exponenţială a unui număr dat
POWER Ridică un număr la o putere (numărul şi puterea sunt fumizate
ca parametri)
SIN Sinusul trigonometric al unui unghi specificat în radiani
TAN Tangenta trigonometrică a unui unghi specificat în radiani
Funcţii de conversie
Funcţiile de conversie transformă date dintr-un tip de date în altul.
CAST
Funcţia CAST transfo rmă d ate dintr-un tip de date în altul. Iată
sintaxa generală a funcţiei CAST, urmată de un exemplu:
CAST (expresie AS tip de date)
• Afişati preţul pentru formatul DVD al filmului The Last Samurai,
cu un simbol dolar în faţa sumei. Valoarea numerică trebuie să fie
convertită într-un şir de caractere pentru a putea fi concatenată cu o
valoare literală conţinând simbolul dolar.
SELECT '$' || CAST(PRET_VANZARE _DVD AS
VARCHAR(6)) AS PRET
FROM FILM
WHERE TITLU_FILM = 'The Last Samurai';
Funcţie
Descriere
AVG Calculează valoarea medie pentru o coloană sau o
expresie.
COUNT Numără valorile dintr-o coloană.
MAX Găseşte valoarea maxină dintr-o coloană.
MIN Găseşte valoarea minimă dintr-o coloană.
19
SUM Însumează valorile dintr-o coloană.
Exemple:
• Care este preţul mediu al unui DVD?
SELECT ROUND(AVG(PRET_VANZARE _DVD),2) AS
AVG_PRET
FROM FILM;
• Câte filme există în tabelul FILM?
SELECT COUNT(*) AS NUM_FILM
FROM FILM;
• Câte genuri diferite de filme sunt reprezentate în tabelul FILM?
SELECT COUNT(DISTINCT COD_GEN_FILM) AS NUM_GEN
FROM FILM;
• Care sunt lungimea minimă şi maximă a titlurilor filmelor?
SELECT MIN(LENGTH(TITLU_FILM)) AS MIN_LENGTH,
MAX(LENGTH(TITLU_FILM)) AS MAX_LENGTH
FROM FILM;
Clauza GROUP BY
20
care aparţin aceleiaşi partiţii. Numele coloanelor din GROUP BY nu
trebuie să figureze obligatoriu în lista de la SELECT.
Clauza WHERE are prioritate fata de GROUP BY. Nu se poate
utiliza alias de coloana in clauza GROUP BY.
Pentru a returna informatie corespunxatoare fiecarui grup, pot fi
utilizate functiile agregat. Acestea pot aparea in clauzele SELECT,
ORDER BY si HAVING. Se poate utiliza functie grup in clauza WHERE?
Este corect …WHERE AVG(sal) > 200? NU!
Cand se utilizeaza GROUP BY, server-ul sorteaza implicit
multimea rezultata in ordinea crescatoare a valorilor coloanelor dupa care
se realizeaza gruparea.
Grupurile sunt formate si functiile grup sunt calculate, inainte ca
clauza HAVING sa fie aplicata grupurilor.
Exemplu:
Să se obţină numărul de câte ori a fost împrumutată fiecare carte.
SELECT codel, COUNT(*)
FROM imprumuta
GROUP BY codel;
Exemplu:
Pentru fiecare domeniu de carte să se obţină numărul cărţilor din
domeniu, media preţurilor şi numărul total de exemplare.
SELECT coded,COUNT(*), AVG(pret),SUM(nrex)
FROM carte
GROUP BY coded;
Dacă în comanda SELECT apar atribute coloană (nu funcţii grup) şi
se utilizează clauza GROUP BY atunci aceste coloane trebuie obligatoriu
să apară în clauza GROUP BY.
Exemplu:
Să se obţină pentru fiecare autor, media preţurilor cărţilor din
bibliotecă.
SELECT autor, AVG(pret)
FROM carte
GROUP BY autor;
Exemplu:
Pentru departamentele în care salariul maxim depăşeşte 5000$ să
se obţină codul acestor departamente şi salariul maxim pe departament.
SELECT deptno, MAX(sal)
FROM emp
GROUP BY deptno
HAVING MAX(sal)>5000;
21
Exemplu:
SELECT MAX(AVG(pret))
FROM carte
GROUP BY autor;
Exemplu:
Să se afişeze numele şi salariul celor mai prost plătiţi angajaţi
din fiecare departament.
SELECT ename, sal
FROM emp
WHERE (deptno, sal) IN
(SELECT deptno, MIN(sal)
FROM emp
GROUP BY deptno);
Exemplu:
Să se obţină pentru fiecare carte, codul său şi numărul de
exemplare care nu au fost încă restituite.
SELECT codel, COUNT(*)
FROM imprumuta
WHERE dataef IS NULL
GROUP BY codel;
Exemplu:
Să se obţină numărul cărţilor împrumutate cel puţin o dată.
SELECT COUNT(DISTINCT codel)
FROM imprumuta;
Exemplu:
Să se afişeze numărul cărţilor împrumutate cel puţin de două ori
(pentru fiecare carte împrumutată mai mult decât o dată să se obţină
numărul de câte ori a fost împrumutată).
SELECT COUNT(COUNT(codel))
FROM imprumuta
GROUP BY codel
HAVING COUNT(*)>1;
22
În cererea anterioară COUNT(codel), reprezintă numărul care arată
de câte ori a fost împrumutată fiecare carte, iar COUNT(COUNT(codel)),
reprezintă numărul total al cărţilor împrumutate.
Exemplu:
Pentru fiecare departament codul dep si numarul de angajati.
1 select department_id, count(*)
2 from employees
3* group by department_id
SQL> /
DEPARTMENT_ID COUNT(*)
------------- ----------
10 1
20 2
30 6
40 1
50 45
60 5
70 1
80 34
90 3
100 6
110 2
1
12 rows selected.
Pentru departamentele cu mai mult de un angajat se afiseaza codul dep si
numarul de angajati.
1 select department_id, coun
2 from employees
3 group by department_id
4* having count(*)>1
SQL> /
DEPARTMENT_ID COUNT(*)
------------- ----------
20 2
30 6
50 45
60 5
80 34
23
90 3
100 6
110 2
8 rows selected.
Se afiseaza numarul departamentelor cu mai mult de un angajat.
1 select count(count(*))
2 from employees
3 group by department_id
4* having count(*)>1
SQL> /
COUNT(COUNT(*))
---------------
8
Exemplu:
Sa se afiseze numărul de cărţi imprumutate din fiecare domeniu.
SELECT d.intdom, COUNT(*)
FROM domeniu d, carte c, imprumuta I
WHERE c.codel = i. codel
AND c.coded = d.coded
GROUP BY intdom;
Exemplu:
Lista codurilor cititorilor care au mai mult de 3 cărţi nerestituite la
termen.
SELECT codec
FROM imprumuta
WHERE dataef IS NULL AND datares < SYSDATE
GROUP BY codec
HAVING COUNT(*) > 2;
Exemplu:
Pentru fiecare domeniu de carte care conţine cel puţin o carte şi
unde preţul oricărei cărţi nu depăşeşte o valoare dată, să se obţină: codul
domeniului, numărul cărţilor din domeniu şi numărul mediu de
exemplare.
SELECT coded, COUNT(*), AVG(nrex)
24
FROM carte
GROUP BY coded
HAVING COUNT(*) >= 1
AND MAX(pret) < &pret_dat;
Exemplu:
Codurile domeniilor care nu contin carti.
SELECT coded
FROM carte
GROUP BY coded
HAVING COUNT(*) = 0;
Nu este corect, deoarece se iau in considerare NUMAI codurile
domeniilor care apar in tabelul CARTE.
SELECT intdom
FROM domeniu d
WHERE 0 = (SELECT COUNT(*)
FROM carte
WHERE coded = d.coded);
Urmatoarea cerere este corecta?
SELECT intdom
FROM domeniu d,(SELECT coded, COUNT(*) a
FROM carte
GROUP BY coded) b
WHERE b.coded = d.coded)
AND b.a = o;
Exemplu:
În ce interogări este necesară utilizarea cuvântului cheie
HAVING?
A. când este necesar să eliminăm linii duble din rezultat;
B. când este necesar să ordonăm mulţimea rezultat;
C. când este necesar să efectuăm un calcul pe grup;
D. când este necesar să restricţionăm grupurile de linii returnate.
UNION
Operatorul UNION adaugă rândurile din setul de înregistrări al
25
unei interogări la cel al unei alte inregistrări şi, în acelaşi timp, elimină
rândurile duplicate, într-un mod similar cu cel al cuvântului cheie
DISTINCT. Operaţia este permisă numai dacă interogările sunt
compatibile din punctul de vedere al uniunii, ceea ce înseamnă că au
acelaşi număr de coloane şi că tipurile de date ale coloanelor
corespondente sunt compatibile.
Iată un exemplu:
• Afişaţi pe o singură coloană toate valorile nenule pentru taxa de
inchiriere şi taxa de întârziere din tabelul FILM_ÎNCHIRIAT.
SELECT INCHIRIAT_FEE AS FEE
FROM FILM_INCHIRIAT
WHERE INCHIRIAT _FEE IS NOT NULL
UNION
SELECT LATE_OR_LOSS_FEE AS FEE
FROM FILM_INCHIRIAT
WHERE LATE _OR_ LOSS FEE IS NOT NULL;
UNION ALL
UNION ALL funcţionează la fel ca şi operatorul UNION,
exceptând faptul că rândurile duplicate nu sunt eliminate.
INTERSECT
Operatorul INTERSECT găseşte valorile selectate dintr-o
interogare, care apar şi într-o altă interogare. În esenţă, găseşte intersecţia
valorilor din cele două interogări. Totuşi, doar un număr mic de sisteme
DBMS (cele mai importance fiind Oracle şi DB2) implementează acest
operator. Nu-1 veţi găsi în Microsoft SQL Server sau MySQL.
Iată un exemplu:
• Există în tabelul FILM filme pentru care preţul pentru DVD este
egal cu preţul pentru VHS?
SELECT INCHIRIAT_FEE AS FEE
FROM FILM_ INCHIRIAT
WHERE INCHIRIAT _FEE IS NOT NULL
INTERSECT
SELECT LATE_OR_LOSS_FEE AS FEE
FROM FILM_ INCHIRIAT
WHERE LATE OR_ LOSS FEE IS NOT NULL
26
EXCEPT
EXCEPT este operatorul standard ANSI/ISO care găseşte
diferenţele dintre două seturi de rezultate, returnând, în esenţă, valorile
din prima interogare care nu apar în cea de-a doua interogare. Foarte
puţine sisteme DBMS implementează acest operator. În unele
implementări, precum Oracle, operatorul se numeşte MINUS, nu
EXCEPT.
27