SQL

1.1. Prezentare generală
Un limbaj particular care provine din dezvoltarea unui model relaţional este Limbajul Interogării Structurate, sau SQL. În ultimii ani SQL a devenit limbajul standard al bazelor de date relaţionale, în 1986 un standard pentru SQL fiind definit de American National Standards Institute (ANSI), care a fost preluat ca standard internaţional de către International Standards Organization (ISO) în 1987. Mai mult de 100 de sisteme de administrare a bazelor de date suportă SQL, rulate atât pe calculatoare personale cât şi pe reţele de calculatoare. În continuare, prezentarea SQL va fi făcută folosind în special terminologia ISO, în acest capitol fiind prezentate noţiunile de bază ale limbajului SQL.

1.1.1. Obiectivele şi terminologia SQL
În mod ideal un limbaj de baze de date ar trebui să permită utilizatorului să creeze baze de date şi structuri relaţionale; ar trebui să permită realizarea unor operaţii de bază asupra datelor ca: inserarea, modificarea şi ştergerea datelor din relaţii; şi ar trebui să permită realizarea atât a interogărilor simple cât şi complexe pentru a transforma datele iniţiale în informaţii. Ca o completare un limbaj de baze de date trebuie să gestioneze aceste evenimente cu un efort minim, şi structura şi sintaxa comenzilor trebuie să fie relativ uşor de învăţat. În final acesta trebuie să fie portabil, adică să fie conform unor standarde recunoscute în domeniu astfel încât să putem folosi aceleaşi structuri şi sintaxe de comenzi când trecem de la un SGBD la altul. SQL intenţionează să satisfacă aceste cerinţe. SQL este un exemplu de limbaj construit pentru folosi relaţiile pentru a transforma intrările în ieşirile cerute. Ca limbaj, SQL are două mari componente: • un limbaj de definire a datelor (LDD) pentru definirea structurii bazelor de date ; • un limbaj de manipulare a datelor (LMD) pentru recuperarea şi actualizarea datelor ; SQL conţine numai aceste comenzi definitorii şi manipulative; nu conţine comezi de control ca: IF…THEN…ELSE, GO TO, DO…WHILE ori alte astfel de comenzi. Acestea trebuiesc implementate folosind un limbaj de programare sau în mod interactiv prin deciziile utilizatorului. SQL poate fi utilizat în două moduri. Primul mod este de a folosi SQL interactiv, introducînd comenzile de la un terminal. Al doilea mod este de a ataşa comenzile SQL unui limbaj de programare procedural. SQL este un limbaj relativ uşor de învăţat: • Este un limbaj non-procedural: utilizatorul mai degrabă specifică ce informaţii îl interesează, decât cum se obţin acestea. Cu alte cuvinte nu cere să se specifice metodele de acces la date. • Ca majoritatea limbajelor moderne, SQL are în mod esenţial un format liber, ceea ce înseamnă că blocurile de declaraţii nu trebuie tipărite în zone particulare ale ecranului. • Structura comenzilor conţine cuvinte din engleza standard: CREATE TABLE, INSERT, SELECT. • SQL poate fi folosit de o mulţime de utilizatori incluzînd administratorii bazelor de date, programatorii de aplicaţii şi multe alte tipuri de utilizatori. Există acum un standard internaţional pentru limbajul SQL (ISO, 1992), care este considerat limbajul standard de definire şi manipulare a bazelor de date relaţionale. Standardul ISO SQL nu foloseşte termeni formali pentru relaţii, atribute şi tupluri, în schimb foloseşte termenii de tabele, coloane şi linii. De asemenea trebuie să punctăm faptul că SQL nu aderă strict la o definiţie a modelului relaţional. De exemplu, SQL permite tabelul produs ca rezultat a operaţiei SELECT ce conţine linii duble, impunînd o ordine a coloanelor, şi de asemenea permite utilizatorului de a ordona liniile unui tabel.

1.1.2. Scrierea comenzilor SQL
În acestă secţiune vom descrie structura unei declaraţii SQL şi notaţiile pe care le folosim în definirea formatelor pentru diferite construcţii SQL. O declaraţie SQL conţine cuvinte rezervate şi cuvinte definite de către utilizator. Cuvintele rezervate sunt o parte fixată a limbajului SQL şi au un înţeles fix. Ele trebuie scrise exact şi nu pot fi despărţite cu cratimă. Cuvintele definite de către utilizator sunt create ţinîndu-se seama de reguli specifice de sintaxă şi reprezintă numele diferitelor obiecte de bază de date cum ar fi relaţii, coloane, indexuri etc. Cuvintele dintr-o declaraţie sunt de asemenea construite ţinîndu-se seama de un set de reguli de sintaxă. Deşi standardul nu cere acest lucru, multe dialecte SQL pretind folosirea unui declaraţii finale pentru a marca sfârşitul fiecărei declaraţii SQL (de obicei se foloseşte “;”). 1

Majoritatea componentelor unei declaraţii SQL sunt insensibile la litere mari sau mici. O excepţie 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 căutăm numele folosind ‘Marin’ articolul nu va fi găsit. Deşi SQL este de liber format, o declaraţie SQL sau un set de declaraţii este mult mai interesantă dacă este folosită alinierea. De exemplu: • Fiecare clauză din declaraţie ar trebui scrisă pe linie nouă. • Începutul fiecărei clauze ar trebui scrisă sub începutul altei clauze. • Dacă o clauză are mai multe părţi ele ar trebui să apară pe linii separate şi să fie inclusă la începutul clauzei pentru a arăta relaţia dintre ele. În acest capitol vom folosi următoarea modalitate pentru a defini declaraţiile SQL: • Literele mari sunt folosite în reprezentarea cuvintelor rezervate şi trebuiesc scrise exact. • Literele mici sunt folosite în reprezentarea cuvintelor definite de către utilizator. • “|” indică o alegere între alternative; de exemplu a | b | c. • Parantezele acolade indică un element dorit: de exemplu, {a}. • Parantezele pătrate indică un element opţional: de exemplu, [a]. • Punctele (…) sunt folosite pentru a indica repetiţia opţională 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 repetiţii al lui c separate prin virgulă. În practică declaraţiile LDD sunt folosite pentru crearea de structuri de baze de date (tabele), iar declaraţiile LMD pentru a popula şi interoga tabelele. În acest capitol vom prezenta declaraţiile LMD înaintea celor LDD pentru a arăta importanţa relativă a declaraţiilor LMD.

1.2. SQL - limbaj de manipulare a datelor (LMD)
Această secţiune se referă la declaraţii SQL LMD disponibile, numite: • SELECT interogarea datelor din baza de date, • INSERT inserarea datelor într-un tabel, • UPDATE actualizarea datelor într-un tabel, • DELETE ştergerea datelor dintr-un tabel. Datorită complexităţii declaraţiilor SELECT şi a simplităţii relative a altor declaraţii LMD o mare parte din această secţiune va fi dedicată declaraţiei SELECT şi diferitelor formate ale acesteia. La început vor fi prezentate interogări simple şi succesiv acestea se vor complica pentru a arăta că pot fi generate interogări care folosesc la sortarea, gruparea, combinarea datelor şi de asemenea interogări pe mai multe tabele. În finalul aceastei secţiuni vor fi prezentate declaraţiile INSERT, UPDATE şi DELETE. Pe parcursul acestei secţiuni vor fi date exemple pentru toate comenzile SQL care vor fi prezentate, iar aceste exemple vor folosi, pentru a ilustra felul în care operează aceste comenzi, următoarele relaţii: cadre_didactice (nr_mat, nume, prenume, funcţia, vechime, salariu) secţii (cod_sec, denumire, iniţiale) grupe (cod_sec, cod_gr, nr_semigrupe, nr_studenţi) oraşe (cod, denumire); municipii(cod_m, denum_m); Pentru aceste relaţii vom considera următoarele înregistrări: Tabelul cadre_didactice: nr_mat nume 1111 Popa 1112 Liana 1113 Barbu 1114 Ştefan 1115 Savu 1116 Ionescu Tabelul secţii: cod_sec 1 2 3 4 denumire Matematică Informatică Matematică-fizică Fizică-chimie iniţiale M I MF FC 2

prenume Ioan Carmen Traian Elena Alexandru Mircea

funcţia 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

