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

2. salariu FROM cadre_didactice. Recuperarea liniilor unui tabel doar pentru anumite coloane ale: 3 . SELECT este comanda cea mai des folosită în SQL. Pentru cuvintele rezervate avem următoarea semnificaţie: FROM specifică tabelul sau tabelele care vor fi folosite. SELECT specifică coloanele care vor apărea în rezultatul interogării. Există mai multe variante ale acestei comenzi. Singurele două clauze obligatorii sunt primele două: SELECT şi FROM celelalte fiind opţionale. SELECT * FROM cadre_didactice. Operaţia SELECT este închisă. nume. totuşi exemplele care urmează ilustrează principalele variante ale acestei declaraţii.000 950. Forma generală a declaraţiei SELECT este : SELECT [DISTINCT|ALL]{* | [expresie_coloană [AS nume_nou]][. Recuperarea tuturor liniilor unui tabel: SELECT nr_mat. lect. vechime.000 900.000 400. alias reprezintă o prescurtare a numelui de tabel. Este o comandă extrem de puternică capabilă de a echivala în algebra relaţională selecţia.1. Ordinea clauzelor în declaraţia SELECT nu poate fi schimbată.…] [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. 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. prenume. funcţia.000 2. HAVING selectează grupurile care respectă condiţia de căutare. proiecţia şi joncţiunea într-o singură declaraţie. conf. 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. conf. ORDER BY ordonează valorile returnate după coloanele specificate.…]} FROM nume_tabel [alias][. Interogări simple 1. conf. rezultatul interogării unui tabel fiind tot un tabel.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. WHERE specifică liniile care trebuiesc recuperate cu ajutorul unor condiţii.000 700. vechime 15 20 25 25 28 18 salariu 400.000 900. GROUP BY grupează toate liniile din tabele care au aceeaşi valoare pe coloana specificată.

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

nume care ar putea fi de referinţă ulterior. liniile tabelului rezultat a unei interogari SQL nu sunt aranjate într-o anumită ordine. Identificatorul de coloană poate fi. Apartenenţa la o mulţime.000 900. • adresa LIKE ‘%Popescu%’ înseamnă o secvenţă de caractere de orice lungime care conţine Popescu. • adresa NOT LIKE ‘H%’ înseamnă că numele nu poate începe cu H. • adresa LIKE ‘%e’ înseamnă orice secvenţă de caractere de lungime cel puţin 1 cu ultimul caracter e. prenume. Testează dacă valoarea unei expresii aparţine unui set de valori (IN/NOT IN): SELECT nr_mat. SQL are două caractere speciale: % reprezintă orice secvenţă de zero sau de mai multe caractere. Compatibilitatea. prenume FROM cadre_didactice WHERE nume LIKE ‘P%’.000 2. _ reprezintă orice caracter singular. prenume. Testează dacă un şir se potriveşte cu un model specificat (LIKE/NOT LIKE).d. salariu FROM cadre_didactice WHERE salariu BETWEEN 500. nr_mat 1111 (1 linie) nume Popa prenume Ioan 5.000 900. Testează dacă o coloană are o valoare nulă (necunoscută) (IS NULL/IS NOT NULL). Nul. 25). ş. nume. vechime FROM cadre_didactice WHERE vechime IN (20.m. Şir. 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. putem sorta rezultatele unei interogări folosind clauza ORDER BY din declaraţia SELECT. 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ă. 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ă. Celelalte caractere se folosesc normal. SELECT nr_mat.a. unele dialecte 5 . fie un nume de coloană. Testează dacă valoarea unei expresii este inclusă într-un şir de valori specificate (BETWEEN/NOT BETWEEN): SELECT nr_mat. Totuşi. nr_mat nume 1112 Liana 1113 Barbu 1114 Ştefan prenume Carmen Traian Elena salariu 700. iar celelalte pot fi orice caracter. De exemplu: • adresa LIKE ‘H%’ înseamnă că primul caracter trebuie să fie H.000. Clauza ORDER BY (rezultate de sortare) În general.nr_mat 1113 1114 1115 nume Barbu Ştefan Savu prenume Traian Elena Alexandru salariu 900. nume. 2 pentru al doilea. Clauza ORDER BY conţine o listă de identificatori de coloană pentru ca rezultatul să fie sortat şi separat prin virgulă.000 950.000 900. • adresa LIKE ‘H_ _ _’ înseamnă că trebuie să fie exact patru caractere în şir primul fiind H.Totuşi. nume. nr_mat 1112 1113 1114 nume Liana Barbu Ştefan prenume Carmen Traian Elena vechime 20 25 25 4.000 3.000 AND 900.

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

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

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

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

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

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

SQL presupune o listă a tuturor coloanelor în ordinea lor originală din CREATE TABLE. dacă este omisă. 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. În această secţiune.2. în cazul în 12 . Lista _coloană este opţională. Utilizarea operatorului EXEPT: (SELECT denumire AS oraşe FROM oraşe) EXEPT (SELECT denum_m FROM municipii).2. 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. atunci orice coloană care este omisă din listă trebuie să fie declarată ca şi coloană NULL cănd tabelul a fost creat. 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. Prima formă permite inserarea unei singure linii într-un tabel specificat. oraşe Codlea 1. altele folosesc MINUS în locul lui EXCEPT. Dacă este specificată. 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. Comenzile pentru modificarea bazei de date nu sunt aşa complexe ca declaraţie SELECT. Exemple: 1.Unele dialecte ale SQL nu acceptă INTERSECT şi EXCEPT. 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ă.

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

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

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

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

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

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

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

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

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

Sign up to vote on this title
UsefulNot useful