Documente Academic
Documente Profesional
Documente Cultură
Curs SQL
Curs SQL
Majoritatea componentelor unei declaraii SQL sunt insensibile la litere mari sau mici. O excepie important de la aceast regul este faptul c datele caractere literale trebuiesc scrise exact cum apar n baza de date. De exemplu dac scriem numele unei persoane MARIN i apoi cutm numele folosind Marin articolul nu va fi gsit. Dei SQL este de liber format, o declaraie SQL sau un set de declaraii este mult mai interesant dac este folosit alinierea. De exemplu: Fiecare clauz din declaraie ar trebui scris pe linie nou. nceputul fiecrei clauze ar trebui scris sub nceputul altei clauze. Dac o clauz are mai multe pri ele ar trebui s apar pe linii separate i s fie inclus la nceputul clauzei pentru a arta relaia dintre ele. n acest capitol vom folosi urmtoarea modalitate pentru a defini declaraiile SQL: Literele mari sunt folosite n reprezentarea cuvintelor rezervate i trebuiesc scrise exact. Literele mici sunt folosite n reprezentarea cuvintelor definite de ctre utilizator. | indic o alegere ntre alternative; de exemplu a | b | c. Parantezele acolade indic un element dorit: de exemplu, {a}. Parantezele ptrate indic un element opional: de exemplu, [a]. Punctele () sunt folosite pentru a indica repetiia opional a unui element nul sau a unui alt element de mai multe ori. De exemplu: {a|b}[,c], ceea ce nseamn a sau b urmat de zero sau mai multe repetiii al lui c separate prin virgul. n practic declaraiile LDD sunt folosite pentru crearea de structuri de baze de date (tabele), iar declaraiile LMD pentru a popula i interoga tabelele. n acest capitol vom prezenta declaraiile LMD naintea celor LDD pentru a arta importana relativ a declaraiilor LMD.
vechime 15 20 25 25 28 18
cod_gr 1 2 1 1 2 1
nr_semigrupe 2 2 1 2 1 2
nr_studeni 25 24 30 28 24 29
1. Recuperarea tuturor liniilor unui tabel: SELECT nr_mat, nume, prenume, funcia, vechime, salariu FROM cadre_didactice; SELECT * FROM cadre_didactice;
Obinem n urma acestor dou interogri acelai rezultat: nr_mat 1111 1112 1113 1114 1115 1116 nume Popa Liana Barbu tefan Savu Ionescu prenume Ioan Carmen Traian Elena Alexandru Mircea funcia lect. conf. conf. conf. conf. lect. vechime 15 20 25 25 28 18 salariu 400,000 700,000 900,000 900,000 950,000 400,000
SELECT nr_mat, nume, prenume, salariu FROM cadre_didactice; nr_mat 1111 1112 1113 1114 1115 1116 nume Popa Liana Barbu tefan Savu Ionescu prenume Ioan Carmen Traian Elena Alexandru Mircea salariu 400,000 700,000 900,000 900,000 950,000 400,000
3. Utilizarea cuvntului rezervat DISTINCT care elimin liniile duble: SELECT salariu FROM cadre_didactice; salariu 400,000 700,000 900,000 900,000 950,000 400,000 SELECT DISTINCT salariu FROM cadre_didactice; salariu 400,000 700,000 900,000 950,000
4.
Exemplele de mai sus arat folosirea declaraiei SELECT pentru a recupera toate liniile dintr-un tabel. Totui, deseori avem nevoie de a restrnge liniile care au fost recuperate. Acest lucru se poate realiza cu clauza WHERE care conine cuvntul cheie urmat de o condiie de cutare care specific liniile ce trebuiesc recuperate. n SQL avem urmtoarii operatori de comparaie: =, <, >, <=, >=, < >, != (diferit). Multe predicate complexe pot fi generate folosind operatori logici AND, OR, i NOT, cu paranteze sau nu, pentru a arta ordinea de valoare. Regulile pentru evaluarea expresiilor condiionate sunt: O expresie evaluat de la stnga la dreapta. Subexpresiile n paranteze sunt evaluate prima dat. Operatorii NOT sunt evaluai naintea operatorilor AND i OR. Operatorii AND sunt evaluai naintea celor OR. Folosirea parantezelor este ntotdeauna recomandat pentru a elimina posibilile ambiguiti. Cele 5 condiii principale de cutare sunt urmtoarele: 1. Comparaia. Compar valorile unei expresii cu valorile altei expresii: SELECT nr_mat, nume, prenume, salariu FROM cadre_didactice WHERE salariu >700.000; 4
2. ir. Testeaz dac valoarea unei expresii este inclus ntr-un ir de valori specificate (BETWEEN/NOT BETWEEN):
SELECT nr_mat, nume, prenume, salariu FROM cadre_didactice WHERE salariu BETWEEN 500.000 AND 900.000; nr_mat nume 1112 Liana 1113 Barbu 1114 tefan
3. Apartenena la o mulime. Testeaz dac valoarea unei expresii aparine unui set de valori (IN/NOT IN): SELECT nr_mat, nume, prenume, vechime FROM cadre_didactice WHERE vechime IN (20, 25); nr_mat 1112 1113 1114 nume Liana Barbu tefan prenume Carmen Traian Elena vechime 20 25 25
4. Compatibilitatea. Testeaz dac un ir se potrivete cu un model specificat (LIKE/NOT LIKE). SQL are dou caractere speciale: % reprezint orice secven de zero sau de mai multe caractere; _ reprezint orice caracter singular. Celelalte caractere se folosesc normal. De exemplu: adresa LIKE H% nseamn c primul caracter trebuie s fie H, iar celelalte pot fi orice caracter. adresa LIKE H_ _ _ nseamn c trebuie s fie exact patru caractere n ir primul fiind H. adresa LIKE %e nseamn orice secven de caractere de lungime cel puin 1 cu ultimul caracter e. adresa LIKE %Popescu% nseamn o secven de caractere de orice lungime care conine Popescu. adresa NOT LIKE H% nseamn c numele nu poate ncepe cu H. SELECT nr_mat, nume, prenume FROM cadre_didactice WHERE nume LIKE P%; nr_mat 1111 (1 linie) nume Popa prenume Ioan
5. Nul. Testeaz dac o coloan are o valoare nul (necunoscut) (IS NULL/IS NOT NULL). Clauza ORDER BY (rezultate de sortare) n general, liniile tabelului rezultat a unei interogari SQL nu sunt aranjate ntr-o anumit ordine. Totui, putem sorta rezultatele unei interogri folosind clauza ORDER BY din declaraia SELECT. Clauza ORDER BY conine o list de identificatori de coloan pentru ca rezultatul s fie sortat i separat prin virgul. Identificatorul de coloan poate fi, fie un nume de coloan, fie un numr de coloan care identific un element din lista SELECT dndu-ne poziia acestuia n list:1 pentru primul element din list, 2 pentru al doilea, .a.m.d. Numerele de coloan pot fi folosite dac coloana ce trebuie sortat este o expresie i nici o clauz AS nu este specificat n vederea atari unui nume pentru coloan, nume care ar putea fi de referin ulterior. Clauza ORDER BY ne permite ordonarea articolelor recuperate n mod cresctor (ASC) sau descresctor (DESC) pe orice coloan sau combinaie de coloane indiferent dac coloana apare sau nu n rezultat.Totui, unele dialecte 5
insist asupra faptului ca elementele ORDER BY s apara n lista SELECT. n ambele cazuri, clauza ORDER BY trebuie s fie ntotdeauna ultima n declaraia SELECT. SELECT nr_mat, nume, prenume, salariu FROM cadre_didactice ORDER BY salariu DESC; nr_mat 1115 1113 1114 1112 1111 1116 nume Savu Barbu tefan Liana Popa Ionescu prenume Alexandru Traian Elena Carmen Ioan Mircea salariu 950,000 900,000 900,000 700,000 400,000 400,000
Este posibil de a include mai multe elemente n clauza ORDER BY. Cheia de sortare major determin ordinea general a tabelului rezultat. Dac cheia de sortare major este unic, nu mai este nevoie de nici o cheie de control pentru sortare. Totui, dac cheia de sortare major nu este unic, ar putea s existe mai multe linii din tabelul rezultat cu aceeai valoare pentru cheia de sortare major. n acest caz, ar fi de dorit s se ordoneze liniile cu aceeai valoare pentru cheia de sortare major cu ajutorul unei chei de sortare adiional. Dac apare un al doilea element n clauza ORDER BY, atunci acesta se numete cheie de sortare minor. SELECT nr_mat, nume, prenume, funcia, salariu FROM cadre_didactice ORDER BY funcia, salariu DESC; nr_mat 1111 1116 1115 1113 1114 1112 nume Popa Ionescu Savu Barbu tefan Liana prenume Ioan Mircea Alexandru Traian Elena Carmen funcia lect. lect. conf. conf. conf. conf. salariu 400,000 400,000 950,000 900,000 900,000 700,000
Standardul ISO specific faptul c zerourile dintr-o coloan sau expresie sortat cu ORDER BY trebuiesc tratate mai puin sau mai mult dect toate valorile nenule. Acest lucru rmne la alegerea implementorului SGBD. Folosirea funciilor complexe SQL Standardul ISO definete 5 functii complexe: COUNT returneaz numarul de valori dintr-o coloan specificat. SUM returneaz suma valorilor dintr-o coloan specificat. AVG returneaz media valorilor dintr-o coloan specificat. MIN returneaz cea mai mic valoare dintr-o coloan specificat. MAX returneaz cea mai mare valoare dintr-o coloan specificat. Aceste funcii opereaz pe o singur coloan a tabelului i returneaz o singur valoare. COUNT, MIN, MAX se aplic att pe cmpuri numerice ct i pe cmpuri nenumerice, iar SUM i AVG pot fi folosite numai pe cmpuri numerice. n afar de COUNT(*), fiecare funcie elimin prima dat zerourile i opereaz pe cele care au rmas cu valoare nenul. COUNT(*) este o folosire special a lui COUNT. Scopul ei este de a numra liniile unui tabel indiferent dac conin sau nu zerouri sau valori duble. Dac dorim s eliminm dublurile nainte de a aplica funcia, trebuie s folosim cuvntul cheie DISTINCT nainte de numele de coloan din funcie. Standardul ISO permite specificarea cuvntului cheie ALL, dac nu dorim eliminarea dublurilor, dei ALL este presupus dac nu se specific nimic. DISTINCT nu are nici un efect asupra funciilor MIN i MAX. Totui, poate avea un efect asupra rezultatelor date de SUM sau AVG, de aceea trebuie pus n vedere dac dublurile trebuiesc incluse sau nu n operaie. Ca o adugare, DISTINCT poate fi specificat o singur dat n interogare. Este important faptul c funciile complexe pot fi folosite numai n lista SELECT i n clauza HAVING. Este incorect folosirea lor n alt parte. Dac lista SELECT include o funcie complex i dac nu a fost folosit clauza GROUP BY pentru gruparea datelor, atunci nici un element din lista SELECT nu poate conine referine la o coloan numai dac acea coloan este un argument a unei funcii complexe. De exemplu, interogarea urmtoare este incorect: 6
SELECT nr_mat, COUNT(salariu) FROM cadre_didactice; deoarece lista SELECT conine att un nume de coloan (nr_mat) ct i o funcie complex separat (COUNT), fr a fi folosit o clauz GROUP BY. Exemple: 1. Utilizarea funciei COUNT(*): SELECT COUNT(*) AS contor FROM cadre_didactice WHERE salariu >400,000; contor 4
2.
SELECT COUNT(DISTINCT salariu) AS contor FROM cadre_didactice WHERE salariu BETWEEN 500,000 AND 950,000; contor 3
3.
SELECT COUNT(nr_mat) AS contor, SUM(salariu) AS total_sal FROM cadre_didactice WHERE funcia=conf.; contor 4 total_sal 4,450,000
4. Utilizarea funciilor MIN, MAX, AVG: SELECT MIN(salariu) AS min, MAX(salariu) AS max, AVG(salariu) AS media FROM cadre_didactice;
min 400,000
max 950,000
media 708,333.3
Clauza GROUP BY (rezultate de grupare) Interogrile sumare de mai sus sunt similare cu totalele de la sfritul raportului. Se condenseaz toate datele din raport ntr-o singur linie sumar de date. Totui, este deseori folositor de a avea subtotale n raport. Pentru aceasta putem folosi clauza GROUP BY din declaraia SELECT. O interogare care cuprinde clauza GROUP BY se numete interogare grupat, deoarece grupeaz datele din tabelele SELECT i creaz o singur linie pentru fiecare grup. Coloanele numite n clauza GROUP BY se numesc coloane de grupare. Standardul ISO cere ca clauzele SELECT i GROUP BY s fie strns integrate.Cnd se folosete GROUP BY, fiecare element din lista SELECT trebuie s aib valoare unic pe grup. n plus, clauza SELECT poate s conin numai: nume de coloan, funcii complexe, constante, o expresie cuprinznd combinaii ale elementelor de mai sus. Toate numele de coloan din lista SELECT trebuie s apar n clauza GROUP BY, n afar de cazul cnd numele este folosit numai ntr-o funcie complex. Reciproca nu este adevrat: pot s existe nume de coloane n clauza GROUP BY care nu apar n lista SELECT. Cnd clauza WHERE este folosit cu GROUP BY, prima dat este apelat clauza WHERE, apoi grupurile sunt formate din liniile rmase ceea ce satisface condiia de cutare.
Standardul ISO consider dou zerouri ca fiind egale pentru scopurile clauzei GROUP BY. Dac dou linii au zerouri n aceeai coloan de grupare i valori identice n toate coloanele de grupare nenule, ele sunt combinate n acelai grup. Exemplu: SELECT funcia, COUNT(nr_mat) AS contor, SUM(salariu) AS total_sal FROM cadre_didactice GROUP BY funcia ORDER BY funcia; funcia lect. conf. contor 2 4 total_sal 800,000 3,450,000
1. SQL divide schema n grupuri innd seama de cmpul funcia. n cadrul fiecrui grup, toate cadrele didactice au aceai funcie. 2. Pentru fiecare grup, SQL calculeaz numrul membrilor schemei i adun valorile n coloana salariu pentru a obine totalul salariilor. SQL genereaz o singur linie sumar n rezultatul interogrii pentru fiecare grup. 3. n final, rezultatul este sortat n ordinea cresctoare dup cmpul funcia.
Clauza HAVING (restrngerea grupurilor) Clauza HAVING este folosit mpreun cu clauza GROUP BY pentru a restrnge grupurile care apar la finalul tabelului rezultat. Dei sunt similare n sintax, HAVING i WHERE servesc scopuri diferite. Clauza WHERE strecoar linii individuale n finalul tabelului rezultat, iar HAVING strecoar grupuri n finalul tabelului rezultat. Standardul ISO cere ca numele coloan folosite n clauza HAVING s apar, deasemenea, n lista GROUP BY sau s fie coninute ntr-o funcie complex. n practic, condiia de cutare din clauza HAVING include ntotdeauna cel puin o funcie complex, altfel condiia de cutare ar putea fi mutat n clauza WHERE i aplicat pe linii individuale. Clauza HAVING nu este parte important a SQL, orice interogare exprimat folosind clauza HAVING poate fi rescris ntotdeauna fr clauza HAVING. Exemplu: SELECT funcia, COUNT(nr_mat) AS contor, SUM(salariu) AS total_sal FROM cadre_didactice GROUP BY funcia HAVING COUNT(nr_mat)>2 ORDER BY funcia; funcia conf. Subinterogri Unele declaraii SQL pot avea o declaraie SELECT complet ncrustat n interiorul lor. Rezultatele acestei declaraii SELECT interioare (sau subselect) sunt folosite n declaraiile exterioare pentru a ajuta la determinarea coninutului rezultatului final. Un subselect poate fi folosit n clauzele WHERE i HAVING a unei declaraii SELECT exterioare, unde acesta este numit subinterogare sau interogare intercalat. Subselectele pot aprea, de asemenea, n declaraiile INSERT, UPDATE i DELETE. contor 4 total_sal 3,450,000
Exemplu: SELECT cod_gr, nr_semigrupe, nr_studeni FROM grupe WHERE cod_sec = (SELECT cod_sec FROM secii WHERE denumire = Matematica); cod_gr 1 nr_semigrupe 2 nr_studeni 25 8
24
Subinterogarea poate fi privit ca productorul unor tabele temporare de rezultate, care pot fi accesate i folosite de ctre declaraii exterioare. O subinterogare poate fi folosit imediat dup un operator relaional (=,< , >, <=, >=, < >) ntr-o clauz WHERE sau HAVING. Subinterogarea nsi este ntodeauna nchis ntre paranteze. Asupra subinterogrilor se aplic urmtoarele reguli: 1) Clauza ORDER BY nu poate fi folosit ntr-o subinterogare (dei ea poate fi folosit n majoritatea declaraiilor SELECT exterioare. 2) Lista subinterogrilor SELECT trebuie s conin un singur nume coloan sau o singur expresie, excepie fcnd subinerogrile care folosesc cuvntul cheie EXISTS. 3) Deoarece lipsesc, numele coloan dintr-o subinterogare se refer la numele tabel din clauza FROM a subinterogrii. Este posibil s se recurg la un tabel dintr-o clauz FROM a unei interogri exterioare n modificarea numelui coloan. 4) Cnd o subinterogare este una din cei doi operani implicai ntr-o comparaie, subinterogarea trebuie s apar n partea dreapt a comparaiei. 5) O subinterogare nu poate fi folosit ca operant ntr-o expresie. Folosirea cuvintelor rezervate ANY i ALL Cuvintele ANY i ALL pot fi folosite cu subinterogri care produc o singur coloan a numerelor. Dac subinterogarea este precedat de cuvntul cheie ALL, condiia va fi adevrat numai dac este satisfcut de toate valorile date de subinterogare. Dac subinterogarea este precedat de cuvntul cheie ANY, condiia va fi adevrat dac este satisfcut de orice (una sau mai multe) valoare dat de subinterogare. Dac subinterogarea este vid, condiia ALL returneaz valoarea adevrat, iar condiia ANY returneaz valoarea fals. Standardul ISO permite folosirea calificativului SOME n locul lui ANY. Exemple:
1. Utilizarea cuvntului rezervat ANY: SELECT nume, prenume, salariu FROM cadre_didactice WHERE salariu > ANY (SELECT salariu FROM cadre_didactice WHERE funcia =conf);
nume Savu Barbu tefan prenume Alexandru Traian Elena salariu 950,000 900,000 900,000
2. Utilizarea cuvntului rezervat ALL: SELECT nume, prenume, salariu FROM cadre_didactice WHERE salariu => ALL (SELECT salariu FROM cadre_didactice WHERE funcia =conf.); nume prenume Savu Alexandru Interogri multi-tabele
salariu 950,000
Toate exemplele considerate pn acum au o limitare major: toate coloanele ce trebuie s apar n tabelele rezultat trebuie s provin dintr-un singur tabel. n multe cazuri, acest lucru nu este suficient. Pentru a combina coloanele din mai multe tabele n obinerea unui tabel rezultat, avem nevoie de o operaie de jonciune. Operaia de jonciune SQL combin informaia din dou tabele formnd perechi de linii nrudite din cele dou tabele. Perechile de linii ce alctuiesc tabelul asociat sunt toate acolo unde coloanele corespunztoare din cele dou tabele au aceeai valoare. Dac avem nevoie s obinem informaii din mai multe tabele, putem alege ntre folosirea unei subinterogri i a unei jonciuni. Dac tabelul rezultat final trebuie s conin coloane din diferite tabele, atunci trebuie s folosim jonciunea. Pentru a reui operaia de jonciune, trebuie doar s includem mai multe nume de tabele n clauza FROM, folosind ca separator virgula i incuznd clauza WHERE pentru a specifica coloanele jonciunii. De asemenea, este posibil s folosim alias pentru un tabel specificat n clauza FROM. n acest caz, aliasul este 9
separat de numele tabelului printr-un spaiu. Un alias poate fi folosit pentru a modifica numele coloan ori de cte ori exist ambiguiti privind sursa numelui coloan. De asemenea, se mai poate folosi ca o notaie pentru numele tabelului. Dac un alias este specificat, trebuie folosit oriunde numele tabelului ar putea fi specificat. Jonciunea este o submulime a unei combinaii mult mai generale a dou tabele cunoscute cum ar fi produsul cartezian a dou tabele. Produsul cartezian a doua tabele este un alt tabel alctuit din toate perechile posibile de linii din cele doua tabele. Coloanele tabelului produs sunt toate coloanele primului tabel urmat de toate coloanele celui de al doilea tabel. Dac specificm o interogare doi-tabel fr clauza WHERE, SQL produce produsul cartezian al celor dou tabele ca fiind interogarea rezultat. Procedura pentru generarea rezultatelor unui SELECT cu o asociere este: 1. Se formeaz produsul cartezian a tabelelor numite n clauza FROM. 2. Dac exist o clauz WHERE, se aplic condiia de cutare fiecrei linii a tabelului produs, reinnd acele linii care satisfac condiia. n termenii algebrei relaionale, aceast operaie produce o restricie a produsului cartezian. 3. Pentru fiecare linie rmas, se determin valoarea fiecrui element din lista SELECT n scopul producerii unei singure linii n tabelul rezultat. 4. Dac SELECT DISTiNCT a fost specificat, se elimin orice linie dubl din tabelul rezultat. n algebra relaional, pasul 3 i 4 sunt echivalente cu o proiecie a restriciei asupra coloanelor menionate n lista SELECT. 5. Dac exist o clauza ORDER BY, se sorteaz n modul cerut tabelul rezultat. Exemple: SELECT s.denumire, s.iniiale, g.cod_gr, g.nr_semigrupe, g.nr_studeni FROM secii s, grupe g WHERE s.cod_sec = g.cod_sec denumire Matematic Matematic Informatic Matematic-fizic Matematic-fizic Fizic-chimie iniiale M M I MF MF FC cod_gr 1 2 1 1 2 1 nr_semigrupe 2 2 1 2 1 2 nr_studeni 25 24 30 28 24 29
Cele mai comune interogri muti-tabel implic dou tabele care au o relaie 1:M (sau tat/fiu). Interogarea precedent este o astfel de interogare. Fiecare fiu are un tat asociat i fiecare printe are asociai mai multi fii. Perechile de linii care genereaz interogarea rezultat sunt combinaii de linii tat/fiu. Tabelul care conine cheia strin este un tabel fiu, iar tabelul care conine cheia fundamental este un tabel tat. Pentru a folosi relaia tat/fiu ntr-o interogare SQL, vom specifica o condiie de cutare care compar cheia strin cu cheia fundamental. n exemplul de mai sus se face o astfel de comparaie. Standardul SQL2 furnizeaz urmtoarele moduri alternative pentru a specifica aceast asociere: FROM secii s JOIN grupe g ON s.cod_sec=g.cod_sec FROM secii JOIN grupe USING cod_sec FROM secii NATURAL JOIN grupe n fiecare caz, clauza FROM nlocuiete clauzele originale FROM i WHERE. Jonciuni externe Operaia de jonciune combin datele din dou tabele formnd perechi de linii specificate, unde coloanele corespunztoare din fiecare tabel au aceeai valoare. Dac o linie a tabelului este fr pereche, linia este omis din tabelul rezultat. Acesta a fost cazul pentru jonciunile examinate mai sus. Standardul ISO furnizeaz un alt set de operatori de jonciune numii jonciuni externe. Jonciunea extern reine liniile care nu satisfac condiia de jonciune. Exist trei tipuri de jonciuni externe:
1. jonciune extern stng: SELECT o.*, m.* FROM orae o LEFT JOIN municipii m ON o.denumire = m.denum_m;
cod O1 O2 O3 denumire Braov Codlea Timioara cod_m M3 NULL M1 denum_m Braov NULL Timioara 10
2. jonciune extern dreapt: SELECT o.*, m.* FROM orae o RIGHT JOIN municipii m ON o.denumire = m.denum_m; cod O3 NULL O1 denumire Timioara NULL Braov cod_m M1 M2 M3 denum_m Timioara Iai Braov
3. jonciune extern total: SELECT o.*, m.* FROM orae o FULL JOIN municipii m ON o.denumire = m.denum_m; cod O3 NULL O2 O1 EXISTS i NOT EXISTS Cuvintele cheie EXISTS i NOT EXISTS se folosesc numai cu subinterogri. Ele produc un rezultat simplu adevrat/fals. EXISTS este adevrat dac i numai dac exist cel puin o linie n tabelul rezultat returnat de ctre interogare i este fals dac subinterogarea returneaz un tabel rezultat vid. NOT EXISTS este opusul lui EXISTS. n timp ce EXISTS i NOT EXISTS verific numai existena sau inexistena liniilor n tabelul rezultat al subinterogrii, subinterogarea poate conine orice numr de coloane. Pentru simplificare, subinterogarea urmnd una din aceste cuvinte cheie este de obicei de forma: (SELECT*). Exemplu: SELECT cod_gr, nr_semigrupe, nr_studeni FROM grupe g WHERE EXISTS (SELECT * FROM secii s WHERE g.cod_sec = s.cod_sec AND iniiale=M ); cod_gr 1 2 nr_semigrupe 2 2 nr_studeni 25 24 denumire Timioara NULL Codlea Braov cod_m M1 M2 NULL M3 denum_m Timioara Iai NULL Braov
Combinarea tabelelor rezultat (UNION, INTERSECT, EXCEPT) n SQL, putem folosi operaiile normale cu mulimi: reuniune, intersecia i diferena, pentru a combina rezultatele a dou sau mai multe interogri ntr-un singur tabel rezultat. Reuniunea a dou tabele, A i B, este un tabel ce conine toate liniile care sunt att n tabelul A ct i n B. Intersecia a dou tabele, A i B este un tabel ce conine toate liniile comune celor dou tabele. Diferena a dou tabele, A i B, este un tabel ce conine toate liniile care sunt n A, dar nu sunt n B. Exist restricii asupra tabelelor care pot fi combinate folosind operaiile cu mulimi. Cea mai important restricie este c cele dou tabele sunt compatibile (prin asociere), adic ele au aceai structur. Aceasta implic faptul c cele dou tabele trebuie s conin acelai numar de coloane i c, coloanele lor corespunztoare s aib aceleai tipuri i lungimi de date. Este responsabilitatea utilizatorului de a se asigura c valorile datelor n coloanele corespunztoare provin din acelai domeniu. De exemplu, ar fi fr sens s combinm o coloan care conine vrsta personalului cu numrul camerelor dintr-o proprietate, chiar dac ambele coloane ar putea avea acelai tip de dat: de exemplu, SMALLINT. Cei trei operatori de mulimi sunt numii, n standardul ISO, UNION, INTERSECT i EXCEPT. Formatul clauzei operatorului de mulimi este, n fiecare caz: operator [ALL][CORRESPONDING [BY {coloan [,]}]] Dac CORRESPONDING BY este specificat, atunci operaia cu mulimi este realizat prin coloana (coloanele) specificate. Dac CORRESPONDING este specificat dar fr clauza BY, operaia cu mulimi este realizat prin coloanele care sunt comune ambelor tabele. Dac ALL este specificat, rezultatul poate include linii duble. 11
Unele dialecte ale SQL nu accept INTERSECT i EXCEPT, altele folosesc MINUS n locul lui EXCEPT. Exemple: 1. Utilizarea operatorului UNION: (SELECT denumire AS orae FROM orae WHERE denumire IS NOT NULL) UNION (SELECT denum_m AS orae FROM municipii WHERE denum_m IS NOT NULL) orae Braov Codlea Timioara Iai 2. Utilizarea operatorului INTERSECT: (SELECT denumire AS orae FROM orae) INTERSECT (SELECT denum_m AS orae FROM municipii) orae Braov Timioara
3.
(SELECT denumire AS orae FROM orae) EXEPT (SELECT denum_m FROM municipii); orae Codlea
care opiunea DEFAULT nu a fost folosit cnd s-a creat coloana. Lista_valoare_dat trebuie s se potriveasc cu lista coloan dup cum urmeaz : Numrul elementelor din ambele liste trebuie s fie acelai Trebuie s fie o corespondent direct ntre poziia elementelor din ambele liste, astfel nct primul element din lista_valoare_dat corespunde primului element din lista_coloan, al doilea element din lista_valoare_dat corespunde celui de-al doilea element din lista_coloan, .a.m.d. Tipul datei fiecrui element din lista_valoare_dat trebuie s fie compatibil cu tipul datei coloanei corespunztoare. Exemplu: INSERT INTO orae VALUES (O5, Deva); A doua form a declaraiei INSERT permite copierea mai multor linii din una sau mai multe tabele n altele. Formatul este: INSERT INTO nume_tabel [(lista_coloan)] SELECT Nume_tabel i lista_coloan sunt definite ca mai sus n cazul ncasrii unei singure linii. Clauza SELECT poate fi orice declaraie valabil SELECT. Liniile inserate n tabelul specificat sunt identice cu cele din tabelul rezultat produs de subselect. Aceleai restricii aplicate primei forme a declaraiei INSERT se aplic i aici. Exemplu: INSERT INTO orae (SELECT cod_m, denum_m FROM municipii); Modificarea datei n baza de date (UPDATE) Declaraia UPDATE permite schimbarea coninutului liniilor existente dintr-un tabel specificat. Formatul comenzii este: UPDATE nume_tabel SET nume_coloan 1=valoare_dat 1[, nume_coloan 2= valoare_dat 2] [WHERE condiie_cutare] Nume_tabel poate fi numele unui tabel de baz sau un view actualizabil. Clauza SET specific numele unei sau mai multor coloane care urmeaz s fie actualizate. Clauza WHERE este opional. Dac este omis, coloana specificat este actualizat pentru toate liniile din tabel. Dac clauza WHERE este specificat, numai acele linii care satisfac condiia_cutare sunt actualizate. Noile valoare_dat trebuie s fie compatibile cu tipul de dat pentru coloana corespunztoare. Exemplu: UPDATE cadre_didactice SET funcia =conf. WHERE funcia=lect.; tergerea datei din baza de date (DELETE) Declaraia DELETE permite tergerea liniilor dintr-un tabel specificat. Formatul comenzii este: DELETE FROM nume_tabel [WHERE condiia_cutare] Ca i n declaraiile INSERT i UPDATE, nume_tabel poate fi numele unui tabel de baz i un view actualizabil. Condiia_cutare este opional, dac este omis, toate liniile sunt terse din tabel. Acesta nu terge tabelul, dac se dorete tergerea coninutul tabelului i definiia tabelului, trebuie folosit, n schimb, declaraia DROP TABLE. Dac condiia_cutare este specificat, numai acele linii care satisfac condiia sunt terse. Exemplu: DELETE FROM cadre_didactice WHERE funcia=lect.;
Limbajul de definire a datei SQL (LDD) ne permite crearea i distrugerea obiectelor baz de dat (scheme, domenii, tabele, view-uri, rapoarte i indexuri). n aceast seciune, examinm, pe scurt, cum s crem i s distrugem scheme, tabele i indexuri. Principalele declaraii de definirii datei n SQL sunt: CREATE SCHEMA DROP SCHEMA CREATE DOMAIN ALTER DOMAIN DROP DOMAIN CREATE TABLE ALTER TABLE DROP TABLE CREATE VIEW DROP VIEW Deasemenea, urmtoarele dou declaraii au fost prevzute de multe SGBD: CREATE INDEX DROP INDEX Aceste declaraii sunt folosite pentru a crea, schimba sau distruge structurile care alctuiesc schema conceptual. nainte de a considera declaraiile LDD, discutm sintaxa identificatorilor SQL i tipurile de date SQL care pot fi folosite n definirea coloanelor tabel.
SMALLINT
Uneori pentru scopuri de manipulare i conversie, tipurile de date caracter i bit sunt atribuite tipurilor de date string, i exact numeric i aproximativ numerice sunt atribuite tipurilor de date numeric, deoarece ele mpart proprietisimilare. Datele caracter Datele caracter conin o secven de caractere dintr-un set de caractere definite de implementator, adic este definit de ctre distribuitorul dialectului particular SQL. Astfel, caracterele exacte care pot aprea ca valorile datelor ntr-o coloan tip caracter vor varia. ASCII este una din seturile utilizate n comun astzi. Formatul pentru specificarea unui tip de dat caracter este: CHARACTER [VARYING][length] CHARACTER can be abbreviated to CHAR and CHARACTER VARYING to VARCHAR. Cnd o coloan caracter string este definit, o lungime poate fi specificat s indice maximul numrului de caractere coninute n coloane (lungimiea implicit este 1). Un caracter string poate fi definit ca avnd o lungime fix sau variabil. Dac stringul este definit cu lungime fix, i dac introducem un string cu cteva caractere mai puin dect aceast lungime, stringul este completat cu spaii la dreapta pentru a obine lungimea cerut. Dac stringul este definit cu lungime variabil i introducem un string cu cteva caractere mai puin dect aceast lungime, numai acele caractere introduse sunt rezervate, astfel folosindu-se mai puine spaii. De 14
exemplu, numrul matricol din coloana nr_mat a tabelului cadre_didactice, care are o lungime fix de 4 caractere, este declarat ca: nr_mat CHAR(4) Coloana nume a tabelului cadre_didactice, care are un numr variabil de caractere pn la maximum de 20, este declarat ca: nume VARCHAR(20) Datele bit Tipul de date bit este folosit pentru definirea stringurile bit, adic o secven de cifre binare, fiecare avnd sau valoarea 0 sau 1. Formatul pentru specificarea tipului de dat bit este similar cu cel al tipului de dat caracter: BIT [VARYING][lenght] De exemplu, pentru a ine lungimea fix a stringului binar 0011, declarm o coloan bit_string, ca: bit_string BIT(4) Datele exact numerice Tipul de dat exact numeric este folosit pentru definirea numerelor cu reprezentare exact. Numrul conine cifre, un punct zecimal opional i un semn opional. Un tip de dat exact numeric conine o precizie i o scal. Precizia d numrul total a cifrelor zecimale semnificative: adic numrul total al cifrelor, incluznd zecimalele dar excluznd punctul. Scala d numrul total al zecimalelor. De exemplu, valoarea exact numeric -12.345 are precizia 5 i scala 3. Un caz special survine n cazul datelor exact numerice ntregi. Exist mai multe moduri de a specifica un tip de dat exact numeric: NUMERIC [precision [, scale]] DECIMAL [precision [, scale]] INTEGER SMALLINT INTEGER poate fi prescurtat prin INT i DECIMAL prin DEC. NUMERIC i DECIMAL genereaz numere n scriere zecimal. Valoarea implicit a scalei este ntotdeauna 0, iar precizia implicit este definit de limbaj. INTEGER este folosit pentru numere mari pozitive sau negative ntregi. SMALLINT este folosit pentru numere mici pozitive sau negative ntregi. Specificnd acest tip de dat, pot fi rezervate mai puine spaii de stocare pentru dat. De exemplu, valoarea absolut maxim care poate fi stocat n acest tip de dat poate fi 32767. Coloana vechime a tabelului cadre_didactice, care reprezint numrul anilor , este evident un ntreg mic i poate fi declarat ca: vechime SMALLINT Coloana salariu a tabelului cadre_didactice poate fi declarat ca: salariu DECIMAL(9,2) care poate manipula o valoare pn la 9,999,999.99. Datele aproximativ numerice Tipul de dat aproximativ numeric este folosit pentru definirea numerelor care nu au o reprezentare exact, ca de pild numerele reale. Aproximativ numeric, sau punct float, este similar notaiei stiinifice n care un numr este scris ca o putere de zece. De exemplu, 10E3, +5.2E6, -0.2E-4. Exist mai multe moduri de a specifica un tip de dat aproximativ numeric: FLOAT [precision] REAL DOUBLE PRECISION Datele dat-timp Acest tip de dat este folosit pentru a defini puncte n timp la un anumit grad de precizie. Ca exemple putem da date calendaristice, intervale de timp i intervale ale unei zile. Standardul ISO folosete pentru acest tip de dat cuvintele rezervate: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, TIMEZONE_HOUR i TIMEZONE_MINUTE. Ultimele dou cmpuri specific ora i minutul pentru anumite zone geografice. Trei tipuri ale acestui tip de date sunt acceptate: DATE TIME [time_precision][WITH TIME ZONE] 15
TIMESTAMP [time_precision][ WITH TIME ZONE] DATE este folosit pentru a reprezenta datele calendaristice folosind cuvintele rezervate YEAR, MONTH i DAY. TIME este folosit pentru a reprezenta timpul folosind cuvintele rezervate HOUR, MINUTE i SECOND. TIMESTAMP reprezint datele calendaristice i timpul. Time_precision reprezint unitatea de msur a cmpului SECOND. Dac nu este specificat acesta este implicit 0 n TIME fiind vorba de secunde, iar n TIMESTAMP valoarea implicit este 6 fiind vorba de microsecunde. Cuvntul cheie WITH TIME ZONE controleaz prezena cmpurilor TIMEZONE_HOUR i TIMEZONE_MINUTE. Date interval Tipul de dat interval este folosit pentru a reprezenta intervale de timp. Fiecare tip de dat interval este alctuit dintr-un subset nvecinat al cmpurilor: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND. Exist dou clase de date interval: intervale an-lun i intervale zi-timp. Clasa an-lun poate conine numai cmpurile YEAR i/sau MONTH, iar clasa zi-timp poate conine o selecie invecinat din DAY, HOUR, MINUTE, SECOND. Formatul pentru specificarea tipului da dat interval este: INTERVAL {{start_cmp TO sfrit_cmp} | cmp_dat-timp} start_cmp=YEAR|MONTH|DAY|HOUR|MINUTE [(precizia cmpului principal al intervalului)] sfrit_cmp=YEAR| MONTH|DAY|HOUR|MINUTE|SECOND [(precizia zecimalelor cmpului secundar al intervalului)] cmp_dat-timp=start_cmp|SECOND [(precizia cmpului principal al intervalului [,precizia cmpului secundar al intervalului])]
zecimalelor
n toate cazurile precizia implicit a cmpului start_cmp este 2. Exemplu: INTERVAL YEAR(2) TO MONTH reprezint un interval de timp cu o valoare ntre 0 ani 0 luni i 99 ani 11 luni. INTERVAL HOUR TO SECOND(4) reprezint un interval de timp cu o valoare ntre 0 ore 0 minute 0 secunde i 99 ore 59 minute 59.9999 secunde.
16
n prezent declaraiile CREATE i DROP SCHEMA nu sunt nc larg implementate. n unele implementri, n locul declaraiei CREATE SCHEMA este folosit declaraia urmtoare: CREATE DATABASE nume_baz-date. Crearea unui tabel (CREATE TABLE) Avnd creat structura bazei de dat, putem acum crea structurile tabelelor de baz a relaiilor pentru a fi localizate n baza de date. Crearea unui tabel se face folosind comanda CREATE TABLE, care are urmtoarea sintax principal: CREATE TABLE nume_tabel (nume_coloan tip_dat [NULL | NOT NULL][,]) Aceast comand creaz un tabel numit nume_tabel alctuit din una sau mai multe coloane al cmpului tip_dat specificat. Specificatorul NULL este folosit pentru a indica dac unei coloane i este permis sau nu s conin null-uri. Un null este diferit de spaiu sau 0 i este folosit pentru a reprezenta date dac acestea nu sunt disponibile, pierdute sau nu sunt aplicabile. Cnd NOT NULL este specificat, sistemul respinge orice ncercare de inserare a unui null n coloane. Dac NULL este specificat, sistemul accept null-uri. Valoarea implicit ISO este NULL. De exemplu, pentru crearea tabelului cadre_didactice avem: CREATE TABEL cadre_didactice( nr_mat CHAR(4) NOT NULL, nume CHAR(15) NOT NULL, prenume CHAR(15) NOT NULL, funcia CHAR(10) vechime SMALLINT ); Distrugerea unui tabel (DROP TABLE) Cu timpul structura unei baze de date se va schimba, tabele noi fiind create iar altele vechi nu vor mai fi necesare. Putem terge un tabel suplimentar din baza de date folosind declaraia DROP TABLE, care are formatul: DROP TABLE nume_tabel [RESTRICT | CASCADE] De exemplu pentru a distruge tabelul cadre_didactice folosim comanda: DROP TABLE cadre_didactice; Observm c aceast comand terge nu numai tabelul specificat, ci i toate liniile din interiorul acesteia. Dac se dorete tergerea liniilor din tabel dar s se rein structura tabelului trebuie folosit declaraia DELETE. Dac RESTRICT este specificat n comanda DROP TABLE i exist orice alte obiecte a cror existen depinde de existena tabelului, asupra cruia acioneaz comanda, SQL nu permite comenzii DROP TABLE s continue. Dac CASCADE este specificat SQL automat terge toate obiectele dependente de tabel (i obiectele dependente de aceste obiecte). O folosire uzual a comenzii DROP TABLE este de a corecta greelile fcute la crearea unui tabel. Dac este creat un tabel cu o structur incorect se poate folosi DROP TABLE pentru a terge tabelul nou creat i ncepe din nou. Modificarea structurii unui tabel (ALTER TABLE) Standardul ISO furnizeaz declaraia ALTER TABLE pentru modificarea structurii unui tabel odat ce a fost creat. Definirea declaraiei ALTER TABLE n standardul ISO este alctuit din 6 opiuni pentru: a aduga o nou coloan la un tabel; a terge o coloan dintr-un tabel ; a aduga o nou restricie pentru tabel; a terge o restricie a tabelului; a stabilii o valoare implicit pentru o coloan; a terge o valoare implicit a coloanei. Formatul principal al declaraiei este:
17
ALTER TABLE nume_tabel [ADD [COLUMN] nume_coloan tip_dat [NOT NULL][UNIQUE] [DEFAULT opiune_implicit][CHECK(condiie_cutare)]] [DROP [COLUMN] nume_coloan [RESTRICT | CASCADE]] [ADD [CONSTRAINT [nume_restricie]] definiie_restricie_tabel] [DROP CONSTRAINT nume_restricie [RESTRICT | CASCADE]] [ALTER [COLUMN] SET DEFAULT opiune_implicit] [ALTER [COLUMN] DROP DEFAULT] unde parametrii sunt definii ca i n declaraia CREATE TABLE. Definiie_restricie_tabel este una din clauzele: PRIMARY KEY, UNIQUE, FOREIGN KEY sau CHECK. Clauza ADD COLUMN este similar cu definirea unei coloane din declaraia CREATE TABLE. Clauza DROP COLUMN specific numele coloanei ce trebuie tears din definiia tabelului. Aceast clauz are un calificativ opional care ne permite s specificm dac aciunea DROP este n cascad sau nu. Avem acela concept ca i la calificativul RESTRICT | CASCADE a declaraiei DROP TABLE. De exemplu pentru a aduga coloana vechime la tabelul cadre_didactice folosim comanda: ALTER TABLE cadre_didactice ADD vechime INTEGER(2); Declaraia ALTER TABLE nu este disponibil n toate dialectele SQL. n unele dialecte, declaraia nu poate fi folosit pentru a muta o coloan existent dintr-un tabel. Crearea unui index (CREATE INDEX) Un index este o structur care furnizeaz accesul rapid la liniile unui tabel bazat pe valorile uneia sau mai multor coloane. Prezena unui index poate mbunti simitor performana unei interogri. Indexurile sunt create, de obicei, pentru a satisface criteriul de cutare particular dup ce tabelul a fost folosit un timp i a crescut n mrime. Crearea indexurilor nu este standardizat n SQL. Totui multe dialecte accept cel puin urmtoarea form a acestei comenzi: CREATE [UNIQUE] INDEX nume_index ON nume_tabel (colon [ASC |DESC] [,]) Coloanele specificate alctuiesc cheia index i ar trebui listate n ordine descresctoare. Indexurile pot fi create numai n tabele de baz nu i n view-uri. Dac clauza UNIQUE este folosit, unicitatea coloanei sau combinaiei de coloane indexate va fi decretat de ctre sistem. Dei indexurile pot fi create oricnd, putem avea probleme dac ncercm s crem un index unic pe un tabel care conine articole, deoarece valorile provenite din coloana (coloanele) indexat poate s conin deja dubluri. De aceea este mai bine s crem indexuri unice, cel puin pentru coloane cheie principale, atunci cnd tabelul de baz este creat i sistemul nu va asigura automat unicitatea cheii principale. Pentru tabelul cadre_didactice putem crea urmtoarele indexuri: CREATE UNIQUE INDEX matricol_ind ON cadre_didactice(nr_mat); CREATE UNIQUE INDEX nume_ind ON cadre_didactice(nume); Pentru fiecare coloan putem specifica dac ordinea este ascendent (ASC) sau descendent (DESC), valoarea implicit fiind ASC. tergerea unui index (DROP INDEX) Dac crem un index pentru un tabel de baz i mai trziu decidem c nu mai este necesar, declaraia DROP INDEX terge indexul din baza de date. DROP INDEX are formatul: DROP INDEX nume_index Declaraia urmtoare va terge indexul creat n exemplul anterior: DROP INDEX matricol_ind;
2. View vertical care pemite restricionarea accesului utilizatorilor la anumite coloane ale unui tabel ale unui tabel: CREATE VIEW cadre_lect AS SELECT nr_mat, nume, prenume FROM cadre_didactice WHERE funcia = lect.; nr_mat 1111 1116 nume Popa Ionescu prenume Ioan Mircea
CREATE VIEW secii_grupe (secia, grupa) AS SELECT s.denumire, g.cod_gr FROM secii s, grupe g WHERE s.cod_sec = g.cod_sec; GROUP BY s.denumire; secia Matematic Matematic Informatic Matematic-fizic Matematic-fizic Fizic-chimie grupa 1 2 1 1 2 1 19
2. Universalitatea Schimbrile oricror tabele n interogarea definit sunt imediat reflectate n view. 3.
Securitatea 20
Fiecare utilizator poate avea privilegiul de a accesa baze de date numai printr-un mic set de view-uri, care conine date potrivite acelui utilizator, astfel restrngnd i controlnd accesul la baza de date a fiecrui utilizator.
4. Complexitatea redus Un view poate simplifica interogrile prezentarea datelor din mai multe tabele ntr-un singur tabel i, astfel, transformnd interogri multi-tabel n interogri 1-tabel. 5. Selectabilitatea View-urile furnizeaz posibilitatea ca aceleai tabele principale s poat fi vzute de diferii utilizatori, n diferite moduri. 6. Integritatea datei Dac WITH CHECK OPTION a declaraiei CREATE VIEW este folosit, SQL asigur faptul c nici o linie care nu satisface clauza WHERE a interogrii definite nu este niciodat adugat la orice tabel principal prin view, prin aceasta asigurnd integritatea view-ului.
Dezavantaje. Dei view-urile furnizeaz multe beneficii semnificative, exist de asemenea, cteva dezavantaje ale view-urilor SQL:
1. Restricia actualizrii n unele cazuri un view nu poate fi actualizat. 2. Restricia structurii Structura unui view este determinat la timpil crerii lui. Dac interogarea definit a fost de forma SELECT * FROM , atunci * se refer la coloanele tabelului de baz existent cnd a fost creat view-ul. Dac coloanele sunt ulterior adugate la tabelul de baz, atunci aceste coloane nu vor aprea n view, n afar de cazul cnd view-ul este ters i recreat. 3. Performana Exist un neajuns care apare cnd folosim un view. n unele cazuri acest lucru va fi neglijabil; n alte cazuri poate fi mai problematic. De exemplu, un view definit printr-o interogare complex multi-tabel poate lua un timp ndelungat pentru a fi prelucrat pe cnd rezoluia view-ului trebuie s joncioneze tabelele de fiecare dat cnd view-ul este accesat. Rezoluia view-ului cere resurse n plus calculatorului.
21