000 900. GROUP BY grupează toate liniile din tabele care au aceeaşi valoare pe coloana specificată. salariu FROM cadre_didactice.Tabelul grupe: cod_sec 1 1 2 3 3 4 Tabelul oraşe: cod O1 O2 O3 cod_gr 1 2 1 1 2 1 nr_semigrupe 2 2 1 2 1 2 nr_studenţi 25 24 30 28 24 29 denumire Braşov Codlea Timişoara Tabelul municipii: cod_m M1 M2 M3 denum_m Timişoara Iaşi Braşov 1. Ordinea clauzelor în declaraţia SELECT nu poate fi schimbată. WHERE specifică liniile care trebuiesc recuperate cu ajutorul unor condiţii. rezultatul interogării unui tabel fiind tot un tabel. conf. Pentru cuvintele rezervate avem următoarea semnificaţie: FROM specifică tabelul sau tabelele care vor fi folosite. Recuperarea liniilor unui tabel doar pentru anumite coloane ale: 3 .2. Interogări simple 1. proiecţia şi joncţiunea într-o singură declaraţie.000 700. prenume. Există mai multe variante ale acestei comenzi. SELECT este comanda cea mai des folosită în SQL.000 2. funcţia.…] [WHERE condiţie] [GROUP BY listă_coloane] [HAVING condiţie] [ORDER BY listă_coloane] În această declaraţie expresie_coloană reprezintă o coloană sau o expresie. vechime. conf. vechime 15 20 25 25 28 18 salariu 400. nume. Forma generală a declaraţiei SELECT este : SELECT [DISTINCT|ALL]{* | [expresie_coloană [AS nume_nou]][. ORDER BY ordonează valorile returnate după coloanele specificate. totuşi exemplele care urmează ilustrează principalele variante ale acestei declaraţii. conf.000 900.000 950. alias reprezintă o prescurtare a numelui de tabel.000 400. lect. Singurele două clauze obligatorii sunt primele două: SELECT şi FROM celelalte fiind opţionale. Comanda SELECT Scopul declaraţiei SELECT este de a recupera şi a afişa datele din unul sau mai multe tabele de baze de date.1. Este o comandă extrem de puternică capabilă de a echivala în algebra relaţională selecţia. SELECT * FROM cadre_didactice. HAVING selectează grupurile care respectă condiţia de căutare. Operaţia SELECT este închisă. SELECT specifică coloanele care vor apărea în rezultatul interogării. conf. Obţinem în urma acestor două interogări acelaşi rezultat: nr_mat 1111 1112 1113 1114 1115 1116 nume Popa Liana Barbu Ştefan Savu Ionescu prenume Ioan Carmen Traian Elena Alexandru Mircea funcţia lect. Recuperarea tuturor liniilor unui tabel: SELECT nr_mat.…]} FROM nume_tabel [alias][.

salariu 400. deseori avem nevoie de a restrânge liniile care au fost recuperate. prenume. <=. salariu 400.000 140. prenume.000 900.000 Exemplele de mai sus arată folosirea declaraţiei SELECT pentru a recupera toate liniile dintr-un tabel. • Operatorii AND sunt evaluaţi înaintea celor OR.000 950. prenume.000 4.000 900. <. OR. Utilizarea cuvântului rezervat DISTINCT care elimină liniile duble: SELECT salariu FROM cadre_didactice. nume. < >.000 700. nr_mat 1111 1112 1113 1114 1115 1116 Clauza WHERE nume Popa Liana Barbu Ştefan Savu Ionescu prenume Ioan Carmen Traian Elena Alexandru Mircea col 4 80.000 400. În SQL avem următoarii operatori de comparaţie: =. • Subexpresiile în paranteze sunt evaluate prima dată.000 700. nume. nume. pentru a arăta ordinea de valoare. salariu/5 FROM cadre_didactice. salariu FROM cadre_didactice. Acest lucru se poate realiza cu clauza WHERE care conţine cuvântul cheie urmat de o condiţie de căutare care specifică liniile ce trebuiesc recuperate.000 900.000 SELECT DISTINCT salariu FROM cadre_didactice. Totuşi. şi NOT.000 700.000 900.000 950. cu paranteze sau nu. Multe predicate complexe pot fi generate folosind operatori logici AND. 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 950.000 180. 4 . Folosirea câmpurilor calculate: SELECT nr_mat. • Operatorii NOT sunt evaluaţi înaintea operatorilor AND şi OR.000 3. salariu FROM cadre_didactice WHERE salariu >700.000 400. Folosirea parantezelor este întotdeauna recomandată pentru a elimina posibilile ambiguităţi. Compară valorile unei expresii cu valorile altei expresii: SELECT nr_mat. >=.000.000 180. != (diferit).000 190. >.000 80.SELECT nr_mat. Cele 5 condiţii principale de căutare sunt următoarele: 1.000 900. Comparaţia. Regulile pentru evaluarea expresiilor condiţionate sunt: • O expresie evaluată de la stânga la dreapta.

unele dialecte 5 .000 900. nume care ar putea fi de referinţă ulterior. • adresa NOT LIKE ‘H%’ înseamnă că numele nu poate începe cu H. salariu FROM cadre_didactice WHERE salariu BETWEEN 500. SQL are două caractere speciale: % reprezintă orice secvenţă de zero sau de mai multe caractere. • adresa LIKE ‘%Popescu%’ înseamnă o secvenţă de caractere de orice lungime care conţine Popescu. liniile tabelului rezultat a unei interogari SQL nu sunt aranjate într-o anumită ordine. • adresa LIKE ‘H_ _ _’ înseamnă că trebuie să fie exact patru caractere în şir primul fiind H. fie un număr de coloană care identifică un element din lista SELECT dîndu-ne poziţia acestuia în listă:1 pentru primul element din listă. ş.000 3. iar celelalte pot fi orice caracter. vechime FROM cadre_didactice WHERE vechime IN (20. Clauza ORDER BY ne permite ordonarea articolelor recuperate în mod crescător (ASC) sau descrescător (DESC) pe orice coloană sau combinaţie de coloane indiferent dacă coloana apare sau nu în rezultat. Numerele de coloană pot fi folosite dacă coloana ce trebuie sortată este o expresie şi nici o clauză AS nu este specificată în vederea ataşări unui nume pentru coloană. SELECT nr_mat. nume. Identificatorul de coloană poate fi. Compatibilitatea. Apartenenţa la o mulţime. Clauza ORDER BY conţine o listă de identificatori de coloană pentru ca rezultatul să fie sortat şi separat prin virgulă. Testează dacă un şir se potriveşte cu un model specificat (LIKE/NOT LIKE). De exemplu: • adresa LIKE ‘H%’ înseamnă că primul caracter trebuie să fie H. putem sorta rezultatele unei interogări folosind clauza ORDER BY din declaraţia SELECT.m. nr_mat 1111 (1 linie) nume Popa prenume Ioan 5. Nul. prenume FROM cadre_didactice WHERE nume LIKE ‘P%’.000 2. Testează dacă valoarea unei expresii este inclusă într-un şir de valori specificate (BETWEEN/NOT BETWEEN): SELECT nr_mat.000 AND 900. _ reprezintă orice caracter singular. Celelalte caractere se folosesc normal. nume.000 900. Şir.a. fie un nume de coloană. nume.nr_mat 1113 1114 1115 nume Barbu Ştefan Savu prenume Traian Elena Alexandru salariu 900. • adresa LIKE ‘%e’ înseamnă orice secvenţă de caractere de lungime cel puţin 1 cu ultimul caracter e. Totuşi. Testează dacă o coloană are o valoare nulă (necunoscută) (IS NULL/IS NOT NULL). nr_mat 1112 1113 1114 nume Liana Barbu Ştefan prenume Carmen Traian Elena vechime 20 25 25 4. 2 pentru al doilea. nr_mat nume 1112 Liana 1113 Barbu 1114 Ştefan prenume Carmen Traian Elena salariu 700. prenume.000.Totuşi.d.000 900. Clauza ORDER BY (rezultate de sortare) În general. prenume.000 950. 25). Testează dacă valoarea unei expresii aparţine unui set de valori (IN/NOT IN): SELECT nr_mat.

SELECT nr_mat. De exemplu. de aceea trebuie pus în vedere dacă dublurile trebuiesc incluse sau nu în operaţie. Ca o adăugare. lect. poate avea un efect asupra rezultatelor date de SUM sau AVG. COUNT. • MIN returnează cea mai mică valoare dintr-o coloană specificată. • AVG returnează media valorilor dintr-o coloană specificată.000 950. conf. SELECT nr_mat. Aceste funcţii operează pe o singură coloană a tabelului şi returnează o singură valoare. MIN. salariu 400. ar putea să existe mai multe linii din tabelul rezultat cu aceeaşi valoare pentru cheia de sortare majoră.insistă asupra faptului ca elementele ORDER BY să apara în lista SELECT. conf. nr_mat 1111 1116 1115 1113 1114 1112 nume Popa Ionescu Savu Barbu Ştefan Liana prenume Ioan Mircea Alexandru Traian Elena Carmen funcţia lect. Este important faptul că funcţiile complexe pot fi folosite numai în lista SELECT şi în clauza HAVING.000 400. trebuie să folosim cuvântul cheie DISTINCT înainte de numele de coloană din funcţie.000 900. • SUM returnează suma valorilor dintr-o coloană specificată. salariu FROM cadre_didactice ORDER BY funcţia. Totuşi. COUNT(*) este o folosire specială a lui COUNT. atunci acesta se numeşte cheie de sortare minoră. În ambele cazuri. nume. Dacă lista SELECT include o funcţie complexă şi dacă nu a fost folosită clauza GROUP BY pentru gruparea datelor. conf. În afară de COUNT(*). iar SUM şi AVG pot fi folosite numai pe câmpuri numerice. salariu FROM cadre_didactice ORDER BY salariu DESC.000 700. dacă cheia de sortare majoră nu este unică. Acest lucru rămîne la alegerea implementorului SGBD. prenume. • MAX returnează cea mai mare valoare dintr-o coloană specificată. Cheia de sortare majoră determină ordinea generală a tabelului rezultat. conf.000 900.000 400.000 900. Scopul ei este de a număra liniile unui tabel indiferent dacă conţin sau nu zerouri sau valori duble. Dacă apare un al doilea element în clauza ORDER BY.000 Este posibil de a include mai multe elemente în clauza ORDER BY. dacă nu dorim eliminarea dublurilor. interogarea următoare este incorectă: 6 . Dacă dorim să eliminăm dublurile înainte de a aplica funcţia. DISTINCT nu are nici un efect asupra funcţiilor MIN şi MAX. clauza ORDER BY trebuie să fie întotdeauna ultima în declaraţia SELECT. Este incorectă folosirea lor în altă parte. prenume. Dacă cheia de sortare majoră este unică.000 900. ar fi de dorit să se ordoneze liniile cu aceeaşi valoare pentru cheia de sortare majoră cu ajutorul unei chei de sortare adiţională. Folosirea funcţiilor complexe SQL Standardul ISO defineşte 5 functii complexe: • COUNT returnează numarul de valori dintr-o coloană specificată. deşi ALL este presupus dacă nu se specifică nimic.000 700. funcţia. Totuşi. atunci nici un element din lista SELECT nu poate conţine referinţe la o coloană numai dacă acea coloană este un argument a unei funcţii complexe. Standardul ISO permite specificarea cuvântului cheie ALL. fiecare funcţie elimină prima dată zerourile şi operează pe cele care au rămas cu valoare nenulă. nu mai este nevoie de nici o cheie de control pentru sortare. nume. DISTINCT poate fi specificat o singură dată în interogare. salariu DESC.000 Standardul ISO specifică faptul că zerourile dintr-o coloană sau expresie sortată cu ORDER BY trebuiesc tratate mai puţin sau mai mult decît toate valorile nenule. 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 400. MAX se aplică atât pe câmpuri numerice cât şi pe câmpuri nenumerice. În acest caz.

contor 3 3. MAX(salariu) AS max. Utilizarea funcţiilor COUNT şi SUM: SELECT COUNT(nr_mat) AS contor. Utilizarea funcţiilor MIN. Când clauza WHERE este folosită cu GROUP BY. COUNT(salariu) FROM cadre_didactice. este deseori folositor de a avea subtotale în raport.000 4.450. • o expresie cuprinzînd combinaţii ale elementelor de mai sus. Utilizarea funcţiei COUNT(*): SELECT COUNT(*) AS contor FROM cadre_didactice WHERE salariu >400.SELECT nr_mat. prima dată este apelată clauza WHERE. Standardul ISO cere ca clauzele SELECT şi GROUP BY să fie strâns integrate. Reciproca nu este adevărată: pot să existe nume de coloane în clauza GROUP BY care nu apar în lista SELECT.3 Clauza GROUP BY (rezultate de grupare) Interogările sumare de mai sus sunt similare cu totalele de la sfârşitul raportului. contor 4 2. Toate numele de coloană din lista SELECT trebuie să apară în clauza GROUP BY. Se condensează toate datele din raport într-o singură linie sumară de date. AVG: SELECT MIN(salariu) AS min.000 max 950.333.’. contor 4 total_sal 4. deoarece grupează datele din tabelele SELECT şi crează o singură linie pentru fiecare grup. fiecare element din lista SELECT trebuie să aibă valoare unică pe grup. • constante. în afară de cazul când numele este folosit numai într-o funcţie complexă. clauza SELECT poate să conţină numai: • nume de coloană.000 AND 950. min 400. apoi grupurile sunt formate din liniile rămase ceea ce satisface condiţia de căutare. Totuşi.000 media 708.000. deoarece lista SELECT conţine atât un nume de coloană (nr_mat) cât şi o funcţie complexă separată (COUNT). În plus. 7 . MAX.Când se foloseşte GROUP BY. Coloanele numite în clauza GROUP BY se numesc coloane de grupare. • funcţii complexe. AVG(salariu) AS media FROM cadre_didactice. O interogare care cuprinde clauza GROUP BY se numeşte interogare grupată. Pentru aceasta putem folosi clauza GROUP BY din declaraţia SELECT. Exemple: 1.000. SUM(salariu) AS total_sal FROM cadre_didactice WHERE funcţia=’conf. fără a fi folosită o clauză GROUP BY. Utilizarea funcţiei COUNT(DISTINCT): SELECT COUNT(DISTINCT salariu) AS contor FROM cadre_didactice WHERE salariu BETWEEN 500.

SQL calculează numărul membrilor schemei şi adună valorile în coloana “salariu” pentru a obţine totalul salariilor.450. Subselectele pot apărea. nr_semigrupe. toate cadrele didactice au aceaşi funcţie. Un subselect poate fi folosit în clauzele WHERE şi HAVING a unei declaraţii SELECT exterioare. Rezultatele acestei declaraţii SELECT interioare (sau subselect) sunt folosite în declaraţiile exterioare pentru a ajuta la determinarea conţinutului rezultatului final. funcţia conf. conf. Exemplu: SELECT funcţia. HAVING şi WHERE servesc scopuri diferite. UPDATE şi DELETE. SUM(salariu) AS total_sal FROM cadre_didactice GROUP BY funcţia ORDER BY funcţia. În practică.000 Conceptual. în lista GROUP BY sau să fie conţinute într-o funcţie complexă. nr_studenţi FROM grupe WHERE cod_sec = (SELECT cod_sec FROM secţii WHERE denumire = ‘Matematica’).000 3. rezultatul este sortat în ordinea crescătoare după câmpul “funcţia”. contor 4 total_sal 3. funcţia lect.Standardul ISO consideră două zerouri ca fiind egale pentru scopurile clauzei GROUP BY. COUNT(nr_mat) AS contor. contor 2 4 total_sal 800. SQL realizează interogarea în felul următor: 1. în declaraţiile INSERT. Exemplu: SELECT funcţia. COUNT(nr_mat) AS contor. de asemenea. Dacă două linii au zerouri în aceeaşi coloană de grupare şi valori identice în toate coloanele de grupare nenule. 3. 2.000 Exemplu: SELECT cod_gr. SUM(salariu) AS total_sal FROM cadre_didactice GROUP BY funcţia HAVING COUNT(nr_mat)>2 ORDER BY funcţia. ele sunt combinate în acelaşi grup. unde acesta este numit subinterogare sau interogare intercalată. Deşi sunt similare în sintaxă. orice interogare exprimată folosind clauza HAVING poate fi rescrisă întotdeauna fără clauza HAVING. Subinterogări Unele declaraţii SQL pot avea o declaraţie SELECT completă încrustată în interiorul lor. Clauza WHERE strecoară linii individuale în finalul tabelului rezultat. Clauza HAVING nu este parte importantă a SQL. Standardul ISO cere ca numele coloană folosite în clauza HAVING să apară. În final. cod_gr 1 nr_semigrupe 2 nr_studenţi 25 8 . deasemenea. În cadrul fiecărui grup. iar HAVING strecoară grupuri în finalul tabelului rezultat. Clauza HAVING (restrângerea grupurilor) Clauza HAVING este folosită împreună cu clauza GROUP BY pentru a restrânge grupurile care apar la finalul tabelului rezultat. SQL divide schema în grupuri ţinînd seama de câmpul “funcţia”. altfel condiţia de căutare ar putea fi mutată în clauza WHERE şi aplicată pe linii individuale.450. SQL generează o singură linie sumară în rezultatul interogării pentru fiecare grup. condiţia de căutare din clauza HAVING include întotdeauna cel puţin o funcţie complexă. Pentru fiecare grup.

Subinterogarea însăşi este întodeauna închisă între paranteze. condiţia va fi adevărată numai dacă este satisfăcută de toate valorile date de subinterogare. nume prenume Savu Alexandru Interogări multi-tabele salariu 950.000 Toate exemplele considerate pînă acum au o limitare majoră: toate coloanele ce trebuie să apară în tabelele rezultat trebuie să provină dintr-un singur tabel. folosind ca separator virgula şi incuzînd clauza WHERE pentru a specifica coloanele joncţiunii. Asupra subinterogărilor se aplică următoarele reguli: 1) Clauza ORDER BY nu poate fi folosită într-o subinterogare (deşi ea poate fi folosită în majoritatea declaraţiilor SELECT exterioare. >=. Dacă subinterogarea este vidă.000 2. Pentru a reuşi operaţia de joncţiune. excepţie făcînd subinerogările care folosesc cuvântul cheie EXISTS. Dacă avem nevoie să obţinem informaţii din mai multe tabele. prenume. 3) Deoarece lipsesc. Folosirea cuvintelor rezervate ANY şi ALL Cuvintele ANY şi ALL pot fi folosite cu subinterogări care produc o singură coloană a numerelor. Dacă subinterogarea este precedată de cuvântul cheie ALL. Exemple: 1.000 900. De asemenea. 5) O subinterogare nu poate fi folosită ca operant într-o expresie. Dacă subinterogarea este precedată de cuvântul cheie ANY. În multe cazuri. este posibil să folosim alias pentru un tabel specificat în clauza FROM. Operaţia de joncţiune SQL combină informaţia din două tabele formînd perechi de linii înrudite din cele două tabele. În acest caz. prenume. <=. >. Standardul ISO permite folosirea calificativului SOME în locul lui ANY.000 900. O subinterogare poate fi folosită imediat după un operator relaţional (=.< . acest lucru nu este suficient.2 2 24 Subinterogarea poate fi privită ca producătorul unor tabele temporare de rezultate. nume Savu Barbu Ştefan prenume Alexandru Traian Elena salariu 950. trebuie doar să includem mai multe nume de tabele în clauza FROM. Utilizarea cuvântului rezervat ANY: SELECT nume. putem alege între folosirea unei subinterogări şi a unei joncţiuni. Utilizarea cuvântului rezervat ALL: SELECT nume. numele coloană dintr-o subinterogare se referă la numele tabel din clauza FROM a subinterogării.’). condiţia va fi adevărată dacă este satisfăcută de orice (una sau mai multe) valoare dată de subinterogare. aliasul este 9 . avem nevoie de o operaţie de joncţiune. condiţia ALL returnează valoarea adevărat. iar condiţia ANY returnează valoarea fals. salariu FROM cadre_didactice WHERE salariu > ANY (SELECT salariu FROM cadre_didactice WHERE funcţia =’conf’). salariu FROM cadre_didactice WHERE salariu => ALL (SELECT salariu FROM cadre_didactice WHERE funcţia =’conf. Este posibil să se recurgă la un tabel dintr-o clauză FROM a unei interogări exterioare în modificarea numelui coloană. atunci trebuie să folosim joncţiunea. Perechile de linii ce alcătuiesc tabelul asociat sunt toate acolo unde coloanele corespunzătoare din cele două tabele au aceeaşi valoare. subinterogarea trebuie să apară în partea dreaptă a comparaţiei. < >) într-o clauză WHERE sau HAVING. Dacă tabelul rezultat final trebuie să conţină coloane din diferite tabele. 4) Când o subinterogare este una din cei doi operanţi implicaţi într-o comparaţie. 2) Lista subinterogărilor SELECT trebuie să conţină un singur nume coloană sau o singură expresie. Pentru a combina coloanele din mai multe tabele în obţinerea unui tabel rezultat. care pot fi accesate şi folosite de către declaraţii exterioare.

cod_sec FROM secţii JOIN grupe USING cod_sec FROM secţii NATURAL JOIN grupe În fiecare caz. g. Tabelul care conţine cheia străină este un tabel fiu. 4. clauza FROM înlocuieşte clauzele originale FROM şi WHERE. linia este omisă din tabelul rezultat. m. Standardul ISO furnizează un alt set de operatori de joncţiune numiţi joncţiuni externe. Dacă un alias este specificat. Joncţiuni externe Operaţia de joncţiune combină datele din două tabele formînd perechi de linii specificate. 2. În termenii algebrei relaţionale. Joncţiunea este o submulţime a unei combinaţii mult mai generale a două tabele cunoscute cum ar fi produsul cartezian a două tabele. grupe g WHERE s. În algebra relaţională. s. Coloanele tabelului produs sunt toate coloanele primului tabel urmat de toate coloanele celui de al doilea tabel. g. Joncţiunea externă reţine liniile care nu satisfac condiţia de joncţiune. Dacă există o clauza ORDER BY.nr_semigrupe. Fiecare fiu are un tată asociat şi fiecare părinte are asociaţi mai multi fii.cod_sec denumire Matematică Matematică Informatică Matematică-fizică Matematică-fizică Fizică-chimie iniţiale M M I MF MF FC cod_gr 1 2 1 1 2 1 nr_semigrupe 2 2 1 2 1 2 nr_studenţi 25 24 30 28 24 29 Cele mai comune interogări muti-tabel implică două tabele care au o relaţie 1:M (sau tată/fiu).separat de numele tabelului printr-un spaţiu. Perechile de linii care generează interogarea rezultat sunt combinaţii de linii tată/fiu.iniţiale. se mai poate folosi ca o notaţie pentru numele tabelului. trebuie folosit oriunde numele tabelului ar putea fi specificat. Dacă specificăm o interogare doi-tabel fără clauza WHERE. cod O1 O2 O3 denumire Braşov Codlea Timişoara cod_m M3 NULL M1 denum_m Braşov NULL Timişoara 10 .cod_sec = g. Dacă SELECT DISTiNCT a fost specificat. se sortează în modul cerut tabelul rezultat. reţinînd acele linii care satisfac condiţia. g. se aplică condiţia de căutare fiecărei linii a tabelului produs. 3. Un alias poate fi folosit pentru a modifica numele coloană ori de câte ori există ambiguităţi privind sursa numelui coloană.denumire. pasul 3 şi 4 sunt echivalente cu o proiecţie a restricţiei asupra coloanelor menţionate în lista SELECT. De asemenea. Acesta a fost cazul pentru joncţiunile examinate mai sus.*.* FROM oraşe o LEFT JOIN municipii m ON o. SQL produce produsul cartezian al celor două tabele ca fiind interogarea rezultat.nr_studenţi FROM secţii s. Exemple: SELECT s. se elimină orice linie dublă din tabelul rezultat. Dacă există o clauză WHERE. Există trei tipuri de joncţiuni externe: 1. această operaţie produce o restricţie a produsului cartezian. joncţiune externă stângă: SELECT o.denum_m.denumire = m. Dacă o linie a tabelului este fără pereche. Standardul SQL2 furnizează următoarele moduri alternative pentru a specifica această asociere: FROM secţii s JOIN grupe g ON s. 5. unde coloanele corespunzătoare din fiecare tabel au aceeaşi valoare. iar tabelul care conţine cheia fundamentală este un tabel tată. se determină valoarea fiecărui element din lista SELECT în scopul producerii unei singure linii în tabelul rezultat. În exemplul de mai sus se face o astfel de comparaţie. Se formează produsul cartezian a tabelelor numite în clauza FROM.cod_sec=g. Interogarea precedentă este o astfel de interogare. Pentru a folosi relaţia tată/fiu într-o interogare SQL. Procedura pentru generarea rezultatelor unui SELECT cu o asociere este: 1. Produsul cartezian a doua tabele este un alt tabel alcătuit din toate perechile posibile de linii din cele doua tabele. Pentru fiecare linie rămasă. vom specifica o condiţie de căutare care compară cheia străină cu cheia fundamentală.cod_gr.

A şi B este un tabel ce conţine toate liniile comune celor două tabele. UNION. adică ele au aceaşi structură. este un tabel ce conţine toate liniile care sunt atât în tabelul A cât şi în B. cod_gr 1 2 nr_semigrupe 2 2 nr_studenţi 25 24 denumire Timişoara NULL Codlea Braşov cod_m M1 M2 NULL M3 denum_m Timişoara Iaşi NULL Braşov Combinarea tabelelor rezultat (UNION. chiar dacă ambele coloane ar putea avea acelaşi tip de dată: de exemplu. pentru a combina rezultatele a două sau mai multe interogări într-un singur tabel rezultat. Intersecţia a două tabele. joncţiune externă totală: SELECT o.*. SMALLINT. A şi B. Ele produc un rezultat simplu adevărat/fals. Exemplu: SELECT cod_gr. cod O3 NULL O1 denumire Timişoara NULL Braşov cod_m M1 M2 M3 denum_m Timişoara Iaşi Braşov 3. m. Aceasta implică faptul că cele două tabele trebuie să conţină acelaşi numar de coloane şi că. subinterogarea poate conţine orice număr de coloane. 11 . Formatul clauzei operatorului de mulţimi este. EXISTS este adevărat dacă şi numai dacă există cel puţin o linie în tabelul rezultat returnată de către interogare şi este falsă dacă subinterogarea returnează un tabel rezultat vid. rezultatul poate include linii duble.* FROM oraşe o RIGHT JOIN municipii m ON o. putem folosi operaţiile normale cu mulţimi: reuniune.2. A şi B.cod_sec = s.denum_m. Cea mai importantă restricţie este că cele două tabele sunt compatibile (prin asociere).denum_m.* FROM oraşe o FULL JOIN municipii m ON o.denumire = m. m. Dacă CORRESPONDING este specificat dar fără clauza BY. este un tabel ce conţine toate liniile care sunt în A. ar fi fără sens să combinăm o coloană care conţine vârsta personalului cu numărul camerelor dintr-o proprietate. joncţiune externă dreaptă: SELECT o. În timp ce EXISTS şi NOT EXISTS verifică numai existenţa sau inexistenţa liniilor în tabelul rezultat al subinterogării. operaţia cu mulţimi este realizată prin coloanele care sunt comune ambelor tabele. coloanele lor corespunzătoare să aibă aceleaşi tipuri şi lungimi de date. Cei trei operatori de mulţimi sunt numiţi. EXCEPT) În SQL. atunci operaţia cu mulţimi este realizată prin coloana (coloanele) specificate. Pentru simplificare. în fiecare caz: operator [ALL][CORRESPONDING [BY {coloană [. în standardul ISO. Diferenţa a două tabele. cod O3 NULL O2 O1 EXISTS şi NOT EXISTS Cuvintele cheie EXISTS şi NOT EXISTS se folosesc numai cu subinterogări. nr_semigrupe.*. INTERSECT şi EXCEPT. INTERSECT.denumire = m. intersecţia şi diferenţa. Există restricţii asupra tabelelor care pot fi combinate folosind operaţiile cu mulţimi. dar nu sunt în B. subinterogarea urmînd una din aceste cuvinte cheie este de obicei de forma: (SELECT*…). Reuniunea a două tabele. NOT EXISTS este opusul lui EXISTS.…]}]] Dacă CORRESPONDING BY este specificat. De exemplu. Dacă ALL este specificat. nr_studenţi FROM grupe g WHERE EXISTS (SELECT * FROM secţii s WHERE g.cod_sec AND iniţiale=’M’ ). Este responsabilitatea utilizatorului de a se asigura că valorile datelor în coloanele corespunzătoare provin din acelaşi domeniu.

Lista _coloană este opţională. Prima formă permite inserarea unei singure linii într-un tabel specificat.2. în cazul în 12 . SQL presupune o listă a tuturor coloanelor în ordinea lor originală din CREATE TABLE. altele folosesc MINUS în locul lui EXCEPT. vom descrie cele 3 declaraţii SQL care sunt disponibile pentru a modifica conţinuturile tabelelor în baza de date: • INSERT se agaugă noi linii de date într-un tabel • UPDATE se modifică data existentă într-un tabel • DELETE se mută linii de date dintr-un tabel Adăugarea datei în baza de date (INSERT) Există două forme a declaraţiei INSERT. Comenzile pentru modificarea bazei de date nu sunt aşa complexe ca declaraţie SELECT.Unele dialecte ale SQL nu acceptă INTERSECT şi EXCEPT. Utilizarea operatorului EXEPT: (SELECT denumire AS oraşe FROM oraşe) EXEPT (SELECT denum_m FROM municipii). Dacă este specificată. Formatul declaraţiei INSERT este: INSERT INTO nume_tabel [(listă_coloană)] VALUES (lista_valoare_dată) nume_tabel poate fi un tabel de bază sau un view actualizabil şi lista_coloană reprezintă o listă a unuia sau mai multor nume coloane separate prin virgulă. dacă este omisă. atunci orice coloană care este omisă din listă trebuie să fie declarată ca şi coloană NULL cănd tabelul a fost creat. Actualizările bazelor de date SQL este un limbaj complet de manipulare a datelor care poate fi folosit pentru modificarea datei în baza de date precum şi interogarea bazei de date. În această secţiune. oraşe Codlea 1. Utilizarea operatorului INTERSECT: (SELECT denumire AS oraşe FROM oraşe) INTERSECT (SELECT denum_m AS oraşe FROM municipii) oraşe Braşov Timişoara 3.2. Utilizarea operatorului UNION: (SELECT denumire AS oraşe FROM oraşe WHERE denumire IS NOT NULL) UNION (SELECT denum_m AS oraşe FROM municipii WHERE denum_m IS NOT NULL) oraşe Braşov Codlea Timişoara Iaşi 2. Exemple: 1.

Formatul este: INSERT INTO nume_tabel [(lista_coloană)] SELECT… Nume_tabel şi lista_coloană sunt definite ca mai sus în cazul încasării unei singure linii. Formatul comenzii este: DELETE FROM nume_tabel [WHERE condiţia_căutare] Ca şi în declaraţiile INSERT şi UPDATE. astfel încât primul element din lista_valoare_dată corespunde primului element din lista_coloană.’. Exemplu: UPDATE cadre_didactice SET funcţia =’conf. coloana specificată este actualizată pentru toate liniile din tabel.3. SQL . • Tipul datei fiecărui element din lista_valoare_dată trebuie să fie compatibil cu tipul datei coloanei corespunzătoare.limbaj de definire a datelor (LDD) 13 .d.’ WHERE funcţia=’lect. nume_tabel poate fi numele unui tabel de bază şi un view actualizabil. Aceleaşi restricţii aplicate primei forme a declaraţiei INSERT se aplică şi aici. numai acele linii care satisfac condiţia_căutare sunt actualizate. al doilea element din lista_valoare_dată corespunde celui de-al doilea element din lista_coloană. în schimb. Ştergerea datei din baza de date (DELETE) Declaraţia DELETE permite ştergerea liniilor dintr-un tabel specificat. Dacă este omisă. Dacă condiţia_căutare este specificată. Condiţia_căutare este opţional. Acesta nu şterge tabelul. Modificarea datei în baza de date (UPDATE) Declaraţia UPDATE permite schimbarea conţinutului liniilor existente dintr-un tabel specificat. dacă se doreşte ştergerea conţinutul tabelului şi definiţia tabelului. Liniile inserate în tabelul specificat sunt identice cu cele din tabelul rezultat produs de subselect. Dacă clauza WHERE este specificată. Clauza SELECT poate fi orice declaraţie valabilă SELECT. dacă este omisă. Exemplu: INSERT INTO oraşe VALUES (‘O5’. Exemplu: INSERT INTO oraşe (SELECT cod_m. Noile valoare_dată trebuie să fie compatibile cu tipul de dată pentru coloana corespunzătoare. toate liniile sunt şterse din tabel. denum_m FROM municipii). Formatul comenzii este: UPDATE nume_tabel SET nume_coloană 1=valoare_dată 1[. Exemplu: DELETE FROM cadre_didactice WHERE funcţia=’lect. ş.care opţiunea DEFAULT nu a fost folosită când s-a creat coloana. A doua formă a declaraţiei INSERT permite copierea mai multor linii din una sau mai multe tabele în altele. numai acele linii care satisfac condiţia sunt şterse. Lista_valoare_dată trebuie să se potrivească cu lista coloană după cum urmează : • Numărul elementelor din ambele liste trebuie să fie acelaşi • Trebuie să fie o corespondentă directă între poziţia elementelor din ambele liste. Clauza SET specifică numele unei sau mai multor coloane care urmează să fie actualizate. 1. declaraţia DROP TABLE. Clauza WHERE este opţională. ‘Deva’).’. nume_coloană 2= valoare_dată 2…] [WHERE condiţie_căutare] Nume_tabel poate fi numele unui tabel de bază sau un view actualizabil. trebuie folosită.a.m.

view-uri. o lungime poate fi specificată să indice maximul numărului de caractere conţinute în coloane (lungimiea implicită este 1). Caracterele care pot fi folosite într-un identificator SQL definit de utilizator trebuie să apara într-un set de caractere. rapoarte şi indexuri). ASCII este una din seturile utilizate în comun astăzi. Datele caracter Datele caracter conţin o secvenţă de caractere dintr-un set de caractere definite de implementator. următoarele două declaraţii au fost prevăzute de multe SGBD: CREATE INDEX DROP INDEX Aceste declaraţii sunt folosite pentru a crea. FLOAT. Un caracter string poate fi definită ca avînd o lungime fixă sau variabilă. NUMERIC. INTEGER. cifrele 0…9 şi caracterele subliniate ( _ ). Dacă stringul este definit cu lungime variabilă şi introducem un string cu câteva caractere mai puţin decât această lungime. DOUBLE PRECISION TIMESTAMP SMALLINT Uneori pentru scopuri de manipulare şi conversie. • Un identificator nu poate conţine spaţii. Identificatorii SQL Identificatorii SQL sunt folosiţi pentru a identifica obiectele în baza de date. numai acele caractere introduse sunt rezervate. TIME. care conţine literele mari A…Z. Este. tipurile de date caracter şi bit sunt atribuite tipurilor de date string.1. Înainte de a considera declaraţiile LDD. tabele şi indexuri. 1. Standardul ISO prevede următorul set de caractere. În această secţiune. pe scurt. discutăm sintaxa identificatorilor SQL şi tipurile de date SQL care pot fi folosite în definirea coloanelor tabel. Dacă stringul este definit cu lungime fixă. cum să creăm şi să distrugem scheme. REAL. deoarece ele împart proprietăţisimilare. Formatul pentru specificarea unui tip de dată caracter este: CHARACTER [VARYING][length] CHARACTER can be abbreviated to CHAR and CHARACTER VARYING to VARCHAR. INTERVAL.3. adică este definită de către distribuitorul dialectului particular SQL. Următoarele restricţii sunt impuse pe un identificator: • Un identificator nu poate fi mai lung decât 128 de caractere (multe dialecte au o limită mai mică decât aceasta). tabele.Limbajul de definire a datei SQL (LDD) ne permite crearea şi distrugerea obiectelor bază de dată (scheme. schimba sau distruge structurile care alcătuiesc schema conceptuală. Principalele declaraţii 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. Când o coloană caracter string este definită. Tipurile de date ISO SQL Există 6 tipuri de date scalare SQL definite în standardul ISO. literele mici a…z. prezentate în tabelul care urmează: Tipul de dată caracter bit exact numeric aproximativ numeric dată-timp interval Declaraţii VARCHAR BIT VARYING DECIMAL. • Un identificator trebuie să înceapă cu o literă. DATE. de asemenea.3.2. astfel folosindu-se mai puţine spaţii. şi exact numeric şi aproximativ numerice sunt atribuite tipurilor de date numeric. Astfel. şi dacă introducem un string cu câteva caractere mai puţin decât această lungime. numele rapoartelor şi coloanele. De 14 . cum ar fi numele tabelelor. caracterele exacte care pot apărea ca valorile datelor într-o coloană tip caracter vor varia. stringul este completat cu spaţii la dreapta pentru a obţine lungimea cerută. examinăm. posibilă specificarea unui set de caractere alternative. CHAR. BIT. 1. domenii.

Scala dă numărul total al zecimalelor. Precizia dă numărul total a cifrelor zecimale semnificative: adică numărul total al cifrelor. care are un număr variabil de caractere până la maximum de 20. De exemplu. MINUTE. De exemplu. SECOND. ca: bit_string BIT(4) Datele exact numerice Tipul de dată exact numeric este folosit pentru definirea numerelor cu reprezentare exactă. Numărul conţine cifre. fiecare avînd sau valoarea 0 sau 1. HOUR. Coloana vechime a tabelului cadre_didactice. care reprezintă numărul anilor . pentru a ţine lungimea fixă a stringului binar ‘0011’. numărul matricol din coloana nr_mat a tabelului cadre_didactice.99.999. NUMERIC şi DECIMAL generează numere în scriere zecimală. INTEGER este folosit pentru numere mari pozitive sau negative întregi. Există mai multe moduri de a specifica un tip de dată exact numeric: NUMERIC [precision [. iar precizia implicită este definită de limbaj.2E-4. 10E3. Valoarea implicită a scalei este întotdeauna 0. pot fi rezervate mai puţine spaţii de stocare pentru dată. un punct zecimal opţional şi un semn opţional. intervale de timp şi intervale ale unei zile. -0.exemplu. declarăm o coloană bit_string. Un caz special survine în cazul datelor exact numerice întregi. Ca exemple putem da date calendaristice.2) care poate manipula o valoare până la 9. ca de pildă numerele reale. adică o secvenţă de cifre binare. scale]] DECIMAL [precision [. SMALLINT este folosit pentru numere mici pozitive sau negative întregi. incluzînd zecimalele dar excluzînd punctul. De exemplu. +5.345 are precizia 5 şi scala 3. Ultimele două câmpuri specifică ora şi minutul pentru anumite zone geografice. scale]] INTEGER SMALLINT INTEGER poate fi prescurtat prin INT şi DECIMAL prin DEC. Datele aproximativ numerice Tipul de dată aproximativ numeric este folosit pentru definirea numerelor care nu au o reprezentare exactă. este similar notaţiei stiinţifice în care un număr este scris ca o putere de zece. MONTH. Un tip de dată exact numeric conţine o precizie şi o scală. Standardul ISO foloseşte pentru acest tip de dată cuvintele rezervate: YEAR. sau punct float. 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. 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. Aproximativ numeric. care are o lungime fixă de 4 caractere. Formatul pentru specificarea tipului de dată bit este similar cu cel al tipului de dată caracter: BIT [VARYING][lenght] De exemplu.2E6. Trei tipuri ale acestui tip de date sunt acceptate: DATE TIME [time_precision][WITH TIME ZONE] 15 . este declarat ca: nr_mat CHAR(4) Coloana nume a tabelului cadre_didactice. TIMEZONE_HOUR şi TIMEZONE_MINUTE. valoarea absolută maximă care poate fi stocată în acest tip de dată poate fi 32767. valoarea exact numerică -12. este declarată ca: nume VARCHAR(20) Datele bit Tipul de date bit este folosit pentru definirea stringurile bit.999. Specificînd acest tip de dată. DAY.

TIMESTAMP reprezintă datele calendaristice şi timpul. Declaraţia de definire a schemei are forma (simplificată) următoare: CREATE SCHEMA [nume | AUTHORIZATION creator-identificator] De aceea. care are forma următoare: DROP SCHEMA nume [RESTRICT | CASCADE] Dacă RESTRICT este specificat. comparaţii. Clasa an-lună poate conţine numai câmpurile YEAR şi/sau MONTH. Time_precision reprezintă unitatea de măsură a câmpului SECOND. O schemă poate fi distrusă folosind declaraţia DROP SCHEMA. MONTH şi DAY. Printre altele. declaraţia SQL este: CREATE SCHEMA sql-schemă AUTHORIZATION Ionescu. Standardul ISO defineşte prin implementare mecanismul pentru crearea şi distrugerea cataloagelor şi furnizează mecanisme pentru crearea şi distrugerea schemelor. Conform standardului ISO. 16 . Formatul pentru specificarea tipului da dată interval este: INTERVAL {{start_câmp TO sfârşit_câmp} | câmp_dată-timp} start_câmp=YEAR|MONTH|DAY|HOUR|MINUTE [(precizia câmpului principal al intervalului)] sfârşit_câmp=YEAR| MONTH|DAY|HOUR|MINUTE|SECOND [(precizia zecimalelor câmpului secundar al intervalului)] câmp_dată-timp=start_câmp|SECOND [(precizia câmpului principal al intervalului [. schema trebuie să fie vidă sau operaţia eşuează. relaţiile şi alte obiecte ale bazei de date există într-un mediu. MINUTE. Dacă nu este specificat acesta este implicit 0 în TIME fiind vorba de secunde. HOUR. Crearea unei baze de date Procesul de creare a bazei de date diferă semnificativ de la produs la produs.precizia câmpului secundar al intervalului])] zecimalelor În toate cazurile precizia implicită a câmpului start_câmp este 2. dacă creatorul unei scheme “sql-schemă” este Ionescu. domenii. HOUR.3. Obiectele dintr-o schemă pot fi tabele. SECOND. Există două clase de date interval: intervale an-lună şi intervale zi-timp. O schemă este o colecţie specificată a obiectelor bazei de date care sunt legate una de alta într-un anumit mod (toate obiectele din baza de date sunt descrise într-o schemă sau alta). Dacă CASCADE este specificat. fiecare mediu este alcătuit dintr-unul sau mai multe cataloage şi fiecare catalog este alcătuit dintr-un set de scheme. MONTH. view-uri. Date interval Tipul de dată interval este folosit pentru a reprezenta intervale de timp.3. MINUTE şi SECOND. SECOND. iar clasa zi-timp poate conţine o selecţie invecinată din DAY.9999 secunde. Cuvântul cheie WITH TIME ZONE controlează prezenţa câmpurilor TIMEZONE_HOUR şi TIMEZONE_MINUTE. TIME este folosit pentru a reprezenta timpul folosind cuvintele rezervate HOUR. operaţia aranjează în cascadă toată obiectele asociate schemei în ordinea definită înainte. Toate obiectele dintr-o schemă au acelaşi proprietar şi împart un număr de valori implicite. DAY. translaţii şi seturi de caractere.TIMESTAMP [time_precision][ WITH TIME ZONE] DATE este folosit pentru a reprezenta datele calendaristice folosind cuvintele rezervate YEAR. 1. Exemplu: INTERVAL YEAR(2) TO MONTH reprezintă un interval de timp cu o valoare între 0 ani 0 luni şi 99 ani 11 luni. iar în TIMESTAMP valoarea implicită este 6 fiind vorba de microsecunde. 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. care este şi valoarea implicită dacă nici unul din calificative nu este specificat. MINUTE. Fiecare tip de dată interval este alcătuit dintr-un subset învecinat al câmpurilor: YEAR.

În unele implementări. Distrugerea unui tabel (DROP TABLE) Cu timpul structura unei baze de date se va schimba. • a şterge o valoare implicită a coloanei. • a stabilii o valoare implicită pentru o coloană. pierdute sau nu sunt aplicabile. Valoarea implicită ISO este NULL. care are următoarea sintaxă principală: CREATE TABLE nume_tabel (nume_coloană tip_dată [NULL | NOT NULL][. nume CHAR(15) NOT NULL. O folosire uzuală a comenzii DROP TABLE este de a corecta greşelile făcute la crearea unui tabel. Un null este diferit de spaţiu sau 0 şi este folosit pentru a reprezenta date dacă acestea nu sunt disponibile.…]) Această comandă crează un tabel numit nume_tabel alcătuit din una sau mai multe coloane al câmpului tip_dată specificat. Dacă CASCADE este specificat SQL automat şterge toate obiectele dependente de tabel (şi obiectele dependente de aceste obiecte). ci şi toate liniile din interiorul acesteia. Crearea unui tabel (CREATE TABLE) Avînd creată structura bazei de dată. prenume CHAR(15) NOT NULL. Specificatorul NULL este folosit pentru a indica dacă unei coloane îi este permis sau nu să conţină null-uri. SQL nu permite comenzii DROP TABLE să continue. tabele noi fiind create iar altele vechi nu vor mai fi necesare. • a şterge o restricţie a tabelului. funcţia CHAR(10) vechime SMALLINT ). Putem şterge un tabel suplimentar din baza de date folosind declaraţia DROP TABLE. Modificarea structurii unui tabel (ALTER TABLE) Standardul ISO furnizează declaraţia ALTER TABLE pentru modificarea structurii unui tabel odată ce a fost creat. asupra căruia acţionează comanda. Dacă NULL este specificat. Crearea unui tabel se face folosind comanda CREATE TABLE. în locul declaraţiei CREATE SCHEMA este folosită declaraţia următoare: CREATE DATABASE nume_bază-date. De exemplu. care are formatul: DROP TABLE nume_tabel [RESTRICT | CASCADE] De exemplu pentru a distruge tabelul cadre_didactice folosim comanda: DROP TABLE cadre_didactice. sistemul acceptă null-uri. sistemul respinge orice încercare de inserare a unui null în coloane.În prezent declaraţiile CREATE şi DROP SCHEMA nu sunt încă larg implementate. pentru crearea tabelului cadre_didactice avem: CREATE TABEL cadre_didactice( nr_mat CHAR(4) NOT NULL. Dacă este creat un tabel cu o structură incorectă se poate folosi DROP TABLE pentru a şterge tabelul nou creat şi începe din nou. • a şterge o coloană dintr-un tabel . Când NOT NULL este specificat. Definirea declaraţiei ALTER TABLE în standardul ISO este alcătuită din 6 opţiuni pentru: • a adăuga o nouă coloană la un tabel. Formatul principal al declaraţiei este: 17 . putem acum crea structurile tabelelor de bază a relaţiilor pentru a fi localizate în baza de date. Dacă se doreşte ştergerea liniilor din tabel dar să se reţină structura tabelului trebuie folosită declaraţia DELETE. Observăm că această comandă şterge nu numai tabelul specificat. • a adăuga o nouă restricţie pentru tabel. Dacă RESTRICT este specificat în comanda DROP TABLE şi există orice alte obiecte a căror existenţă depinde de existenţa tabelului.

În unele dialecte. Această clauză are un calificativ opţional care ne permite să specificăm dacă acţiunea DROP este în cascadă sau nu. CREATE UNIQUE INDEX nume_ind ON cadre_didactice(nume). Totuşi multe dialecte acceptă cel puţin următoarea formă a acestei comenzi: CREATE [UNIQUE] INDEX nume_index ON nume_tabel (colonă [ASC |DESC] [. deoarece valorile provenite din coloana (coloanele) indexată poate să conţină deja dubluri. de obicei. SQL avansat. UNIQUE. Dacă clauza UNIQUE este folosită. Pentru fiecare coloană putem specifica dacă ordinea este ascendentă (ASC) sau descendentă (DESC). Pentru tabelul cadre_didactice putem crea următoarele indexuri: CREATE UNIQUE INDEX matricol_ind ON cadre_didactice(nr_mat). Un view este o relaţie virtuală care nu există. Deşi indexurile pot fi create oricând. pentru a satisface criteriul de căutare particular după ce tabelul a fost folosit un timp şi a crescut în mărime. 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. De exemplu pentru a adăuga coloana “vechime” la tabelul cadre_didactice folosim comanda: ALTER TABLE cadre_didactice ADD vechime INTEGER(2). dar este produsă pe baza cerinţei unui utilizator particular. Clauza ADD COLUMN este similară cu definirea unei coloane din declaraţia CREATE TABLE. putem avea probleme dacă încercăm să creăm un index unic pe un tabel care conţine articole. atunci când tabelul de bază este creat şi sistemul nu va asigura automat unicitatea cheii principale. FOREIGN KEY sau CHECK. De aceea este mai bine să creăm indexuri unice. Prezenţa unui index poate îmbunătăţi simţitor performanţa unei interogări. Definiţie_restricţie_tabel este una din clauzele: PRIMARY KEY. Declaraţia ALTER TABLE nu este disponibilă în toate dialectele SQL. Clauza DROP COLUMN specifică numele coloanei ce trebuie ştearsă din definiţia tabelului. declaraţia nu poate fi folosită pentru a muta o coloană existentă dintr-un tabel. Ştergerea unui index (DROP INDEX) Dacă creăm un index pentru un tabel de bază şi mai târziu decidem că nu mai este necesar. 18 . valoarea implicită fiind ASC. cel puţin pentru coloane cheie principale. Avem acelaş concept ca şi la calificativul RESTRICT | CASCADE a declaraţiei DROP TABLE. de fapt. View-uri Un view este rezultatul dinamic a uneia sau mai multor operaţii relaţionale care operează pe relaţii de bază pentru a produce altă relaţie.4. DROP INDEX are formatul: DROP INDEX nume_index Declaraţia următoare va şterge indexul creat în exemplul anterior: DROP INDEX matricol_ind.ALTER TABLE nume_tabel [ADD [COLUMN] nume_coloană tip_dată [NOT NULL][UNIQUE] [DEFAULT opţiune_implicită][CHECK(condiţie_căutare)]] [DROP [COLUMN] nume_coloană [RESTRICT | CASCADE]] [ADD [CONSTRAINT [nume_restricţie]] definiţie_restricţie_tabel] [DROP CONSTRAINT nume_restricţie [RESTRICT | CASCADE]] [ALTER [COLUMN] SET DEFAULT opţiune_implicită] [ALTER [COLUMN] DROP DEFAULT] unde parametrii sunt definiţi ca şi în declaraţia CREATE TABLE.…]) Coloanele specificate alcătuiesc cheia index şi ar trebui listate în ordine descrescătoare. Crearea indexurilor nu este standardizată în SQL. unicitatea coloanei sau combinaţiei de coloane indexate va fi decretată de către sistem. 1. în baza de date. Indexurile pot fi create numai în tabele de bază nu şi în view-uri. Indexurile sunt create. declaraţia DROP INDEX şterge indexul din baza de date.

Dacă WITH CHECK OPTION este specificat.denumire.000 900.’. GROUP BY s.…])] AS subselect [WITH [CASCADED | LOCAL] CHECK OPTION] Se poate repartiza.000 2. Crearea unui view (CREATE VIEW) Formatul declaraţiei CREATE VIEW este: CREATE VIEW nume_view [(nume_coloană [. care pemite restricţionarea accesului utilizatorilor la anumite linii ale unui tabel: CREATE VIEW vechime_cadre AS SELECT * FROM cadre_didactice WHERE vechime >= 25.cod_gr FROM secţii s.1. SQL asigură faptul că dacă o linie nu ajută la satisfacerea clauzei WHERE a interogării definite a view-ului. în practică diferite tipuri de view-uri sunt folosite pentru diferite scopuri: 1. Wiew orizontal. grupe g WHERE s. opţional.denumire. Dacă o listă a numelor de coloană este specificată.4. Lista numelor de coloană trebuie să fie specificată în cazul în care există orice ambiguitate în numele unei coloane. aceasta nu este adăugată la tabelul view-ului. vechime 25 25 28 salariu 900. conf. conf. Subselectul este cunoscut ca interogare definită. prenume FROM cadre_didactice WHERE funcţia = ‘lect. Deşi toate view-urile sunt create în acelaşi mod.cod_sec = g. View vertical care pemite restricţionarea accesului utilizatorilor la anumite coloane ale unui tabel ale unui tabel: CREATE VIEW cadre_lect AS SELECT nr_mat.000 950.1. secţia Matematică Matematică Informatică Matematică-fizică Matematică-fizică Fizică-chimie grupa 1 2 1 1 2 1 19 . Aceasta se poate întâmpla dacă subselectul include coloane calculate şi subclauza AS nu a fost folosită pentru a numi astfel de coloane sau produce două coloane cu nume identice ca rezultat a unei joncţiuni. nr_mat 1113 1114 1115 nume Barbu Ştefan Savu prenume Traian Elena Alexandru funcţia conf. Dacă lista numelor de coloană este omisă.cod_sec. grupa) AS SELECT s. un nume pentru fiecare coloană din view. g. nr_mat 1111 1116 nume Popa Ionescu prenume Ioan Mircea 3. View grupat şi view joncţionat: CREATE VIEW secţii_grupe (secţia. atunci trebuie să aibă acelaşi număr de elemente ca şi numărul coloanelor produse de către subselect. nume. fiecare coloană din view ia numele coloanei corespunzătoare din subselect.

Dacă RESTRICT este specificat şi există orice alte obiecte a căror existenţă depinde de existenţa view-ului ce urmează a fi şters. În plus.4. Securitatea 20 .5. restructurate sau redenumite). reuniune (UNION). deşi există variaţii considerabile între dialecte. fiecare linie adăugată prin view nu trebuie să încalce restricţiile de integritate ale tabelului. • Un view grupat nu poate fi joncţionat cu un tabel sau un view.4. Avantaje şi dezavantaje ale view-urilor Avantaje. 3. Valoarea imlicită este RESTRICT.2. şterge toate obiectele de referinţă ale view-ului. În particular.4. adică view-ul trebuie să aibă un singur tabel sursă asupra căruia utilizatorul are privilegiile cerute. DROP VIEW şterge toate obiectele dependente. o expresie sau o funcţie complexă) şi nici o coloană nu apare mai mult decât o dată. relaţii schimbate. coloane adăugate sau şterse. putem să ne aşteptăm la faptul că dacă un view este actualizat atunci tabelul (tabelele) va reflecta acea schimbare. Dacă un tabel existent este rearanjat sau dezbinat. nemodificabilă a structurii bazei de date. • Fiecare element din lista SELECT a interogării definitorii este un nume de coloană (mai degrabă decât o constantă. Universalitatea Schimbările oricăror tabele în interogarea definită sunt imediat reflectate în view.4. vechiul tabel poate fi recreat prin definirea unui view joncţionînd noile tabele. intersecţie (INTERSECT) şi diferenţă (EXCEPT). Standardul ISO specifică view-urile care trebuie să fie actualizabile într-un sistem corespunzător standardului. • Nu există clauzele GROUP BY şi HAVING în interogarea definitorie. Independenţa datei Un view poate prezenta o imagine consistentă. putem şterge view-ul vechime_cadre folosind declaraţia: DROP VIEW vechime_cadre. • Dacă o coloană din view se bazează pe o funcţie complexă. Definiţia dată în standardul ISO este că un view este actualizabil dacă şi numai dacă: • DISTINCT nu este specificat. atunci coloana poate apărea numai în clauzele SELECT şi ORDER BY ale interogării care accesează view-ul. De exemplu. În cazul dezbinării unui tabel.4. Actualizabilitatea view-urilor Toate actualizările unui tabel sunt imediat reflectate în toate view-urile care cuprind acel tabel. o astfel de coloană nu poate fi folosită într-o clauză WHERE şi nu poate fi folosită ca argument pentru o funcţie complexă în orice interogare bazată pe view. adică liniile duble nu trebuie eliminate din rezultatele interogării. atunci definirea view-ului nu necesită schimbări. aceasta exclude orice view-uri bazate pe o joncţiune. 1. 1. tabele dezbinate. 2. un view poate fi definit astfel încât utilizatorul poate continua să vadă vechiul tabel. Analog.1. De aceea.3. • Clauza WHERE nu include nici un SELECT intercalat care se referă la tabelul din clauza FROM. 1. chiar dacă tabelele sursă principale sunt schimbate (de exemplu. 1. Dacă CASCADE este specificat. Cu alte cuvinte. atunci acest view trebuie să satisfacă aceste condiţii. cu alte cuvinte. Ştergerea unui view (DROP VIEW) Un view este şters din baza de date cu declaraţia: DROP VIEW nume_view [RESTRICT | CASCADE]. Dacă tabelul sursă însăşi este un view. Dacă coloanele sunt adăugate sau şterse dintr-un tabel şi aceste coloane nu sunt cerute de către view. • Clauza FROM specifică numai un tabel. comanda este respinsă. SGBD-ul trebuie să poată să copieze orice linie sau coloană înapoi în linia sau coloana sa din tabelul sursă. Restricţii asupra view-urilor Standardul ISO impune câteva restricţii importante în crearea şi folosirea view-urilor.

Performanţa Există un neajuns care apare când folosim un view. Rezoluţia view-ului cere resurse în plus calculatorului. Selectabilitatea View-urile furnizează posibilitatea ca aceleaşi tabele principale să poată fi văzute de diferiţi utilizatori. Restricţia actualizării În unele cazuri un view nu poate fi actualizat. SQL asigură faptul că nici o linie care nu satisface clauza WHERE a interogării definite nu este niciodată adăugată la orice tabel principal prin view. în alte cazuri poate fi mai problematic. câteva dezavantaje ale view-urilor SQL: 1. 6. atunci * se referă la coloanele tabelului de bază existent când a fost creat view-ul. transformînd interogări multi-tabel în interogări 1-tabel.Fiecare utilizator poate avea privilegiul de a accesa baze de date numai printr-un mic set de view-uri. astfel. Dezavantaje. 2. 3. Deşi view-urile furnizează multe beneficii semnificative. atunci aceste coloane nu vor apărea în view. astfel restrângînd şi controlînd accesul la baza de date a fiecărui utilizator. prin aceasta asigurînd integritatea view-ului. De exemplu. un view definit printr-o interogare complexă multi-tabel poate lua un timp îndelungat pentru a fi prelucrat pe când rezoluţia view-ului trebuie să joncţioneze tabelele de fiecare dată când view-ul este accesat. în diferite moduri. Complexitatea redusă Un view poate simplifica interogările prezentarea datelor din mai multe tabele într-un singur tabel şi. 21 . în afară de cazul când view-ul este şters şi recreat. Dacă coloanele sunt ulterior adăugate la tabelul de bază. În unele cazuri acest lucru va fi neglijabil. care conţine date potrivite acelui utilizator. există de asemenea. Restricţia structurii Structura unui view este determinată la timpil creării lui. 5. Dacă interogarea definită a fost de forma SELECT * FROM …. Integritatea datei Dacă WITH CHECK OPTION a declaraţiei CREATE VIEW este folosit. 4.

Sign up to vote on this title
UsefulNot useful