Sunteți pe pagina 1din 64

0

Introducere

Bazele de date sunt fiiere care conin informaii. De obicei reprezentarea informaiilor din fiierele de baze de date se red sub forma unui tabel. Pentru crearea, actualizarea i citirea bazelor de date s-au creat limbaje speciale i programe numite SGBD-uri, sisteme de gestionare a bazelor de date care interpreteaz limbajele de programare pentru baze de date Terminologie SQL este un limbaj de programare standard pentru crearea, actualizarea i regsirea informaiilor stocate n bazele de date. A fost creat iniial n cadrul IBM de ctre Donald D. Chamberlin i Raymond F. Boyce n anii 1970 pentru manipularea datelor n sistemul cvasirelaional de baze de date, System R. MySQL este un SGDB relaional(RDBMS) creat de ctre Michael Widenius i numit dup fiica sa, My. MySQL este open source i liceniat GPL(General Public Licence). Dezvoltarea utilitarului MySQL a fost continuat de ctre compania MySQL AB fondat n 1995 fiind una dintre cele mai mari companii productoare de utilitare open source. n 2008 aceasta a fost achiziionat de Sun Microsystems iar n 2010 Oracle achiziioneaz Sun Microsystems iar MySQL AB devine parte a Oracle Corporation. SQL: NU este un limbaj structurat(nu gsim clauze IF-THEN, FOR..) este un limbaj declarativ(se specific ce dorim s facem i nu cum dorim s facem(paradigma procedural)) este un limbaj apropiat de limba englez i deci uor de nvat are puine cuvinte cheie ceea ce l face de asemenea uor de nvat este un limbaj nglobat, interactiv(instruciunile SQL pot fi incluse n programe scrise n alte limbaje de programare exist aplicaii care ofer suport pentru interconectarea limbajelor majore(Visual Basic, Java, PHP, C/C++, Python..) la MySQL).

Baze de date MySQL


www.opensource.org

OpenBooklet padre_cosmin

SGBD tip SQL Server este partea de server a unei configuraii client/server stocnd fiiere de baze de date i rspunznd la solicitrile SQL ale aplicaiilor client. Un client poate fi o aplicaie ce ruleaz pe acelai calculator sau pe un calculator la distan. SGBD de tip desktop se instaleaz i ruleaz local. Poate consta n ntr-o aplicaie stand-alone care s permite crearea i ntreinerea bazelor de date sau poate s fie un client care comunic cu un SGBD de tip Server. Exemple de servere SQL: Microsoft SQL Oracle MySQL PostgreSQL Exemple de sisteme desktop: Microsoft Access FileMakerPro Pentru a continua vom intra pe situl http://dev.mysql.com/downloads/ i vom descrca pachetul MySQL Community Server. Nu voi trata n aceast lucrare pasii de instalare a programului dar trebuie aleas opiunea Server pentru ca bazele de date s fie salvate pe calculatorul dumneavoastr. Spre finalul instalrii vi se va cere o parol de root. De lucrat, vom lucra n command promptul MySQL. 1) Pentru a accesa terminalul(command promptul) pe Windows MySQL mergem n Start--> MySQL --> MySQL Command Line. La deschiderea terminalului MySQL vi se cere parola pe care ai setat-o la instalare. Dup ce ai introdus parola, linia de comand MySQL arat mysql>_ 2) Instalarea MySQL-ului pe Ubuntu se poate face din Ubuntu Software Center unde cutm MySQL Server. Dup instalare putem accesa terminalul mysql astfel intrnd n terminalul linux i scriind $ sudo mysql -u root p --> prima dat vi se cere parola de superuser al sistemului de operare --> apoi vi se cere parola de root a MySQL Server-lui pe care ai setat-o la instalarea programului Dac nu este nicio parol selectat pentru mysql, folosim comanda $ mysqladmin -u root password myPassword n terminalul linux.

* Linia de comand SQL este case unsenzitive, nu conteaz dac scriei cu majuscule sau minuscule!!!! * Toate liniile de comand se termin n punct i virgul ';' * Se pot scrie mai multe instruciuni una dup alta, dar trebuie terminate fiecare cu ';' * Comentariile pe un singur rnd se scriu dup caracterul '#' sau '- -' iar cele pe mai multer rnduri se scriu intre /* ... */ > # acesta e un comentariu > -- acesta e tot un comentariu > /* acesta e un comentariu /*> pe mai multe rnduri */ Comenzi utile diverse mysql> SELECT VERSION(); #returneaz versiunea de MySQL mysql> exit; # sau >quit; permite ieirea din prompt-ul mysql $ mysql -?; #permite afiarea unei liste de opiuni pentru prompt mysql> mysql -? | more # afiaz o list mai detaliat sub forma unor ecrane printre care se navigheaz cu tasta Space, q pt. a iei mysql> use baza_date; #deschide baza de date 'baza_date' mysql> mysql -t baza_date < sql_script; # -t plaseaz rezultatele ntrun tabel(se omite aceast opiunea dac se dorete o ieire delimitat cu tab-uri), baza_date baza de date pe care se opereaz, sql_script este un fiier script ce conine o niruire de operaii care se executa asupra bazei de date mai sus menionate mysql> mysql -- ansi; #permite utilizarea sintaxei ANSI SQL n locul celei MySQL implicite $ mysql -h host -u user -p dbname #atunci cnd folosim o aplicaie client i dorim s ne conectm la server trebuie s specificm host numele gazdei, user-numele utilizatorului, dbname numele bazei de date utilizat. Apoi MySQL va solicita o parol

PROIECTAREA BAZELOR DE DATE


Bazele de date pot fi structurate dup unul din urmtoarele modele: modelul ierarhic modelul concurenial modelul reea modelul relaional(cel mai folosit) SQL implementeaz destul de fidel modelul relaional. Elementul de baz al bazelor de date este tabelul. Tabelul este un element bidimensional folosit pentru reinerea datelor.

Un SGBD conine dou tipuri de tabele, tabele utilizator-tabele definite de utilizator, tabele sistem-sau metadate conin date despre baza de date: informaii structurale, detalii fizice, statistici despre performan i i setri de securitate. Bazele de date pe care le vom crea i modifica prin SQL se vor supune regulilor modelului relaional deci tabelele vor fi legate, interconectate ntre ele prin mecanisme cu chei. Vom vedea cum se face aceasta n capitolele urmtoare. exemplu de tabel afiat de consola mysql.

n cadrul bazelor de date, rndurile unui tabel se numesc nregistrri iar coloanele cmpuri.
Putem considera o baz de date ca o colecie de unul sau mai multe tabele. Coloanele unui tabel: fiecare coloan reprezint un atribut, o proprietate a individului, obiectului ale crui proprieti au fost memorate pe rndul respectiv; fiecare coloan are permite reinerea unor valori restricionate ntrun anumit interval; intrrile n coloane au o singur valoare; ordinea coloanelor nu este important; fiecare coloan are un nume unic n respectivul tabel. Rndurile unui tabel: fiecare rnd descrie o entitate, reine proprietile pe care am dorit s le evideniem ale unei persoane, obiect; fiecare rnd e unic, nu vom retine de dou proprietile unei persoane, obiect NU pot exista dou rnduri identice; ordinea rndurilor nu este important; fiecare rnd e identificat unic prin cheia sa <vom vedea mai trziu ce nseamn asta>.

1.2 Chei primare(PRIMARY KEY) Pentru a accesa informaia din tabel i mai mult, pentru a realiza legturile ntre tabele, legturi specifice bazelor de date relaionale, avem nevoie de mecanisme speciale de prelucrare. Tabelele pot fi accesate prin numele lor. Rndurile coninute de tabel nu au nume de aceea necesit un mecanism diferit de accesare. Acesta const n crearea unei coloane speciale numit cheie primar. Fiecare rnd dintr-un tabewl va avea o valoare unic pentru cheia sa primar. Astfel o cheie primar este: obligatorie(fiecare tabel are obligatoriu o singur cheie primar) rndurile nu sunt ordonate deci nu pot fi accesate dup poziia lor n tabel, de aceea mecanismul cu chei primare e obligatoriu unic(nu exist dou rnduri cu aceeai valoare pentru cheile lor primare) simpl sau compus(o cheie primar poate cuprinde o coloan sau mai multe dintr-un tabel, o cheie realizat printr-o singur coloan se numete cheie primar simpl, sunt de preferat cheile simple) non-null(valoarea unei chei primare nu poate fi vid) stabil(odat create, cheile primare se schimb foarte rar) ne-reutilizabil(dac se terge un rnd, nu putem asocia valoarea cheii lui primare altui rnd) minimal(e de preferat s alegem drept cheie primar o singur coloan)

n exemplul de tabel din imaginea precedent, coloana au_id este cheia primar a tabelului. Stabilirea cheii primare este crucial deoarece modificarea ei ulterioar este foarte complicat. Alegerea numelui sau prenumelui sau alegerea compus a numelui i prenumelui drept chei primare este neadecvat deoarece exist multe persoane care au acelai nume i chiar i nume i prenume i persoanele se pot cstori sau divora. Alegerea cheii primare se face prin specificarea PRIMARY KEY la definirea tabelului. 1.3 Cheie extern(FOREIGN KEY) Acum vom vedea cum se leag de fapt tabelele ntre ele. Datorit faptului c uneori dorim s facem anumite informaii ascunse despre persoanele, obiectele nregistrate sau din cauz c dorim s organizm informaia mai compartimentat, este de dorit s crem mai multe tabele. De exemplu, pentru baza de date a unei librrii, putem avea un tabel cu edituri i un tabel cu cri. Tabelul edituri va cuprinde dou coloane, una, cheia primar-aleas arbitrat, o combinaie simbolic, i cealalt coloan va cuprinde numele editurii. Deoarece vom dori la un moment dat s accesm toate crile de la o anumit editur, tabelul cri va cuprinde de asemenea o coloan cheie primar, de asemenea o combinaie simbolic, o coloan cu numele crilor dar va mai cuprinde i o alt coloan, numit cheie extern, n care se vor nregistra cheile primare ale editurilor corespunztor pentru crile din tabelul cri. Astfel cnd i vom cere serverului mysql s returneze toate crile aprute la o anumit editur, el va lua cheia primar a acelei edituri i se va duce n tabelul cri i va returna toate numele de cri care au drept cheie extern cheia primar a editurii cerute. Tabelul titles conine un cmp cheie extern cu valorile cheilor primare ale tabelului publishers. Acest lucru permite navigarea ntre tabele.

Caracteristicile cheii primare: este o coloan sau un grup de coloane dintr-un tabel ale crui valori sunt n relaie cu valorile dintr-un alt tabel sau fac referin la aceste valori; asigur faptul c rndurile dintr-un tabel au rnduri corespondente n alt tabel; tabelul care conine cheia extern este tabelul care face referire sau tabelul copil. Tabelul cellalt este tabelul la care se face referire sau tabelul printe; o cheie extern stabilete o relaie direct cu cheia primar, valorile ei sunt restricionate la valorile cheii primare din tabelul printe i plicit tipul valorilor cheii externe este acelai cu tipul valorilor cheii primare proprietate numit integritate referenial; Spre deosebire de valorile cheii primare, valorile cheii externe pot fi nule; numele de coloan al cheii externe poate fi diferit de cel al numelui de coloan al cheii primare din tabelul printe; n general, valorile cheii externe nu sunt unice; o cheie extern poate face referire la o cheie primar din acelai tabel(ex.: tabelul angajai, cheia extern a unui numr de angajai poate face referin la cheia primar a efului care este i el trecut n tabelul angajai) Un rnd orfan este un rnd din tabelul copil pentru care nu exist, n tabelul printe, nici un rnd asociat.

1.4

Tipuri de relaii

O relaie este o asociere stabilit ntre coloanele comune din dou tabele i poate fi de tipul: unu la unu unu la mai muli mai muli la mai muli

1.4.1 Unu la unu Fiecare rnd din tabelul A are cel mult un rnd corespondent n tabelul B i fiecare rnd din tabelul B are cel mult un rnd corespondent n tabelul A. Informaiile din cele dou tabele ar putea fi memorate ntr-un singur tabel dar se folosesc totui pentru a izola informaii confideniale, pentru a spori viteza de execuie a interogrilor sau pentru a evita plasarea de null-uri. O relaie de tipul unu la unu este stabilit atunci cnd cheia primar a unui tabel este n acelai timp i o cheie extern care face referire la cheia primar a unui alt tabel. Practic cheile primare ale celor dou tabele au aceleai valori. Fiecare rnd din tabelul titles poate avea cel mult un rnd corespondent n tabelul royalties i viceversa. Cheia primar a tabelului royalties este n acelai timp i cheie extern.

1.4.2 Unu la mai muli Fiecare rnd din tabelul A poate avea mai 0(zero) sau mai multe rnduri corespondente n tabelul B dar fiecare rnd din tabelul B are numai un singur rnd corespondent n A. Ex. O clas poate avea mai muli elevi dar un elev poate aparine unei singure clase. O relaie unu la mai muli se stabilete atunci cnd cheia primar a unui tabel este n acelai timp cheia extern a mai multor tabele. Fiecare rnd din tabelul publishers poate avea mai multe rnduri corespondente n tabelul titles dar fiecare rnd din titles are un singur rnd corespondent n publishers.

Relaionarea grafic a dou tabele printr-o relaie unu la mai muli. Rdcina sgeii reprezint componenta unu a relaiei, sgeata reprezint componenta mai muli a relaiei.

Unele aplicaii de baze de date permit stabilirea grafic a relaiilor dintr-o baz de date, aa arat o relaie unu la unu realizat ntr-o aplicaie grafic.

1.4.3 Mai muli la mai muli Fiecare rnd din A poate avea 0(zero) sau mai multe rnduri corespondente n tabelul B i fiecare rnd din tabelul B poate avea mai multe rnduri corespunztoare n tabelul A. Ex. un autor poate avea mai multe cri scrise i fiecare carte scris poate avea mai muli autori. O relaie de tipul mai multi la mai muli se stabilete numai prin crearea unui al treilea tabel tabel asociativ(de jonciune sau de intersecie), a crui cheie primar compus este o combinaie ntre cheile primare ale celorlalte dou tabele. Fiecare coloan din cheia compus luat separat este o cheie extern. Se produce ntotdeauna o valoare unic pentru fiecare nregistrare din tabelul asociativ i transform relaia de tipul mai muli la mai muli n dou relaii de tipul unu la mai muli. Relaie mai muli la mai muli Tabelul asociativ title_authors transform relaia de tipul mai multi la mai muli dintre tabelele titles i authors n dou relaii unu la mai muli.

Se poate stabili o relaie mai muli la mai muli fr a crea al treilea tabel, dac adugm tabelelor grupuri care se repet, dar astfel se ncarc o regul de normalizare. O relaie mai muli la mai muli se numete i relaie de tipul printecopil sau master-detaliu.

1.5

NORMALIZAREA

Unul din motivele pentru care nu se alege s se creeze doar un singur tabel, sau mult mai puine tabele, care s conin toat informaia unei baze de date ci se prefer strategiile cu chei primare i chei externe este pentru c se dorete ca tabelele s aib ct mai puin informaie redundant, s nu aib mai multe cmpuri cu aceeai informaie. Dac se elimin redundana se mrete i viteza de execuie a comenzilor SQL. De asemenea, aceast strategie face i modificarea datelor mai uoar. Normalizarea este procesul prin care baza de date este astfel proiectat nct s se reduc redundaa informaiei n tabele. Modelul relaional definete trei forme de normare: Prima form de normare 1FN A doua form de normare 2FN A treia form de normare 3FN Observaii: - nivelurile de normare mai avansate obinuiesc s mreasc numrul de tabele ale bazei de date - o baz de date de nivelul 2FN se n nivelul 1FN iar una n nivelul 3FN este i n nivelul 2FN i n nivelul 1FN - descompunerea informaiei n mai multe tabele trebuie s fie fr pierderi de informaii i fr pierderi de relaiilor - coloanele cheie primar i cheie extern nu sunt considerate date redundante. - exist i niveluri de normare mai nalte, 4FN, 5FN, dar nu fac parte din modelul relaional standard i de obicei nu realizeaz performane mult mai bune

o relaie mai muli la mai muli configurat grafic.

1.5.1

Prima form normal

1FN

Un tabel care respecta prima form normal: are coloane ce conin numai valori atomice; nu are grupuri care se repet O valoare atomic(scalar) este o valoare unic care nu mai poate fi subdivizat ntr-un mod n care s mai aib sens. Ex. Numele unei persoane, prenumele unei persoane, vrsta unei persoane, marca unei maini. Ex. care nu sunt atomice: numele i prenumele unei persoane trecute n acelai cmp. Presupunem c vrem s facem o baz de date cu crile unei biblioteci. E greit conform primei forme normale s facem un singur tabel i n cadrul acestuia s avem un cmp Nume_Autori i aici s trecem toi autorii: <--- greit Este greit de asemenea s facem mai multe coloane pentru autori, instanele multiple ale unei entiti nu trebuie reprezentate sub form de coloane multiple: <--- greit

1.5.2 A doua form normal 2FN Un tabel este n forma 2FN dac este n forma 1FN i adaug: cheia primar este o singur coloan(cheia primar e simpl) SAU toate coloanele din tabel formeaz cheia primar(simpl sau compus) Adic un tabel n forma a doua normal: este n prima form normal i Nu are dependene funcionale pariale Un tabel conine o dependen funcional parial atunci cnd cteva dintre valorile cheii compuse(nu toate ns) determin o valoare a unei coloane non-cheie. Un tabel 2FN este n ntregime dependent din punct de vedere funcional, trebuie s se modifice toate coloanele non-cheie atunci cnd o coloan din cheia compus sau coloana cheie simpl se modific. Un tabel este n forma 2FN dac NU pot determina o valoare noncheie dac cunosc doar o parte din coloanele cheii primare compuse. 1.5.3 A treia form normal 3FN Un tabel este n forma 3FN dac: - este n forma 2FN i adaug - NU are dependene tranzitive. Un tabel conine o dependen tranzitiv n cazul n care valoarea unei coloane non-cheie determin valoarea unei alte coloane non-cheie. Un tabel 3FN elimin dependenele dintre coloanele non-cheie, coloanele non-cheie sunt independente i sunt dependente doar de coloanele coloana(coloanele) cheii primare. Normalizarea este un lucru bun la proiectarea bazelor de date pentru c permite selectarea mult mai uoar a informaiei, modificarea mai uoar pe viitor a bazei de date i o mai bun securizare a datelor. Totui se prefer uneori denormalizarea ei pentru mrirea vitezei de execuie a interogrii.

<<--- CORECT
Solutia corect const n mutarea informaiilor despre autori ntr-un tabel copil nou, care conine un rnd pentru fiecare autor al unei cri Cheia primar din tabelul printe este title_id, iar cheia compus din tabelul copil este title_id i au_id. <---------\ au_phone depinde de au_id dar nu i de title_id--> acest tabel conine o dependen funcionat parial, NU este tabel 2FN.

1.6

Exemplu de proiectare a unei baze de date

Tabelul publishers
Descrie editurile, fiecare editur are un cod(identificator) unic, coloana pub_id, care reprezint cheia primar a tabelului.

O baz de date apare utilizatorului ca o colecie de tabele i nimic altceva. Tabelul authors Descrie autorii crii, fiecare autor are un cod identificator unic, coloana au_id, care reprezint cheia primar a tabelului.

Tabelul titles
Descrie crile . Fiecare carte are un cod unic, cheia primar, title_id. Acest tabel conine i o cheie extern, pub_id ce face referin la cheia primar a tabelului publishers.

Tabelul title_authors Face legtura de tipul mai muli la mai muli ntre tabelele cri i autori. De obicei, pentru o mai bun depanare, aceste tabele au numele formate din unirea numelui tabelului printe_numelui tabelului copil. Cheia primar este una compus i e format din coloanele title_id i au_id.

2.

Bazele limbajului SQL

SQL nu se identific cu modelul relaional, spre deosebire de modelul relaional, n SQL prezena cheilor primare este opional. De aceea utilizatorii SGBD-urilor i nu SGBD-urile posed responsabilitatea crerii de baze de date relaionale. 2.1 Sintaxa limbajului SQL<elemente generice>

Tabelul royalties Specific rata drepturilor de autor pltite ctre toi autorii fiecrei cri. Cheia primar a acestui tabel este odul titlului, title_id. Tabelul royalties este n

Comentariile mysql> #acesta e un comentariu pe un singur rndurilor mysql> -- acesta e tot un comentariu pe un rnd mysql> /* acesta este un /*> un comentariu pe mai multe rnduri*/ Instruciunile SQL Instruciunile sunt o combinaie de tokenuri(cuvinte cheie, identificatori, operatori i alte simboluri) Toate instruciunile SQL se termin cu ; (punct i virgul) Clauzele Reprezint un un fragment de instruciune i este introdus printr-un cuvnt cheie de tipul SELECT, FROM, WHERE, ORDER BY care introduc cele 4 clauze majore. Cuvintele cheie sunt cuvinte rezervate ale limbajului i nu putem denumi tabele, baze de date cu numele lor. Identificatorii sunt cuvinte utilizate de utilizator pentru denumirea tabelelor, bazelor de date. SQL este un limbaj case unsensitive!!!

relaie de tipul 1 la 1 cu tabelul titles, cheia primar a tabelului royalties este n acelai timp i cheie extern ce face legtura cu cheia primar a tabelului titles.

Nu conteaz dac scriem cu majuscule sau minuscule.

Caracteristici diverse ale limbajului SQLspecial MySQL: * este case-unsensitive(nu tine cont de majuscule, minuscule); * instruciunile pot fi scrise pe mai multe rnduri att timp ct nu sunt divizate cuvinte, tokenuri sau iruri de cuvinte ncadrate n ghilimele; * se pot scrie mai multe instruciuni pe acelai rnd; * cuvntul introductiv al unei instruciuni este denumit verb; * pentru a ngloba spaii ntr-un identificator, identificatorul trebuie scris ntre apostrofi ex. 'last name' dei e de preferat folosirea caracterului undescore ex. last_name sau folosirea majusculelor pentru prima liter a unui cuvnt dintr-un identificator compus ex. LastName CTRL + SHIFT+V pentru paste <--CTRL+SHIFT +C pentru copiere <--- consola Linux

2.2

TIPURI DE DATE

mysql> show databases; #afieaz toate bazele de date coninute mysql> use Baza_date #selecteaz baza de date specificat spre utilizare mysql> show tables; #utilizat dup ce a fost setat o baz de date afieaz toate tabelele coninute de acea baz mysql> Describe Tabel; #afieaz structura tabelului mysql> SELECT * FROM Tabel; #afieaz toate rndurile unui tabel. mysql> show columns from Tabel afieaz coloane din tabel
mysql> quit #iese din interpretorul de comenzi mysql mysql> \!cls #Windows mysql> \!clear #Linux, cur consola mysql> \! comanda_shell #trimite comanda shell la SO Creating a new user. Login as root. Switch to the MySQL db. Make the user. Update privs. # mysql -u root -p mysql> use mysql; mysql> INSERT INTO user (Host,User,Password) VALUES('%','username',PASSWORD('password')); mysql> flush privileges; $ mysqldump -u root -p BazaDate > /../BazaDate.sql creaz o copie a bazei de date intr-un fiier .sql $ mysql -u root -p BazaDate < dump.sql execut asupra bazei de date instruciunile din fisierul dump.sql http://www.pantz.org/software/mysql/mysqlcommands.html

Se refer la tipurile de date posibile pentru o coloan dintr-un tabel. Fiecare coloan dintr-un tabel are un singur tip de date. TIPURI DE DATE IR DE CARACTERE 1) CARACTER(lungime) sau CHAR(lungime) - o valoare de tipul Character(lungime) reine un ir de caractere de lungime predeterminat; - unele SGBD-uri limiteaz lungime maxim posibil pentru o variabil character; - dac nu am completat toate locaiile alocate pentru valoarea character, SGBD-ul va completa locaiile libere cu caractere spaiu; 2) CHARACTER VARYING(lun) sau CHAR VARYING(lun) sau VARCHAR(lungime) - reprezinta un numr variabil de caractere; - poate avea pn la maxim lungime caractere; - valoarea maxim pentru lungime depinde de SGBD; - SGBD-ul stocheaz irul ca atare i nu completeaz cu spaiu locaiile libere; 3) NATIONAL CHARACTER sau NATIONAL CHAR sau NCHAR - este identic cu tipul CHARACTER doar c stocheaz caracterele n format Unicode . Astfel se pot stoca diacritice caracteristice diverselor alfabete. 4) NATIONAL CHARACTER VARYING sau NATIONAL CHAR VARYING sau NCHAR VARYING - este identic cu tipul VARCHAR doar c stocheaz caracterele n format Unicode . Astfel se pot stoca diacritice caracteristice diverselor alfabete. 5) TEXT suport iruri de caractere mari OBServaii:
- pentru a insera un ir de caractere cu apostrof, ex. it's scriem 'it''s' - ghilimelele sunt tratate ca un caracter separat si nu necesit o prelucrare special - lungimea unui caracter este cuprins ntre 0 i lungime, specificat la definirea sa, un ir de caractere cu niciun caracter se nume te ir vid. - n Microsoft SQL Server tipurile ir de caractere sunt: char, varchar, text, nchar, nvarchar i ntext. - n MySQL tipurile ir de caractere sunt: char, varchar, nchar, nvarchar, text tinytext, mediumtext i longtext - n PostgreSQL avem: char, varchar i text - n Oracle: char, varchar, varchar2, nchar, nvarchar, nvarchar2

- un ir de caractere se trimite ntre apostrofi, 'Ana are mere' este un sir de tipul CHAR(12)

TIPURI DE DATE IRURI DE BII(bit strings) - este o succesiune ordonat de bii; - fiecare bit are valoarea 0 sau 1; - se utilizeaz pentru stocarea datelor binare: fiierele aplicaiei, fiiere care conine imagini sau sunete digitalizate; - n SQL, literalii de tip ir de ii sunt ncadrai de apostrofi; - SGBD-ul nu ncearc s interpreteze informaia din irurile de bii, aceasta e treaba aplicaiilor; - informaia binar poate fi reprezentat i hexazecimal sau octal; 1) BIT(lungime) - reprezint un numr fixat de bii, lungime reprezint lungimea irului; - dac trimitem un ir de bii de lungime mai mic dect lungime, SGBD-ul va genera de obicei o eroare; - irurile de tip bit se scriu de obicei ca irurile de caractere dar sunt precedate de B, ex. B'10001110' este un sir de tipul BIT(3), acelai ir poate fi scris i hexazecimal X'8E' 2) BIT VARYING - reprezint un numr variabil de bii; - un ir de bii stocat ntr-o coloan de tip BIT VARYING(lungime) poate avea le la 1(unu) pn la lungime bii; - dac depunem un numr de bii mai mic de lungime, SGBD-ul salveaz irul ca atare; - B'1011' este un exemplu de BIT(8) TIPURI DE DATE NUMERICE EXACTE (VIRGUL FIX) - se utilizeaz pentru stocarea valorilor numerice exacte; - o valoare numeric exact poate fi: * un nr negativ, 0(zero) sau un numr pozitiv; * un numr zecimal n virgul fix - precizia reprezint numrul de cifre semnificative utilizate pentru exprimarea numrului, nr de cifre total al numrului - scala reprezint nr. Total de cifre de la dreapta virgulei; - valorile numerice nu se ncadreaz ntre ghilimele; - vom stoca ca valori numerice, valorile implicate n calcule matematice, nu se obinuiete stocarea numerelor de telefon, codurilor potale ca numere; - calculele cu valori n virgul fix sunt mai rapide dect cele n virgula mobil pe care le vom studia n continuare.

1) NUMERIC NUMERIC(precizie [, scala]) - reprezint un numr zecimal n virgul fix; - precizie este o valoare >= 1 si valoarea ei maxim depinde de SGBD; - scala = 0 .. precizie, omiterea ei presupune scala = 0 iar numrul este un ntreg 2) DECIMAL sau DEC DECIMAL(precizie [,scala]) - este similar cu tipul numeric, unele SGBD-uri le trateaz ca sinonime; - diferena const c unele SGBD-uri ofer o limit de precizie mai mare pentru Decimal dect pentru tipul Numeric; - pentru unele SGBD-uri, argumentul precizie din declaraia Decimal specific precizia minim i nu precizia exact ca n cazul Numeric, deci putem depi valoarea specificat ca precizie; 3) INTEGER sau INT - reprezint un ntreg; - nu necesit argumente; 4) SMALLINT - este identic cu INTEGER doar c stocheaz un interval mai mic de valori - nici el nu necesit argument; OBServaii: - n Micrsoft Access avem urmtoarele tipuri numerice exacte: decimal, integer, byte, long integer; - n Microsoft SQL Server: numeric, decimal, integer, smallint, bigint, tinyint - n Oracle: numeric, decimal, integer, smallint, number; - n MySQL: numeric, decimal, integer, smallint, bigint, mediumint, tinyint -n PostgreSQL: numeric, decimal, integer, smallint, bigint http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html http://dev.mysql.com/doc/refman/5.0/en/data-types.html http://www.pantz.org/software/mysql/mysqlcommands.html

TIPURI DE DATE NUMERICE APROXIMATIVE ( VIRGUL MOBIL) - pot fi numere ntregi(0, pozitiv, negativ ntreg), o aproximare a unui numr n virgul mobil(real) - se pot exprima n notaie tiinific: mantis E exponent (ex. 1.44E2 = 1.44 x 102) unde mantisa reprezinta cifrele semnificative(aici 1.44) iar exponentul puterea lui 10(aici 2) - are o precizie determinat dar scala este determinat de mrimea si semnul exponentului; - pentru a converti precizia binar la cea zecimal, se nmulete precizia binar cu 0.30103; - pentru a converti precizia zecimal la cea binar, se nmulete precizia zecimal cu 3.32193; -- astfel 24 de bii nseamn o precizie de 7 cifre, 53 de biti nseamn o precizie de 15 cifre; 1) FLOAT FLOAT(precizie) - reprezinta un numr n virgul mobil; - precizie este un numar >= 1 i exprima un numr de bii, nu un numr de cifre. 2) REAL - asemntor cu Float doar c au o precizie mai redus; - reprezint numere n n simpl precizie; - NU necesit argumente. 3) DOUBLE PRECISION - este asemntor cu Float dar are o precizie mai mare dect a tipului Real; - NU necesit argumente. OBServaii: - n Microsoft Access avem urmtoarele tipuri aproximative: single i double; - n Microsoft SQL Server: float, real; - n Oracle: float, real, double precision i number; - n MySQL: float, real, double precision - n PostgreSQL: real, double precision

TIPURI DE DATE DE LUCRU CU DATA/ORA CURENT - se utilizeaz pentru a reprezenta ora i data curent sau a ultimei actualizri a bazei de date etc. - pentru separarea componentelor datei se folosete caracterul - - pentru separarea componentelor timpului curent se folosete caracterul : 1) DATE - reprezint data; - o dat stocat ntr-o coloan de tip DATE are trei cmpuri ntregi YEAR, MONTH, DAY i se reprezint sub formatul yyyy-mm-dd - nu necesit argument; 2) TIME - reprezint timpul din zi; - se compune din trei cmpuri ntregi: HOUR, MINUTE, SECOND i se reprezint sub formatul hh:mm:ss; - opional se pot specifica fraciuni de secund TIME(precizie), precizie reprezint numrul de fraciuni de secund care se adaug, formatul artnd astfel: hh:mm:ss.sss... 3) TIMESTAMP - reprezint o combinaie de valori de tipul DATE si TIME separate prin spaiu; - formatul timestamp este: yyyy-mm-dd hh:mm:ss sau yyyy-mm-dd hh:mm:ss.sss... atunci cnd se ofer argument (TIMESTAMP(precision)) 4) TIME WITH TIME ZONE - este asemntor cu TIME doar c un cmp suplimentar, TIME ZONE OFFSET indic diferena de fus orar(n ore fa de UTC) 5) TIMESTAMP WITH TIME ZONE - asemntor cu TIMESTAMP doar c adaug un cmp suplimentar, TIME ZONE OFFSET care indic fusul orar n format UTC OBServaii: - n Micrsoft Access avem tipurile de date: date i time - n Microsoft SQL Server: datetime i smalldatetime - n Oracle: date, timestamp - n MySQL: date, time, datetime i timestamp - n PostgreSQL: date, time, timestamp n Microsoft Access literalii de tip temporal se ncadreaz ntre dou caractere # i se omite prefixul numelui tipului de dat.

TIPURI DE DATE INTERVAL - stocheaz timpul dintre dou valori temporale, ex. ntre 9:00 i 13:30 este un interval de 4:30; - se poate utiliza pentru decrementarea, incrementarea unei valori temporale; - are aceleai cmpuri ca i valorile temporale(year, hour, second) dar adaug semnele + (nainte) i -(napoi); - se ncadreaz n categoriile: intervale an-lun(year-month) interval sub form de ani i un numr ntreg de luni - sau intervale zior(day-time) interval sub form de zile, ore, minute i secunde. 1) Year-month - aceste intervale conin numai o valoare de tip an, numai o valoare de tip lun sau ambele; - tipurile de coloane valide sunt: interval year, interval year(precizie), interval month, interval month(precizie), interval year to month sau interval year to month(precizie) 2) Day-time - aceste intervale conin o valoare de tip zi, o valoare de tip or, o valoare de tip minut, o valoare de tip secund sau o combinaie oarecare a acestor valori; - printre tipurile de coloane valide se numr: interval minute, interval day(precizie), interval day to hour, interval day(precizie) to second sau interval minute(precizie) to second(drac_precizie). OBServaii: - o coloan mono-cmp de tipul INTERVAL HOUR poate stoca intervale ca 4 ore sau 26 ore, o coloan multi-cmp ca INTERVAL DAY TO MINUTE poate stoca intervale ca 2 zile, 5 ore, 10 minute. - dac nu precizm valoarea preciziei unei coloane mono-cmp se consider implicit valoarea 2; - Microsoft Access, Microsoft SQL Server i MySQL nu accept tipurile de dat intervalele - Oracle i PostgreSQL accept tipurile de date interval

NULL-uri - sunt folosite pentru a reprezenta o valoare care lipsete sau nu este cunoscut momentan sau pentru totdeauna; - NULL este cuvntul cheie SQL care reprezinta un null; - coloanele non-null nu accept valoarea null; - IS NULL determin dac respectiva coloan are valoarea null; - null-urile nu sunt niciodat egale unul cu alta dar clauza DISTINCT ca trata null-urile ca fiind egale; - SUM(), MAX(), AVG() ignor null-urile; - null-urile afecteaz rezultatele compunerilor i cauzeaz probleme n subinterogri; - sunt afiate cu NULL, (NULL), <NULL> sau spaiu; - versiuni mai noi de Oracle trateaz irurile vide ('') ca null dar nu este indicat, s-ar putea s cauzeze probleme ntre versiuni; - se prefer utilizarea de valori implicite n loc de NULL-uri pentru a ocoli eventualele erori; - nu trebuie plasat cuvntul NULL n interogri deoarece SGBD-ul l interpreteaz ca irul de caractere 'NULL'.

3.

COMENZI UTILE

Un program client MySQL, numit i MySQL monitor este o interfa care permite utilizatorului s se conecteze la serverul MySQL trimindu-i comenzi n urma interpretrii interogrilor sql. Un astfel de program este adesea un command prompt sql. %> mysql [optiuni] [baza_date] #permite conectarea la serverul mysql din terminalul sistemului de operare folosit i deschiderea spre folosire as bazei de date selectate. > mysql #permite conectarea la serverul mysql instalat pe calculator sub windows, dup care serverul v va cere parola pe care ai setat-o n timpul instalrii Sub Linux, mysql este de obicei instalat n /usr/bin/mysql $ sudo mysql -u root -p #permite conectarea la serverul mysql instalat pe celculator sub Linux, se cere specificarea parolei de root pentru sistemul de operare iar apoi a parolei de root pentru serverul mysql %> mysql - - help #trimis n terminalul sistemului de operare folosit, help mysql> \h sau \? #trimis terminalului mysql ... help mysql> \c #clear, clear the current input statement mysql> \e #pornete editorul vim pentru editat comenzi mysql> \! comanda_shell #execut o comand a shelului sistemului de operare folosit mysql> exit sau quit sau \q #permite ieirea din shelul mysql mysql> use baza_date sau \u baza_date #deschide o baz de date spre utilizare mysql> \. script.sql #ruleaz script sql mysql> \W #arat mesaje de avertizare dup fiecare instruc. rulat mysql> \w #se renun la mesajele de avertizare dup fiecare inst. mysql>\! clear #terge consola %> mysqladmin -u root password myPassword #setm parol pentru serverul sql $ mysql -h host -u user -p dbname #atunci cnd folosim o aplicaie client i dorim s ne conectm la server trebuie s specificm host numele gazdei, user-numele utilizatorului, dbname numele bazei de date utilizat. Apoi MySQL va solicita o parol mysql> mysql -t baza_date < sql_script; # -t plaseaz rezultatele ntrun tabel(se omite aceast opiunea dac se dorete o ieire delimitat cu tab-uri), baza_date baza de date pe care se opereaz, sql_script este un fiier script ce conine o niruire de operaii care se executa asupra bazei de date mai sus menionate

mysql>set password for 'root'@'localhost' =PASSWORD ('secret_passwd'); schimbarea parolei, 'root' este username-ul i mpreun cu 'localhost-ul', care este un hostname, constitue un utilizator unic n MySQL. %> mysqladmin -u rott password 'parola' #permite de asemenea schimbarea parolei %> mysql -u root -psecret_password #metod nerecomandat de conectare la mysql, parola este afiat i exist posibilitatea ca cineva s utilizeze aplicaia Unix ps i s observe parola introdus. O metod mai bun ar fi salvarea parolei n ~/.mycnf. mysqladmin %> mysqladmin [option] command(s) #programul mysqladmin se folosete pentru a administra diverse aspecte ale serverului mysql %>mysqladmin - - help #afieaz opiunile %> mysqladmin -u root -p create baza_date #permite crearea bazei de date i deschiderea terminalului mysql pentru oferirea de privilegii Grant
mysql>GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...] ON {tbl_name | * | *.* | db_name.*} TO user_name [IDENTIFIED BY 'password'] [, user_name [IDENTIFIED BY 'password'] ...] [WITH GRANT OPTION]

Comanda Grant se folosete pentru a crea noi utilizatori i pentru a asigna privilegii utilizatorilor. mysql> GRANT usage ON *.* TO BDAdmin@localhost -> IDENTIFIED BY 'parola'; creaz un nou utilizator, BDAdmin capabil s se conecteze la serverul MySQL via gazda 'localhost' folosind parola 'parola'. Aceast comand permite doar privilegii de conexiune la baza de date i nu va permite utilizatorului s fac nimic asupra serverului. mysql> SELECT *FROM user; #vom observa c utilizatorul BDAdmin are valoarea N pentru toate privilegiile, deci se poate conecta la bazele de date dar nu poate face nimic. mysql> GRANT SELECT, INSERT, UPDATE, DELETE -> ON baza_date.* TO BDAdmin@localhost ; #oferim utilizatorului BDAdmin drepturi de a efectua interogrile select, insert, update i delete asupra baza de date baza_date. mysql> SELECT * FROM baza_date; #observm noul tabel de privilegii

mysql>GRANT SELECT, INSERT, UPDATE, DELETE ->ON widgets.* TO widgetAdmin@localhost

->IDENTIFIED BY 'ilovewidgets'; este posibil crearea unui utilizator nou i asignarea de privilegii printr-o singur interogare Revoke se folosete pentru luarea privilegiilor oferite odat pentru un utilizator: REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...]
ON {tbl_name | * | *.* | db_name.*}

%> mysqlhotcopy [optiuni] db_nume /path/to/new_directory #face backupul la o singur baz de date
%> mysqlhotcopy [optiuni] db_nume1 ... db_numeN /path/to/directory

#face backupul la cteva baze de date %> mysqlhotcopy - -help #pentru ajutor %> mysqlhotcopy -u root -p baza_date./^.('2000')$/ /usr/mysql/backups #expresia /^.+('2000')$/ spune utilitarului mysqlhotcopy s fac backup tabelelor care se termin n 2000 Linkuri http://dev.mysql.com/doc/refman/5.5/en/mysqldump.html http://dev.mysql.com/doc/refman/5.5/en/mysqlhotcopy.html

FROM user_name [, user_name ] mysql> REVOKE DELETE ON baza_date.* -> FROM BDAdmin@localhost; #se revoc oferirea privilegiului de a executa DELETE asupra bazei de date de ctre utilizatorul BDAdmin mysql> REVOKE ALL PRIVILEGES ON baza_date.* -> FROM BDAdmin@localhost; #se revoc toate privilegiile mysql> DELETE FROM user WHERE user = 'BDAdmin'; #terge utilizatorul complet din baza de utilizatori mysql> flush privileges; Backup-uri mysqldump O metod mai puin eficient de a crea back-upuri. %> mysqldump [optiuni] baza_date #creaz backup la baza de date %> mysqldump [optiuni] baza_date tabel1 tabel2 ... tabelN #creaz backuprui la tabelele specificate %> mysqldump [optiuni] - -databases [optiuni] db_nume1 db_nume2 ... db_numN #creaz backupuri la bazele de date specificate %>mysqldump [optiuni] - -all -databases [optiuni] #creaz backupuri pentru toate bazele de date %> mysqldump - -help #pentru ajutor Exemple:-------------%>mysqldump -u root -p --opt widgets %>mysqldump -u root -p --no-create-info widgets %>mysqldump -u root -p --no-data widgets mysqlhotcopy este un script scris n Perl care utilizeaz cteva comezi SQL pentru crearea de backupuri pentru bazele de date.

4)

CREAREA/ DESCHIDEREA / TERGEREA BAZELOR DE DATE

mysql> CREATE DATABASE baza_date #creaz o baz de


date goal dup ce am creat o baz de date trebuie s ne focalizm asupra ei pentru a o putea folosi, din terminalul mysql putem folosi comanda:

mysql> use baza_date


din afara terminalului, putem folosi comanda: $ sudo mysql -u root -p baza_date #pentru Ubuntu GNU/Linux > mysql baza_date 'pentru Windows

mysql> DROP DATABASE baza_date #terge baza de date


specificat

5)

TABELE CREAREA / MODIFICAREA I TERGEREA LOR

Se obinuiete ca fiecare restricie de coloan sau tabel s fie scris pe o singur linie de program. 5.2 Pe larg despre RESTRICII Restricie Descriere NOT NULL NULL DEFAULT Interzice inserarea de null-uri pe respectiva coloan Stabilete c o coloan poate avea valoarea null Stabilete valoarea implicit pentru respectiva coloan

* CREATE TABLE Tabel - creaz un tabel nou * ALTER TABLE Tabel- modific structura unui tabel * DROP TABLE Tabel- terge un tabel precum i datele stocate n el * CREATE TEMPORARY TABLE Tabel creeaz un tabel pe care SGBD-ul l terge automat atunci cnd nu mai este utilizat * SELECT INTO - creeaz un tabel nou dintr-un tablou existent Instruciunile de mai sus nu returneaz nici un rezultat, dar SGBD-ul pe care l utilizm va returna adesea un mesaj care spune dac instruciunea a fost executat corect sau au intervenit probleme. 5.1 CREAREA TABELELOR nainte de a crea un tabel, proiectatul de baze de date va studia atent proiectul deoarece o schimbare ulterioar e destul de costisitoare. Pentru a crea un tabel trebuie s cunoatem: - numele tabelului; - numele coloanelor; - tipurile de date ale coloanelor; - restriciile. CREATE TABLE tabel ( coloana1 tip_data [constrngeri], coloana2 tip_data [constrngeri], ........... coloanaN tip_data [constrngeri], [, constrngeri_tabel] [, constrngeri_tabel] [, constrngeri_tabel] ); Fiecare coloan are un nume, suport un tip de dat iar datele se ncadreaz n anumite constrngeri. Lista de constrngeri poate lipsi, de aceea a fost ncadrat n []. Restriciile multiple ale unei coloane NU se despart prin virgule. Dup definirea coloanelor urmeaz specificarea restriciilor tabelului, care pot lipsi, de aceea au fost ncadrate n []. Restriciile tabelului se despart prin virgule.

PRIMARY KEY Stabilete coloana(coloanele) care compun/e cheia primar FOREIGN KEY Stabilete coloana(coloanele) UNIQUE Interzice inserarea valorilor duplicate ntr-o coloan(mai multe celule de pe aceeai coloan nu pot avea aceeai valoare)

Limiteaz valorile care pot fi inserate ntr-o coloan preen utilizarea de expresii logice(de tip Boolean) Restriciile sunt reguli care se aplic pentru coloana sau tabelul pentru care au fost definite. O restricie de coloan se aplic doar pentru coloana pentru care a fost definit. O restricie de tabel se aplic pentru toate coloanele din tabelul respectiv. 5.2.2 Definirea unei constrngeri CONSTRAINT nume_constrngere constrngeri_din_tabelul de mai_sus ; MySQL nu accept clauza constraint pentru restriciile de coloane ci doar pentru cele de tip tabel.

CHECK

5.1

Crearea unui tabel cu CREATE TABLE

5.2.1

Interzicea nulurilor NOT NULL

CREATE TABLE titles ( title_id CHAR(3) , title_name VARCHAR(40) , type VARCHAR(10) , price INTEGER , contract SMALLINT ); #un tabel minimal Dac se ncearc crearea unui tabel cu un nume care deja a fost dat altui tabel, SGBD-ul va genera o eroare iar noul tabel nu va fi creat. Un tabel nou creat este vid, are 0 rnduri, el trebuie populat folosind instruciunea INSERT. Pentru modificarea structurii tabelului se folosete instruciunea ALTER TABLE. Pentru a crea un alt tabel cu structura tabelului existent se folosete instruciunea SELECT INTO. tergerea unui tabel se face cu DROP TABLE. MySQL modific n mod transparent pt. Utilizator coloanele de tip VARCHAR cu o lungime mai mica de 4 coloane n coloane de tip CHAR. Exemplu detaliat de crearea a unui tabel:
CREATE TABLE autori

NOT NULL interzicerea coloanei respective de a re ine null-uri. NULL- specific faptul c respectiva coloan poate accepta null-uri de i aceasta este opiunea default n cazul n care nu e prezent constrngerea not null. Un null nu este o valoare ci un marcaj care semnific faptul c nu a fost introdus nicio valoare. Null-urile difer de valoarea 0(zero). Null-urile nu aparin unui tip de date i pot fi inserate n orice coloan care le accept. Prezena null-urilor complic inserarea i actuializrile. Coloana Primary Key NU poate accepta null-uri. SGBD-ul definete automat toate coloanele componente PRIMARY KEY ca NOT NULL. Null-urile afecteaz verificrile integrit ii referen iale n cheile externe. Dac inserm un rnd folosind instruciunea INSERT, i pentru o coloan nu specificm nicio valoare, SGBD-ul va insera un NULL, excep ie fcnd coloanele care au coloanele care sunt setate s retin o valoare DEFAULT pentru cazul acesta.

( au_id CHAR(3) NOT NULL UNIQUE, au_nume VARCHAR(15) NOT NULL, au_prenume VARCHAR(15) NOT NULL, telefon VARCHAR(12) NULL, adresa VARCHAR(20) DEFAULT NULL, income DECIMAL(5,2) DEFAULT 0.00, ocupaie VARCHAR(10) DEFAULT 'scriitor', PRIMARY KEY (au_id), REFERENCES <tabel_strain>(<cheie_straina>) );

CREATE TABLE produse ( Id_produs INTEGER NOT NULL , nume_produs VARCHAR(20) NULL, pret INTEGER NULL , marca VARCHAR(20) DEFAULT NULL , CONSTRAINT cheie_primara PRIMARY KEY (Id_produs) #nc o metod de a introduce # o constrngere, n cazul acesta de tipul cheie primara ); INSERT INTO produse ( Id_produs, nume_produs, pret) VALUES (111, 'paine', 1); #nu s-a specificat nimic pentru marc, celula #marc a acestui rnd ca reine o valoare NULL. Cnd inserm valoare NULL ntr-un tabel, NULL NU trebui cuprins ntrre '...' * Oracle trateaz irurile vide, '', ca i null-urile * MySQL accept clauza Constraint dect pentru restriciile de tip tabel.

Specificarea unei valori implicite utiliznd DEFAULT O valoare implicita specific o valoare pe care SGBD-ul utilizat o atribuie unei coloane n situaiile n care, la inserarea unui rnd, omitem specificarea unei valori pentru un anumit rnd. * O restricie de tipul Default este ntotdeauna o restricie care se aplic pentru o coloan, NU se aplic niciodat pentru tabele. * Se face utiliznd cuvntul cheie DEFAULT la crearea tabelului cu CREATE TABLE. * Valoarea dat implicit trimis cu default trebuie s fie cuprins n intervalul de valori specific tipului cu care a fost definit cmpul. * Atunci cnd inserm un rnd cu INSERT, dac a fost omis un cmp, iar coloana din care face parte cmpul a fost definit cu constrngerea default, valoarea lui va deveni valoarea trimis de default n caz contrar valoarea va fi NULL, dac cmpul accept null-uri, n caz contrar SGBD-ul va genera o eroare. CREATE TABLE carte ( id INTEGER NOT NULL, nume VARCHAR(20) NOT NULL, editura VARCHAR(10) DEFAULT 'nespecificat', pret INTEGER DEFAULT 0.00, vnzri INTEGER DEFAULT (10 * 3) 5, data_inregistrarii DATE DEFAULT CURRENT_DATE PRIMARY KEY (id) ); * Microsoft Acces nu permite expresii aritmetice ntr-o restricie DEFAULT. * Microsoft SQL nu accept tipul de date DATE, se utilizeaz n schimb DATETIME i GETDATE() n loc de CURRENT_DATE. * Pn la Oracle 9i, CURRENT_DATE trebuia nlocuit cu SYSDATE. * n Oracle, restricia implicit succede tipul de date i precede toate celelalte restricii definite pentru coloana respectiv. * n Oracle '' == NULL. Dac o coloan nu are nicio restricie DEFAULT i este declarat de tipul NOT NULL, unele SGBD-uri atribuie automat o valoare din tipul specificat pentru coloana respectiv, MySQL atribuie implicit 0 coloanelor cu problema de mai sus.

5.2.2

5.2.3

Cheia primar

PRIMARY KEY

* O cheie primar identific n mod unic un rnd dintr-un tabel. * Valoarea unei chei primare nu poate fi NULL. * Fiecare tabel are exact o cheie primar, dar aceasta poate fi compus din una(cheie simpl) sau mai multe(cheie compus) coloane. * n cazul cheilor compuse, valorile pot fi duplicate n cadrul unei coloane ns fiecare combinaie de valori care provine de la toate coloanele din cheie trebuie s fie unic. Atunci cnd definim o cheie primar: * O cheie primar simpl poate fi o restricie de coloan sau o restric ie de tabel.; o cheie primar compus este ntotdeauna o restric ie de tabel. CREATE TABLE Produs ( id INTEGER PRIMARY KEY, nume_produs VARCHAR(20) NULL, ........... ) ; #definirea unei chei primare simple ca o restric ie de coloan CREATE TABLE Produs ( id INTEGER NOT NULL, nume_produs VARCHAR(20) NULL, ........... PRIMARY KEY (id) ) ; #definirea unei chei primare simple ca o restricie de tabel nedenumit CREATE TABLE Produs ( id INTEGER NOT NULL, nume_produs VARCHAR(20) NULL, ........... CONSTRAINT cheie_primara_produs PRIMARY KEY (id) ) ; #definirea unei chei primare simple ca o restricie de tabel cu nume --------------------Definirea unei chei primare compuse----------------CREATE TABLE Title_Authors ( title_id CHAR(3) NOT NULL, au_id CHAR(3) NOT NULL, au_order SMALLINT NOT NULL, CONSTRAINT Title_Authors_chieie_primara PRIMARY KEY (title_id, au_id) ) ; #definete o cheie primar compus printr-o restricie denumit * n tabel NU este permis mai mult de o restric ie referitoare la cheia primar, se utilizeaz exemplul 3 pentru a defini chei compuse.

* Toate coloanele definite n cadrul restriciei PRIMARY KEY trebuie s fie de tipul NOT NULL. * Valorile cheilor primare se schimb foarte rar. * NU reutilizai o valoare a cheii primare a unui rnd ters cu DELETE. * MySQL impune ca, n cazul definirii restriciei Primary Key ca restric ie de tabel, coloanele cheii s fie restric ionate cu NOT NULL.

5.2.4

Cheia extern

FOREIGN KEY

* O cheie extern este un mecanism care asociaz dou tabele. * O cheie extern este o coloan (sau un set de coloane) dintr-un tabel ale cror valori sunt legate de sau fac referire la valori din alte tabele. * O cheie extern face ca rndurilor dintr-un tabel s le corespund rnduri din alt tabel, numit tabel la care se face referire sau tabel printe. * O cheie extern stabilete o relaie direct cu cheia primar sau cu o cheie candidat din tabelul la care se face referire, astfel valorile cheii externe dintr-un tabel sunt restricionate la valorile cheilor printe care exist deja. Acest lucru se numete integritate referenial. * O cheie extern poate accepta valori NULL, dac coloana/ele cheie strin nu a fost definit/e ca not null. * Un tabel poate avea 0(zero), una sau mai multe chei strine. * n general valorile cheii externe nu sunt unice, mai multe celule ale cheii strine pot avea aceeai valoare, dac coloana cheie strin nu a fost definit ca Uniq. * O cheie extern simpl implic o singur coloan, o cheie extern compus implic mai multe coloane. * O cheie extern simpl se definete ca o restricie de coloan sau

Definirea unei Chei Externe Simple ca restricie de tip coloan: CREATE TABLE Carte ( Carte_Id INTEGER NOT NULL PRIMARY KEY, Carte_Nume VARCHAR(20), COD_Editura INTEGER NOT NULL, REFERENCES Editura(Editura_ID), pret DECIMAL(5,2) ) ; #observai, cheia extern COD_Editura din tabelul Carte face referire la tabelul Edituri lund valori din coloana Editura_ID din acel tabel. Definirea unei Chei Externe Simple ca restricie de tip tabel: CREATE TABLE Carte ( Carte_Id INTEGER NOT NULL PRIMARY KEY, Carte_Nume VARCHAR(20), COD_Editura NOT NULL, pret DECIMAL(5,2), CONSTRAINT Carte_Editura_Lk FOREIGN KEY (COD_Editura) REFERENCES Editura(Editura_ID) ); Definirea unor Chei Externe Simple ca restricii de tabel denumite: CREATE TABLE Carte_Autor ( Carte_ID INTEGER NOT NULL, Autor_ID INTEGER NOT NULL, Autor_Income DECIMAL(5, 2) NOT NULL, CONSTRAINT Carte_Autor_PK PRIMARY KEY (Carte_ID, Autor_ID), CONSTRAINT Carte_Autor__Carte_Lk FOREIGN KEY (Carte_ID) REFERENCES Carte(Carte_Id), CONSTRAINT Carte_Autor__Autor_Lk FOREIGN KEY (Autor_ID) REFERENCES Autor(Autor_Id) ) ; # acest tabel face o legtur mai muli la mai muli ntre tabelele Carte i Autor, un autor poate scrie mai multe cri i unele cri au mai muli autori. Cheia primar a tabelului este una compus ...

de tabel, o cheie extern compus se definete ca o restricie de tabel. * O cheie extern poate avea un nume de coloan diferit de cheia sa printe dar tipul de date i restriciile(not null, null, unique, dac exist) trebuie s se pstreze. * O cheie extern dintr-un tabel nu trebuie s fac referin doar la coloane PRIMARY KEY, ea poate face referin la orice tip de coloane care au restricia UNIQUE. * Dac nu specificm restriciile null, not null, referitoare la o cheie extern, SGBD-ul va stabili implicit restricia NOT NULL. * Pentru a pstra integritatea referenial, SGBD-ul va mpiedica crearea de rnduri orfane, rnduri din tabelul cheii externe care nu au rnduri asociate n tabelul printe. De asemenea, SGBD-ul va urmri atent operaiunile de INSERT, DELETE, UPDATE efectuate asupra tabelului, nu va insera un rnd n tabelul copil dac valoarea introdus pentru cheia strin nu se gsete prin cheile primare din tabelul printe, nu va permite tergerea unui rnd dac rndul omolog din tabelul printe mai exist nc, etc.

Definirea unei Chei Externe Compuse ca restricie de tabel CREATE TABLE Out_of_Print -- tabelul stocheaz legturi cu crile care nu se mai reediteaz ( Carte_ID INTEGER NOT NULL, Autor_ID INTEGER< NOT NULL, CONSTRAINT Out_of_Print_Fk FOREIGN KEY (Carte_ID, Autor_ID) REFERENCES Carte_Autor(Carte_ID, Autor_ID) ); * O restricie Foreign Key poate face referire la alte coloane din cadrul aceluiai tabel: <<exemplu angajai ef>> CREATE TABLE Angajati ( Angajat_id INTEGER NOT NULL, Angajat_Nume VARCHAR(20) NOT NULL, Angajat_Prenume VARCHAR(20) NOT NULL, SEF_ID INTEGER NULL, CONSTRAINT Angajati_Pk PRIMARY KEY(Angajat_id), CONSTRAINT Angajat_Fk FOREIGN KEY (SEF_ID) REFERENCES Angajati(Angajat_Id) ) ; #referin la propriul tabel >>>>***!!!
SQL permite definirea aciunilor pe care SGBD-ul le execut n cazul n care folosim UPDATE sau DELETE asupra unei valori a cheii din tabelul printe care este referit de valorile cheii externe. Pentru aceasta se specific o clauz ON DELETE sau ON UPDATE n restricia FOREIGN KEY. Cum se face acest lucru difer de la un SGBD la altul. ON UPDATE specific aciunea executat de SGBD atunci cnd ncercm s actualizm o cheie n tabelul printe cu UPDATE. Pentru ON UPDATE n cazul n care se face referirte la valoarea cheii prin cheile externe din rndurile ce apar in altor tabele, action poate lua una din valorile: CASCADE actualizeaz valorile cheilor externe dependente la noua valoare a cheii printe. SET NULL stabilete valorile cheilor externe dependente la null-uri. SET DEFAULT stabilete valorile cheilor externe dependente la valorile lor implicite NO ACTION genereaz o eroare n cazul nclcrii cheii externe, reprezint aciunea implicit.

Clauza ON DELETE specific aciunea executat de SGBD n cazul n care ncercm s tergem utiliznd DELETE o valoare a cheii ntr-un rnd - n cazul tabelului printe n cazul n care se face referire la valoarea cheii prin cheile externe din rndurile ce aparin altor tabele, action poate avea valorile: CASCADE - terge rndurile care conin valori de chei externe care corespund valorii cheii printe care a fost tears. SET NULL stabilete valorile cheilor externe dependente la null. SET DEFAULT stabilete valorile cheilor externe dependente la valorile lor implicite. NO ACTION genereaz o eroare n cazul nclcrii cheii externe, este aciunea implicit.
Mysql> CREATE TABLE Models -> ( -> ModelID SMALLINT UNSIGNED NOT NULL -> Name VARCHAR(40) NOT NULL, -> PRIMARY KEY (ModelID) -> ); Query OK,0 rows affected (0.02 sec) AUTO_INCREMENT,

mysql> mysql> CREATE TABLE Orders -> ( -> ID SMALLINT UNSIGNED NOT NULL PRIMARY KEY, -> ModelID SMALLINT UNSIGNED NOT NULL, -> Description VARCHAR(40), -> FOREIGN KEY (ModelID) REFERENCES Models (ModelID) -> ON DELETE CASCADE ON UPDATE CASCADE ->)
mysql> drop table Orders; Query OK, 0 rows affected (0.00 sec) mysql> mysql> drop table Models; Query OK, 0 rows affected (0.00 sec)

MySQL 4 i versiuni anterioare nu accept chei externe, accept clauzele Foreign Key i References n Create Table pentru compatibilitate cu standardul SQL dar nu impune n mod real integritatea referen ial, pentru aceasta se instaleaz add-on-ul InnoDB pentru MySQL (www.innodb.com). MySQL nu accept clauza CONSTRAINT pentru restric ii de coloan iar ORACLE trateaz irul '' ca NULL.

OBServaii:

5.2.5

UNIQUE Impunerea valorilor unice

5.2.6

Restricia CHECK

Impunerea unei restricii UNIQUE face ca acea coloan s nu poat conine valori duplicate. O coloan cu restricia UNIQUE poate conine NULL-uri. Un tabel poate avea oricte coloane definite cu restric ia UNIQUE. Cheia perimar are prin definiie restric iile UNIQUE i NOT NULL. Se pot defini restricii UNIQUE simple, pentru o coloan, compuse, pentru mai multe coloane. n cazul restriciilor UNIQUE pentru mai multe coloane, pe o coloan pot exista valori duplicate dar combinaia de valori din toate coloanele trebuie s fie unic. O restricie simpl referitoare la unicitate poate fi definit ca o restric ie de coloan sau ca o restricie de tabel, o restric ie unique compus nu poate fi definit dect ca restricie de tabel. n mod implicit SGBD-ul stabilete n mod implicit coloanele de tip UNIQUE ca fiind i NOT NULL, dar noi putem ataa restric ia NULL ca acestea s poat accepta null-uri. CREATE TABLE Carti ( Carte_ID INTEGER PRIMARY KEY, Carte_Nume VARCHAR(40) NOT NULL UNIQUE, ISBN NOT NULL, pret DECIMAL(5,2) NULL, ............................ CONSTRAINT unicitatea_ISBNului UNIQUE (ISBN) ) ; # Carte_Nume a fost definit ca unique printr-o restric ie de coloan n timp ce ISBN a fost definit ca unique printr-o restric ie de tabel CREATE TABLE Autori ( Au_Id INTEGER NOT NULL, Au_Nume VARCHAR(20) NOT NULL, Au_Prenume VARCHAR(20) NOT NULL, ......................... CONSTRAINT Nume_si_Prenume_Unice UNIQUE (Au_Nume, Au_Prenume) ) ;#restricie unique compus definit ca restric ie de tabel OBServaii: SQL NU permite mai mult de un singur NULL ntr-o coloan UNIQUE care accepta NULLuri. O cheie extern poate referi o coloan UNIQUE din tabelul printe. Se poate crea un index n locul unei restricii referitoare la unicitate cu ajutorul CREATE INDEX.

Se utilizeaz pentru a impune restricii suplimentare asupra coloanelor din tabele. Se pot impune restricii de tipul: * valori minime sau maxime: o coloan nu poate avea valori mai mici dect o limit sau mai mare dect o limit superioar; * valori specifice: permite doar anumite valori pentru o coloan, ex: 'limba romn', 'matematic', 'fizic' pentru coloana materii_scolare; * un domeniu de valori: valorile unei coloane trebuie s fie cuprinse ntr-un interval, s aib o limit superioar i alta inferioar. Restriciile Check pot fi definite ca restric ii de coloan sau de tabel i o coloan poate avea mai multe restricii de tip Check. CREATE TABLE Carti ( Carte_ID CHAR(3) NOT NULL, Carte_Nume VARCHAR(40) NOT NULL, tip VARCHAR(20) NULL CONSTRAINT tip_chk CHECK (tip IN ('Biologie', 'Computer', 'Copii', 'Istorie', 'Psihologie', 'Religie')), pret DECIMAL(5,2) CHECK (pret>0) NOT NULL,

CONSTRAINT pret_chk CHECK (pret >=0.00 AND pret<100.00) CONSTRAINT Carte_ID_CHK CHECK((SUBSTRING(Carte_ID FROM 1 FOR 1) ='T') AND (CAST(SUBSTRING(Carte_ID FROM 2 FOR 2) AS INTEGER) BETWEEN 0 AND 99)), ) ; #pentru pret am definit dou restricii CHECK, una de tip coloan i alta de tip tabel Operatorii de ordine: > (mai mare), < (mai mic), <= (mai mic sau egal), >= (mai mare sau egal), < > (diferit). MySQL 4 i versiuni mai vechi nu accept versiuni de verificare, acestea accept clauza CHECK n instruciunile CREATE TABLE. CAST(100.4 AS INTEGER) returneaz valoarea 100 Se pot folosi functiile i operatorii care vor fi studia i un pic mai trziu.

5.2.7

AUTO_INCREMENT

Autoincrementarea

Se folosete pentru a introduce valori unice n mod automat prin incrementare. Este adesea folosit pentru autoincrementarea cheii primare astfel nct s nu existe posibilitatea introducerii unei valori deja existente pentru o cheie primar. n acest caz, programul care comunic cu SGBD-ul e astfel creat nct s nu permit introducerea de ctre utilizator a valorii pentru cheia primar sau n cazul n care permite iar utilizatorul uit s specifice o valoare pentru cheia primar, SGBD-ul s aleag valoarea imediat urmtoare. Restricia AUTO_INCREMENT se poate folosi si pentru coloane care nu fac parte din cheia primar. CREATE TABLE Carte ( Carte_ID INTEGER AUTO_INCREMENT NOT NULL, ............ PRIMARY KEY(Carte_ID) )

5.3

CREATE TEMPORARY TABLE

Crearea unui tabel temporar Tabelele pe care le-am creat pn acum au fost tabele permanente, tabele de baz. Tabelele temporare permit stocarea temporar a rezultatelor intermediare. Se utilizeaz pentru: - stocarea, o sigur dat, a rezultatului unei interogri complexe, care consum timp i pentru utilizarea acestui rezultat n mod repetat n cadrul interogrilor urmtoare; - crearea unei imagini a unui tabel la un anumit moment de timp. - pstrarea rezultatelor unei subinterogri. Tabelul temporar este ters de SGBD automat la sfritul unei sesiuni sau al unei tranzacii. Exist tabele temporare de tip global (GLOBAL TEMPORARY) disponibil n cadrul tuturor sesiunilor active, local(LOCAL TEMPORARY) vizibil doar n cadrul sesiunii n care a fost creat. La crearea tabelelor temporare se respect aceleai restricii i norme ca la crearea tabelelor de baz. tergerea unui tabel temporar, dac dorim s eliberm memoria i nu dorim s ateptm s-l tearg SGBD-ul n mod automat, se face cu DROP TABLE la fel ca n cazul tabelelor de baz.

CREATE LOCAL TEMPORARY TABLE Edituri ( Ed_ID INTEGER, Ed_Nume VARCHAR(20), ............ ) ; # tabel local CREATE GLOBAL TEMPORARY TABLE Edituri ( Ed_ID INTEGER, Ed_Nume VARCHAR(20), ............ ) ; # tabel global OBServaii Se poate crea o copie temporar a unui tabel existent cu ajutorul SELECT INTO. Microsoft Access NU accept tabele temporare. Microsoft SQL Server definete un tabel local temporar astfel: CREATE TABLE # Tabel (....) ; un tabel global temporar: CREATE TABLE ## Tabel (....); n Oracle un tabel temporar este vizibil n cadrul tuturor sesiunilor. MySQL accept doar tabele temporare locale, specificatorii LOCAL i GLOBAL trebuie omii: CREATE TEMPORARY TABLE Tabel (...); PostGre SQL accept de asemenea doar tabele temporare locale iar specificatorul LOCAL este opional. Cu ON COMMIT PRESERVE ROWS se pot salva modificrile aduse unui tabel temporar atunci cnd se execut COMMIT iar cu ON COMMIT DELETE ROWS videaz tabelul temporar dup ce se execut o clauz COMMIT.

5.4

Crearea unui tabel nou din unul existent SELECT INTO

SELECT INTO creeaz un tabel nou i l populeaz cu rezultatele unei instruciuni SELECT. Se folosete pentru: - arhivarea rndurilor specificate; - efectuarea de copii de rezerv ale tabelelor; - crearea unui instantaneu al unui tabel la anumite momente de timp - duplicarea rapid a structurii unui tabel fr duplicarea datelor acestuia

- crearea datelor de test; - copierea unui tabel pentru atesta operaiile INSERT, UPDATE i DELETE naintea modificrii datelor utilizate n timp real. Se pot selecta rndurile pe care le dorim s le copiem folosind SELECT cu Where, Join, Group By, Having. SELECT INTO face inserarea rndurilor ntr-un singur tabel indiferent la cte tabele face referire clauza SELECT. Noul tabel trebuie s fie denumit altfel dect tabelul, tabelele din care se extrage SELECT * INTO Autori2 FROM Autori; #copiaz tot tabelul Autori n Autori2 SELECT * INTO Edituri2 FROM Edituri WHERE 1 > 2; #copiaz doar structura tab. Edituri n tabelul Edituri2, nu i datele SELECT Carte_Nume, vanzari INTO GLOBAL TEMPORARY TABLE Carti2 FROM Carti WHERE pub_Id = 123 ; #creeaz un tabel temporar n care copiaz coloanele Carte_Nume i vanzari care au n tabelul Carte valoarea pub_id=123 pentru id-ul editurii. SELECT A.Au_Nume, A.Au_Prenume, C.Carte_Nume INTO Autori__Carti_Autori FROM Autori A INNER JOIN Carti_Autori CA ON A.Au_ID = CA.Au_ID INNER JOIN Carti C ON CA.Carte_ID = C.Carte_ID WHER A.Tara_Origine NOT IN ('Canada', 'Bosnia') ; OBServaii n Oracle instructiunile SELECT INTO este utilizat pentru atribuirea variabilelor n PL/SQL dar se folosete ns instruciunea CREATE TABLE AS SELECT sub forma:
CREATE TABLE Tabel_Nou AS SELECT Coloanele FROM Tabel_Existent [WHERE condiii_de_selectare] ; MySQL NU accept SELECT INTO, se folosete CREATE TABLE i INSERT SELECT. PostgreSQL nu accept GLOBAL dar accept CREATE TABLE..AS

5.5.

MODIFICAREA UNUI TABEL

ALTER TABLE
Cu ALTER TABLE se poate: - aduga sau terge coloane; - modifica tipul de date al unei coloane; - aduga, modifica sau terge restricii referitoare la acceptarea NULL-urilor sau restricii referitoare la valoarea implicit a unei col.; - aduga, modifica sau terge restricii de coloan sau a restriciilor de tabel precum cele de cheie primar, cheie extern sau unicitate i restriciile de verificare; - redenumirea unei coloane; - redenumirea unui tabel. Structura instruciunii: ALTER TABLE Tabel alter_table_action ; Tabel --> tabelul asupra cruia se efectueaz operaia. alter_table_action --> aciunea care se efectueaz asupra tabelului: ADD [COLUMN] nume_coloana tip_date DROP COLUMN nume_coloana ADD definitie_constrngere DROP CONSTRAINT nume_constrngere Exemplu: ALTER TABLE Autori ADD adresa_email VARCHAR(40); #am adugat o coloan n tabelul Autori ALTER TABLE Autori DROP COLUMN adresa_email ; #am ters o coloan n tabelul Autori. 5.5.1 Afiarea structurii tabelului Dup ce am executat o instruciune de modificare asupra unui tabel, uneori vom dori s vedem ce efect a avut i cum arat structura nou a tabelului. n funcie de SGBD: * Microsoft Access: Apsm tasta F11, executm click pe opiunea Tables(sub Objects), executm click pe un tabel din list, executm click pe opiunea Design din bara de instrumente pentru a deschide tabelul n modul Design View. * Microsoft SQL Server: Lansm SQL Query Analyzer sau utilitarul interactiv n linie de comand osql . Se recomand utilizarea

SQL Query Analyzer i selectarea Query>Results n Grid. Se tasteaz sp_help Tabel, Tabel este numele tabelului pe care vrem s-l vizionm. n SQL Query Analyzer selectm Query > Execute i se apas tasta F5. n osql se apas tasta Enter i se tasteaz go apoi se apas iar tasta Enter. * PostgreSQL: se lanseaz utilitarul n linie de comand psql i se tasteaz \d Tabel; i se apas tasta Enter. * Oracle: Se lanseaz SQL *Plus sau utilitarul n linie de comand sqlplus. Se tasteaz DESCRIBE Tabel; i se apas tasta Enter. * MySQL: Se lanseaz n execuie utilitarul n linie de comand mysql, se tasteaz DESCRIBE Tabel; i se apas Enter. Exemplu:

5.6 DROP
tabel temporar.

TERGEREA UNUI TABEL DROP TABLE TABLE Tabel; terge un tabel de baz ct i un

Observaii: 1) Pentru tergerea sau modificarea unei constrngeri se folosete numele pe care i l-am dat n clauza CONSTRAINT atunci cnd am creat constrngerea. Dac nu i-am oferit niciun nume constrngerii, vom utiliza numele restriciei generat automat de SGBD-ul folosit. 2) De obicei SGBD-urile impun mai puine restricii de modificare pentru tabelele vide, dac adugm o coloan unui tabel care are deja una sau mai multe coloane, coloana nou introdus nu poate avea restricia NOT NULL. 3) PostgreSQL permite adugarea sau redenumirea de coloane dar NU permite tergerea de coloane, pentru a terge coloane trebuie s recrem i s repopulm un tabelul...folosind Select Into. Pentru redenumirea unui tabel: n Microsoft Access aceste operaii se efectueaz grafic. n Microsoft SQL Server se execut procedura stocat EXEC sp_rename 'old_name' , 'new_name' Oracle: RENAME TABLE old_name TO new_name; MySQL: RENAME TABLE ald_name TO new_name; PostgreSQL: ALTER TABLE old_name RENAME TO new_name;

Un tabel ters odat este ters pentru totdeauna. Singura metod de a recupera un tabel ters const n recrearea tabelului i restaurarea datelor acestuia cu ajutorul celei mai recente copii de siguran . tergerea unui tabel terge structura, datele, indec ii, restric iile i permisiunile acestuia dar NU se terg vederile care fac referire la acest tabel. tergerea unui tabel poate fi problematic deoarece se vor ntmpina probleme n cazul cheilor externe sau al vederilor care fac referire la un tabel ters, excepie fcnd situaiile n care aceste chei sau vederi au fost terse. Unele SGBD-uri vor cere modificarea anumitor propriet i nainte de tergerea propriu-zis a tabelului, n Microsoft SQL nu se permite tergerea unui tabel pn nu sunt terse restriciile de tipul Foreign Key din el. Standardul SQL permite specificarea comportamentului tergerii utiliznd unul din cuvintele cheie RESTRICT sau CASCADE. Clauza RESTRICT mpiedic tergerea unui tabel la care fac referire vederi sau alte restric ii. Clauza CASCADE(periculoas) provoac, odat cu tergerea tabelului, tergerea tuturor obiectelor la care face referire, terge restric ia cheie strin nainte de a ncepe tergerea tabelului, nu va terge alte tabele. tergerea tabelului este diferit de tergerea de rnduri din tabel care se face cu DELETE FROM Tabel.

DROP [TEMPORARY] TABLE [IF EXISTS]


tbl_name [, tbl_name] ...

[RESTRICT | CASCADE] #sintaxa MySQL

IF Exists ajut la eliminarea erorii n cazul n care tabelul nu exist. DROP TABLE Tabel RESTRICT; #terge un tabel folosind opiunea restrict DROP TABLE Tabel CASCADE; #terge un tabel folosind opiunea cascade.

6.

Se vor trata instruciunile: INSERT - adaug rnduri noi unui tabel; UPDATE - modific valorile aflate n rndurile existente ntr-un tabel; DELETE - terge, elimin rnduri dintr-un tabel Aceste instruciuni nu returneaz un rezultat, dar, de obicei, SGBDul utilizat va afia un mesaj specificnd dac instruciunea a fost executat cu succes. Pentru a vizualiza rezultatul efectuat asupra tabelului, se poate utiliza SELECT * FROM Tabel; #care va afia toate rndurile reinute n tabel. S-ar putea ca instruciunile de mai sus s necesite prioriti de utilizator mai ridicate i astfel s fie nevoie de contactarea administratorului. Pentru a putea insera, terge, modifica date dintr-un tabel, trebuie s cunoatem structura respectivului tabel. Pentru aceasta se verific seciunea 5.5.1 de mai sus. Mai pe scurt referitor la afiarea structurii de tabel instruciuni -: MySQL i Oracle: mysql> DESCRIBE Tabel; PostgreSQL: n psql: Baza_Date=# \d Tabel; Microsoft Access: tasta F11 pentru a trece la fereastra Database. Executm click pe opiunea Tables(sub Objects), executm un click pe un tabel din list, executm click pe opiunea Design din bara de instrumente pentru a deschide tabelul n modul Design View. Microsoft SQL Server: lansm SQL Query Analyzer sau utilitarul n linie de comand osql. Tastm > sp_help Tabel; n SQL Query Analyzer selectm Query->Execute sau apsm tasta F5.

INSERAREA / ACTUALIZAREA I TERGEREA RNDURILOR

6.1

Inserarea rndurilor INSERT

Instruciunea INSERT se folosete pentru inserarea de rnduri ntrun tabel. Se pot insera rnduri fr a specifica coloanele, bazndu-ne pe ordinea plasrii coloanelor n tabel(INSERT VALUES); specificnd coloanele(INSERT VALUES); selectnd rnduri din alt tabel(INSERT SELECT). Insert Values poate aduga un singur rnd unui tabel, Insert Select poate aduga mai multe rnduri unui tabel. Valorile inserate trebuie s corespund tipurilor de date ale coloanelor, se utilizeaz CAST() pentru a schimba tipul de date. Pentru a pstra integritatea referenial, o valoare inserat a cheii externe trebuie s conin sau un null sau o valoare existent de cheie din coloanele cu rol de cheie primar sau cheie unic la care face referire cheia extern. O valoare introdus nu poate nclca o restricie de verificare. Ordinea rndurilor nu este important, nu se poate controla locaia fizic a rndurilor. 6.1.1 INSERAREA PE BAZA POZIIILOR COLOANELOR N TABEL INSERT INTO Tabel VALUES ( val1, val2, ...., valn ) ;

coninute de server

MySQL mysql> show databases; #afieaz toate bazele de date mysql> use Baza_date #selecteaz baza de date

specificat spre utilizare

mysql> show tables; #utilizat dup ce a fost setat o baz de date afieaz toate tabelele coninute de acea baz mysql> describe Tabel; #afieaz structura tabelului mysql> SELECT * FROM Tabel #afieaz toate rndurile unui tabel.

INSERT INTO Angajati VALUES ( 3, 'Constantinescu', 'Gabriel-Cosmin', 3 );

6.1.2

INSERAREA RNDRURILOR SPECIFICND COLOANELE

6.1.3

INSERT INTO Tabel ( coloana1, coloana2, ..., coloanaN ) VALUES ( valoare1, valoare2, ..., valoareN ) ; INSERT INTO Tabel ( Angajat_Nume, Angajat_Prenume, SEF_ID ) VALUES ( 'Stefan', 'Viorel', 3 );

INSERAREA RNDURILOR PE BAZA VALORILOR DIN ALT TABEL Permite copierea mai multor coloane dintr-un tabel n altul. INSERT INTO Tabel_2 [ ( coloana1, coloana2, ..., coloanaN ) ] SELECT coloana'1, coloana'2, ................ coloana'N FROM Tabel_1 [WHERE ... ];
INSERT INTO Angajati2 SELECT * FROM Angajati ; #copiaz toate rndurile din tabelul Angajati n tabelul Angajati2 INSERT INTO Angajati2 ( Angajat_ID, Angajat_Nume, Angajat_Prenume, ) SELECT Angajat_ID, Angajat_Nume, Angajat_Prenume, FROM Angajat WHERE SEF_ID = 3 ; #copiaz n tabelul Angajat2 toi angajaii care au pe coloana SEF_ID valoarea 3. Trebuie specificate coloanele n care se insereaz din tabelul 2 i coloanele din care se selecteaz din tabelul 1, dac omitem coloanele n care se insereaz, SGBD-ul va lua n considera ie ordinea n care ele au fost definite la crearea tabelului. Aici numele coloanelor au corespuns celor dou tipuri de tabele dar acest lucru nu este obligatoriu. Putem de asemenea omite coloanele din clauza Select dar o facem pe rspunderea noastr, se pot omite ambele liste de coloane, ca n primul exemplu, dar tabelele trebuie s aib structur asemntoare, coloanele, n ordinea n care sunt definite, trebuie s accepte acelea i tipuri de date. Observaii Trebuie s fim prudeni la inserare, e de preferat s testm inserarea pe un tabel temporar cu aceeai structur. n standardul SQL, cuvntul cheie INTO este opional dar n Microsoft Access, Oracle i PostgreSQL el este obligatoriu.

cloana1, coloana2, ..., coloanaN sunt numele coloanelor aa cum apar ele n definiia i structura tabelului, ordinea coloanelor NU e important. valoarea1, valoarea2, ..., valoareaN sunt valorile pe care vrem s le introducem pentru coloanele specificate, n ordinea n care au fost specificate n cadrul instruciunii INSERT. Putem omite coloane n cadrul instruciunii INSERT, n acest caz, valorile care se vor pune n respectivele coloane depind de restriciile cu care au fost definite, dac acele coloane nu au restricii Default, Null sau Auto_Increment, SGBD-ul va genera o eroare. Angajat_ID este definit cu auto_increment, dup cum se observ incrementarea a nceput s se fac de la valoarea dat pentru prima nregistrare, de la 3.

6.2

ACTUALIZAREA RNDURILOR UPDADE

# seteaz coloanele specificate la valorile specificare din tabelul Tabel care ndeplinesc clauza Where.
UPDATE Angajati SET SEF_ID = 4 ; # seteaz coloana ef a fiecrui rnd din tabelul angajai la valoarea 4, toi angajaii vor avea ca ef pe Stefan Viorel.

Instruciunea UPGRADE modific valorile aflate n rndurile existente ntr-un tabel. S poate utiliza UPGRADE pentru: - a modifica toate rndurile dintr-un tabel; - doar anumite rnduri din tabel; Pentru actualizarea rndurilor dintr-un tabel trebuie specificat: - tabelul care trebuie actualizat; - numele coloanelor care trebuie actualizate precum i noile lor valori; - o condiie optimal de cutate prin care se specific rndurile care trebuie s fie actualizate. * Instruciunea INSERT are o clauz WHERE la fel ca i Select n care se specific rndurile care vor fi actualizate, n absena clauzei WHERE, instruciunea Insert va modifica toate rndurile. * Instruciunea INSERT este periculoas deoarece dac nu se specific Where vor fi modificate toate rndurile din tabel. DE aceea se obinuiete s se ruleze o instruciune SELECT cu aceeai clauz WHERE pentru a vedea toate rndurile care vor fi modificate nainte de a face modificarea cu Insert. * Rulnd o instruciune SELECT COUNT(*) cu clauza WHERE care va fi inclus mai trziu n clauza INSERT, vom afla numrul rndurilor care vor fi modificate. * Valorile trimise cu UPGRADE trebuie s respecte tipurile de date i restriciile coloanelor din tabelul pe care dorim s-l actualizm. Putem s utilizm funcia CAST() pentru a schimba tipul de date acolo unde este cazul. * Pentru pstrarea integritii refereniale SGBD-urile permit definirea aciunilor pe care acestea trebuie s le execute n mod automat atunci cnd ncercai s actualizai cu ajutorul instruciunilor UPDATE o valoare de cheie care este referit de o cheie extern. * Cu UPDATE se pot aduga restricii de tipul CHECK. UPDATE Tabel SET coloana = valoare ; #face toate celulele de pe coloana coloana s conin valoarea valoare. Dup cum vedem lipsete clauza WHERE, deci vor fi modificate toate rndurile din tabelul Tabel. UPDATE Tabel SET coloana1 = valoare, ............................. coloanaN = valoare WHERE clauza_where ;

UPDATE Angajati

1) UPDATE Angajati SET Angajat_Prenume = 'Sorin' WHERE Angajat_Nume = 'Stefan'; #exemplu de schimbare a prenumelui unui angajat. 2) UPDATE Produs SET pret = pret *2 WHERE type = 'mbrcminte'; # exemplu de dublare a preului unui produs. 3) UPDATE produse SET pret = pret * 0.5; WHERE pret > (SELECT AVG(pret) FROM produse); #am sczut cu 50% preurile produselor cu pre mediu. 4) UPDATE titles SET pubdate = DATE '2003-01-01' WHERE title_id IN (SELECT title_id FROM title_authors WHERE au_id IN SELECT au_id FROM authors WHERE au_fname = 'Sarah' AND au_lname = 'Buchman')); #modific data de publicare a tuturor crilor scrise de Sarah Buchman la 1 ianuarie 2003

5) UPDATE titles SET pub_id = (SELECT pub_id FROM publishers WHERE pub_name = 'Abatis Publishers') WHERE pub_id = (SELECT pub_id FROM publishers WHERE pub_name = 'Tenterhooks Press'); modific editura pentru toate crile companiei Tenterhooks Press n Abatis Publishers OBServaii: 1) SGBD-ul evalueaz expresiile dintr-o clauz SET sau WHERE utiliznd valorile pe care le-au avut nainte de efectuarea actualizrii coloanele la care se face referire: UPDATE mytable SET col1 = col1 * 2, col2 = col1 *3, col3 = col2 *6 WHERE col1 = 1 AND col2 = 2; 2) Se recomand testarea clauzei UPDATE ntr-un tabel temporar . 3) Se pot actualiza rndurile cu ajutorul instruciunii UPDATE prin intermediul vederilor. 4) n cazul n care se utilizeaz tranzaciile, trebuie efectuat o operaie COMMIT pentru modificarea efectiv a bazei de date. 5) Microsoft Access nu accept subinterogri scalare n clauza SET, instruciunile din ultimele dou exemple trebuie separate n dou instruciuni, una de tip SELECT care selecteaz codul editurii pub_id pentru Abatis Publishers i alta care utilizeaz acest cod pub_id pentru a realiza modificarea codului pub_id. 6) n literalii de tip dat din Microsoft SQL Server, trebuie omis cuvntul cheie DATE. Se pune #2003-01-01# pentru date. 7) MySQL 4.0 i versiunile anterioare nu accept subinterogri interioare, nu va rula ultimele interogri. 8) n PostgreSQL trebuie convertite numerele din virgul mobil din ultimele interogri la tipul DECIMAL utiliznd CAST(), ex: CAST(2.0 AS DECIMAL)

6.3

TERGEREA RNDURILOR CU DELETE

Instruciunea DELETE terge rnduri din cadrul unui tabel. Putem utiliza instruciunea DELETE pentru: - tergerea tuturor rndurilor dintr-un tabel; - tergerea anumitor rnduri dintr-un tabel; Pentru efectuarea unei instruciuni DELETE trebuie precizat: - tabelul din care vrem s tergem rndurile; - o condiie de cutare prin care se indic rndurile de ters. DELETE: - terge rnduri dar niciodat definiia unui tabel; - are o clauz opional WHERE prin care se specific rndurile de ters, n absena ei se vor terge toate rndurile tabelului; - este periculoas de aceea este indicat testarea ei pe un tabel temporar sau s se ruleze o instruciune SELECT cu aceeai clauz WHERE; - pentru pstrarea integritii refereniale, SGBD-ul permite definirea aciunilor pe care acesta trebuie s le execute n mod automat atunci cnd ncercai s tergei cu ajutorul instruciunii DELETE o valoare de cheie care este referit de o cheie extern; DELETE FROM tabel [WHERE condiie_de_selectare] ; tabel --> tabelul din care se terge conditie_de_selectare --> pot fi condiii WHERE mpreun cu operatori de comparaie LIKE, BETWEEN, IN, IS NULL, ALL, ANY, EXIST, combinaii de tipul AND, OR, NOT. Lipsa clauzei WHERE implic tergerea tuturor rndurilor din tabel. DELETE * FROM tabel; echivalent cu DELETE FROM tabel; #terge toate rndurile din tabel

DELETE FROM Angajati WHERE Angajat_Prenume = 'Gabriel Cosmin'; #am ters din tabelul angajai toi angajatii cu prenumele Gabriel Cosmin DELETE FROM title_authors WHERE title_id IN ( SELECT title_id FROM titles WHERE pub_id ('P01', 'P04')); #terge din tabelul title_authors rndurile pentru toate crile publicate de ctre editurile cu codurile P01 si P04.

OBServaii: 1) Putem terge rnduri dintr-un tabel dat pe baza valorilor stocate n alt tabel. 2) Se recomand testarea instruciunii DELETE pe un tabel temporar sau pe utilizarea unei instruciuni SELECT cu aceeai clauza WHERE; 3) se pot terge rnduri cu ajutorul DELETE prin intermediul unei vederi; 4) n cazul tranzaciilor, trebuie efectuat la final o instruciune COMMIT pentru a permanentiza modificrile efectuate; 5) pentru tergerea tuturor rndurilor dintr-un tabel, instruciunea TRUNCATE este mult mai rapid dect DELETE dar nu face parte din standardul SQL dar este acceptata de Microsoft SQL Server, Oracle, MySQL i PostgreSQL. TRUNCATE e relativ asemntoare cu o instruciune DELETE fr clauz WHERE fiind mai rapid deoarece nu scaneaz ntregul tabel i nu nregistreaz modificrile n jurnalul de tranzacii. Dar dac s-a executat o instruciune TRUNCATE nu se mai pot recupera datele iniiale, nu se poate efectua roll-back dac s-a efectuat o eroare. TRUNCATE TABLE tabel ;

7.

INSTRUCIUNEA SELECT REGASIREA DATELOR DINTR-UN TABEL

Instruciunea SELECT este la baza limbajului SQL i se utilizeaz pentru regsirea i manipularea datelor. SELECT coloane FROM tabel [JOIN joinuri] [WHERE conditii_de_cutare] [GROUP BY coloane_de_grupare] [HAVING conditie_de_cautare] [ORDER by conditii_de ordonare] Din punct de vedere teoretic, instruciunea SELECT este singura care se poate numi interogare n limbajul SQL. SELECT coloana FROM tabel ; #afieaz valorile de pe coloana coloana din tabelul tabel.

SELECT coloana1, coloana2, coloana3 FROM tabel ; #se pot selecta mai multe coloana dintr-un tabel

SELECT * FROM FROM tabel ; #selecteaz toate coloanele din tabel i afieaz coninutul acestora. <====== echivalent cu =======> DESCRIBE tabel ; Clauzele SELECT i FROM sunt obligatorii pentru regsirea coloanelor din tabel, restul de clauze sunt opionale. Operaia care selecteaz anumite coloane dintr-un tabel este denumit proiecie.

CREAREA ALIAS-URILOR UTILIZND AS AS se utilizeaz pentru a crea un antet diferit pentru numele coloanei, practic numele coloanei va aprea diferit n rezultatul instruciunii SELECT: SELECT Angajat_Nume AS ''Nume Second Name'', Angajat_Prenume AS 'Prenume First Name' FROM Angajati ;

7.1

7.3

ORDONAREA RNDURILOR ORDER BY

Rndurile din rezultatul unei interogri sunt neordonate, cu ajutorul clauzei ORDER BY se poate impune o anumit ordine de afiare. SELECT coloana1, coloana2, ... , coloanan FROM tabel ORDER BY coloana_de_sortare[ASC | DESC] ; Am adugat o coloan salariu la tabelul Angajati creat mai nainte

AS se poate folosi pentru a denumi coloane derivate, alias-uri de tabele i nu modific numele coloanelor. n Micrsoft Access i PostgreSQL cuvntul AS este obligatoriu. Oracle trunchiaz numele alias-urilor la nr de char. sup de col. Eliminarea rndurilor duplicate utiliznd DISTINCT Se utilizeaz pentru a nu afia rndurile care conin valori care au mai fost afiate. SELECT DISTINCT coloana1, coloana2, ... , coloanan FROM tabel ; Dac clauza Select Distinct conine mai multe coloane, unicitatea rndurilor este determinat de combinaia dintre valorile tuturor coloanelor respective. Cu toate c null-urile nu sunt niciodat identice, Select Distinct le consider identice. SELECT ALL coloana1, coloana2, ... , coloanan FROM tabel ; # Clauza Select conine cuvntul cheie ALL dar acesta determin comportarea implicit, afiarea tuturor rndurilor. SELECT DISTINCT * FROM tabel ; #va afia toate rndurile deoarece toate rndurile sunt unicat. 7.2

Dac nu se specific ASC sau DESC, valoarea implicit este ASC. Pentru sortarea valorilor de tipul ir de caractere SGBD-ul utilizeaz o secven de interclasare pentru a determina ordinea n care sunt sortate caracterele, stabilete pentru fiecare caracter codul ASCII sau codul multibyte pentru caracterele aparinnd unor limbi ale cror caractere nu se regsesc n ASCII. Se pot efectua sortri dup mai multe coloane: SELECT coloana1, coloana2, ..., coloanan FROM tabel ORDER BY coloana_sortare1 [ASC | DESC], coloana_sortare2 [ASC | DESC], ................ coloana_sortaren [ASC | DESC] ; Sortarea se face mai nti dup coloana_sortare1 dup care rndurile care au valori egale n coloana1 sunt sortate dup coloana a doua i tot aa. Sortarea dup poziia relativ a coloanelor SELECT * FROM Angajai ORDER BY 5 ASC, 2 DESC; #ordoneaz angajaii dup salariu(coloana salariu este a 5-a coloan n tabelul meu) i apoi dup nume(Angajat_Nume este a doua coloan n tabelul meu). !!! SQL prevede ca valorile pentru NULL-uri s fie fie mai mari fie mai mici dect valorile NOT NULL depinznd de SGBD.

Se pot face sortri dup expresii de coloane: SELECT title_id price, sales, price * sales AS 'Revenue' FROM titles ORDER BY 'Revenue' DESC; OBServaii: Micrsoft Access, Micrsoft SQL Server, PostgreSQL trateaz NULLurile ca fiind cele mai mici valori. Oracle i MySQL trateaz NULLurile ca fiind cele mai mari valori. n Microsoft SQL Server nu se pot face sortri dup coloane de tipul ntext, text, i image. n Oracle nu se pot face sortri dup coloane de tipul bloc, clob, nclob i bfile. n Microsoft Access nu se pot utiliza Alias-uri pentru coloane de tip expresie n ORDER BY.

Compararea se face doar ntre date similare. SELECT coloana1, coloana2, ... , coloanan FROM tabel WHERE coloana_test Operator valoare ;

7.4

FILTRAREA RNDURILOR UTILIZND WHERE

Se utilizeaz pentru a filtra rndurile nedorite din rezultat, ofer adevrata putere a instruciunii SELECT. Se poate utiliza mpreun cu operatori de condiie i/sau cu operatori de comparaie: Tipuri de condiie: OPERATOR OPERATORI SQL Comparaie =, <>, <, <=, >, >= Testarea corespondenei LIKE cu modelele Filtrarea dup domenii BETWEEN Filtrarea dup liste IN Testarea NULL-urilor IS NULL Operatori de comparaie: OPERATOR DESCRIERE = <> < <= > >= Egal cu Diferit de mai mic dect mai mic dect sau egal cu mai mare dect mai mare dect sau egal cu irurile de caractere sunt comparate lexicografic Valorile temporale sunt comparate cronologic.

SELECT title_name, pubdate FROM titles WHERE pubdate >= DATE '2001-01-01' ; #listeaz titlurile publicate n anul 2001 i ulterior SELECT title_name, price * sales AS 'Revenue' FROM titles WHERE price * sales > 10000; #listeaz titlurile care au generat venituri mai mari de zece mii de dolari. ntr-o clauz WHERE nu se pot utiliza funcii de comasare cum ar fi SUM() sau COUT(). Cu toate c SQL stipuleaz c tipul de liter(majuscul, minuscul) este semnificativ n cadrul irurilor ncadrate n ' ' sau '' '', secvena de interclasare specific SGBD-ului utilizat stabilete dac operaiile de comparare a irurilor sunt case sensitive sau case unsensitive. n mod implicit Micrsoft Access, Microsoft SQL Server i MySQL execut comparaii care nu depind de tipul de liter iar PostgreSQL i Oracle execut comparaii care depind de tipul de liter. n literarii de tip dat Microsoft Access se omite cuvntul DATE iar literele se ncadreaz n doua caractere #, ex: #2001-01-01#. n PostgreSQL pentru a compara valoarea dintr-o coloan de tip NUMERIC sau dECIMAL cu un numr real(n virgul mobil), se va converti n mod explicit numrul real la unul din tipurile Numeric sau Decimal cu ajutorul CAST().

7.4.1

COMBINAREA CONDIIILOR UTILIZND OPERATORI LOGICI OR, AND, NOT

SQL utilizeaz logica trivalent 3VL rezultatul unei expresii poate fi adevrat, fals sau necunoscut. AND True False unknown True false unknown OR True false unknown Conditie True false unknown True false unknown True True true true NOT Condiie False true unknown False false false False True false unknown Unknown false unknown unknown True unknown unknown

Condiii echivalente NOT(p AND q) NOT (p OR q) NOT (NOT p) (NOT p) OR (NOT q) (NOT p) AND (NOT q) p

Ordinea operatiilor:
INTERVAL BINARY, COLLATE ! - (unary minus), ~ (unary bit inversion) ^ *, /, DIV, %, MOD -, + <<, >> & | = (comparison), <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN BETWEEN, CASE, WHEN, THEN, ELSE NOT &&, AND XOR ||, OR = (assignment), :=

SELECT titles_name, type, price FROM titles WHERE type = 'history' OR type = 'biology' AND price < 20; #listeaz bibliografiile al cror pre este mai mic de 20 dolari. SELECT au_fname, au_lname, state FROM authors WHERE au_lname >= 'H' AND au_lname <= 'Zz' AND state <> 'CA'; #listeaz autorii ale cror nume de familie ncep cu una dintre literele cuprinse ntre H i Z i care nu locuiesc n California. SELECT au_fname, au_lname, city, state FROM authors WHERE (state = 'NY') OR (state = 'CO') OR (city = 'San Francisco') ; #listeaz autorii care locuiesc n statul New York, n statul Colorado sau n oraul San Francisco. SELECT au_fname, au_lname, state FROM authors WHERE NOT (state = 'CA') ; #listeaz autorii care nu locuiesc n statul California SELECT titles_name, sales, price FROM titles WHERE NOT (price < 20) AND (sales > 15000) ; #listeaz titlurile al cror pre nu este mai mic de 20 dolari i din care s-au vndut mai mult de 15.000 exemplare. SELECT title_id, type, price FROM titles WHERE (type = 'history' OR type = 'biography') AND price < 20; # listeaz id-urile i preurile crilor de istorie i biografice care au pre mai mic de 20 de dolari, operatorul AND are o prioritate mai mare dect operatorul OR OBServaii: ...WHERE state = 'NY' OR 'CA' <<--- GREIT ...WHERE state = 'NY' OR state = 'CA' <<--CORECT n MysQL False AND Unknown == Unknown MySQL pune la dispoziie: AND(&&), OR(||), NOT(!), XOR NOT((p AND q) OR (NOT p AND r)) = = NOT(p AND q) AND NOT (NOT p AND r) = = (NOT p OR NOT q) AND (p OR NOT r).

7.4.2

Testarea corespondenei cu modelele utiliznd

LIKE

SELECT coloana1, coloana2, ... , coloanan FROM tabel WHERE coloana_test [NOT] LIKE model ; Cu LIKE se pot regsi rnduri pe baza unor informaii pariale, se folosete cnd nu cunoatem o valoare exact. Operatori de tipul caracter de nlocuire Operator Corespunde cu Semn procent - corespunde cu orice ir de zero sau mai multe caractere _ caracter liniu de subliniere(underscore) - corespunde cu orice caracter(numai un singur caracter) Exemple de modele cu % i _ MODEL Corespunde cu %
Corespunde cu o valoare ir de lungime mai mare sau egal cu 1 care ncepe cu A incluznd irul compus numai din A: 'A', 'Anonimous', 'AC/DC' '%s' corespunde cu o valoare ir de lungime mai mare sau egal cu 1 care se termin cu s, incluznd irul compus numai din litera s. O valoare cu zerouri posterioare(dup s) nu corespunde. Exemple viabile: 'Victoria Falls', 's', 'Ares', '%in%' corespunde cu o valoare ir de lungime mai mare sau egal cu 2 care conine in indiferent de poziie: 'in', 'inch', 'Linux' 'lynchpin' '_ _ _ _' corespunde cu orice valoare ir de lungime egal cu 4. Exemple de corespondene: 'ABCD', 'I am', 'Jack' 'Qua_ _' corespunde cu orice valoare ir de lungime egal cu 5 care ncepe cu Qua: 'Quack', 'Quaff' '_re_' corespunde cu o valoare ir de lungime eal cu 4 care are re drept al doilea i al treilea caracter: 'Tree', 'area', 'free' '_re%' corespunde cu o valoare ir de lungime mai mare sau egal cu 3 care poate ncepe cu orice caracter i are re drept al doilea i al treilea caracter: 'Tree', 'area', 'fret', 'fretful' '%re_' corespunde cu o valoare ir de lungime mai mare sau egal cu 3 care are re drept antepenultimul si penultimul caracter: 'Tree', 'area', 'Blood red' [bsdm%] corespunde irurilor de caractere care ncep cu una din literele 'b', 's', 'd', 'm' [!bsdm%] ---- // ---- care NU ncep cu una din literele 'b', 's', 'd', 'm' [^bsdm%] 'A%'

1) LIKE funcioneaz numai cu iruri de caractere nu i cu numere sau valori temporale 2) LIKE utilizeaz un model cu care sunt comparate valorile. Un model este un sir ncadrat de caractere de citare i care con ine caractere litere care trebuie s corespund exact i orice combina ie posibil de caractere de nlocuire. 3) Atenie!: Unele SGBD-uri sunt case-sensitive altele sunt caseunsensitive 4) se pot nega condiiile LIKE sub forma NOT LIKE 5) n cel mai simplu caz n care un model nu conine caractere de nlocuire, LIKE funcioneaz ca o comparaie = iar NOT LIKE ca o compara ie <>. 6) Pentru a cuta valori care conin caractere de nlocuire vom utiliza cuvntul cheie ESCAPE

Observaii:

SELECT title_name FROM titles WHERE title_name LIKE '%!%%' ESCAPE '!' ; #listeaz titlurile care contin semnul procent, numai % care urmeaz dup ! are neles, celelalte dou caractere % acioneaz drept caractere de nlocuire. ... WHERE coloana LIKE '100!%' ESCAPE '!' ; #corespunde irului 100%. '_op' corespunde cu 'top', 'hop', 'pop' etc. '!_op' corespunde cu '_op'

'[a-c]at' corespunde cu 'bat', cat, dar nu cu 'fat', primul caracter trebuie s fie cuprins ntre 'a' i 'c' inclusiv 'se[^n]'% corespunde cu orice ir de lungime mai mare sau egal cu 2 care ncepe cu se i care nu are caracterul n pe a treia poziie. WHERE phone NOT LIKE '212-%' <==> WHERE NOT phone LIKE '212-%' <==> WHERE NOT phone NOT LIKE '212-%' Microsoft Access nu accepta clauza ESCAPE dar se poate ncadra un caracter de nlocuire cu paranteze drepte pentru a-l transforma n caracter literar sau nlocui cu WHERE col LIKE '%[%]%'; Microsoft SQL Server accept expresiile regulate n stil Posix, [] coresp. cu orice caracter singular care aparine unui interval.

7.4.3

Filtrarea dup domenii utiliznd

BETWEEN
Utilizm BETWEEN pentru a determina dac o valoare dat se afl ntr-un domeniu specificat. SELECT coloane FROM tabel WHERE coloana_test [NOT] BETWEEN val_min AND val_max ; OBServaii: 1) BETWEEN funcioneaz cu iruri de caractere, cu nume i cu valori temporale. 2) intervalul specificat prin BETWEEN conine o valoare inferioar i o valoare superioar separate prin AND. 3) condiiile BETWEEN reprezint o clauz convenional, avantajoas pentru c este scurt. Se poate reproduce comportarea acesteia utiliznd AND: WHERE coloana_test BETWEEN val_minim AND val_max <===========> WHERE (coloana_test >= val_minim) AND (coloana_test <= val_maxim) 4) BETWEEN specific un domeniu inclusiv n care att valoarea inferioar ct i valoarea superioar sunt incluse n cutare. Pentru a specifica un domeniu exclusiv(exclude marginile) se utilizeaz WHERE (coloana_test > val_minim) AND (coloana_test < val_maxim) 5) Comparaiile ntre iruri de caractere pot fi case-sensitive sau case-unsensitive funcie de SGBD. 6) Se poate nega o condiie BETWEEN sub forma NOT BETWEEN 7) Se poate combina BETWEEN cu AND sau OR.

SELECT title_id, pudbate FROM titles WHERE pubdate BETWEEN DATE '2000-01-01' AND DATE '2000-12-31'; #listeaz titlurile publicate n anul 2000 SELECT title_id, price FROM titles WHERE price BETWEEN 10 AND 19.95; #listeaz titlurile ale cror preuri sunt cuprinse ntre 10 i 19.95 inclusiv SELECT title_id, price FROM titles WHERE (price > 10) AND (price < 19.95); #listeaz titlurile ale cror preuri sunt cuprinse ntre 10 i 19.95 exclusiv SELECT * FROM Persons WHERE LastName BETWEEN 'Hansen' AND 'Petterson'; #selecteaz persoanele ale cror nume sunt plasate alfabetic ntre Hansen i Petterson Alte observaii: 1) val_min trebuie s fie mai mic dect val_max i ambele valori trebuie s se conformeze tipului de date al coloanei coloana_test. 2) ... WHERE last_name BETWEEN 'F' AND 'Fz' ; returneaz persoanele ale cror nume ncepe cu litera 'F'. 3) Dac folosim PostgreSQL trebuie fcut conversia lui 19.95 la decimal CAST(19.95 AS DECIMAL) 4) Dac folosim Micrsoft Access trebuie omis cuvntul DATE i ncadrate datele ntre caractere #: #2000-01-01# 5) Dac folosim Micrsoft SQL Server se omite cuvntul cheie DATE i se folosete direct '2000-01-01'.

7.4.4

Filtrarea dup liste utiliznd

8.

IN Se utilizeaz pentru a determina dac o valoare dat corespunde cu vreuna dintre valorile dintr-o list specificat. SELECT coloana1, coloana2, ... , coloanan FROM tabel WHERE coloana_test [NOT] IN ( val1, val2, ..., valn ); OBServaii: 1) IN funcioneaz iruri de caractere, numere i valori temporare. 2) Lista specificat prin IN este ncadrat de paranteze i conine una sau mai multe valori separate prin virgul i nu este obligatori ca acele elemente s fie trecute ntr-o anumit ordine. 3) WHERE coloana_test IN (val1, val2, val3) < ======== ======= > WHERE (coloana_test = val1) OR (coloana_test = val2) OR (coloana_test = val3) ; 4) n funcie de specificaiile SGBD-ului, comparaiile ntre iruri de caractere pot fi case-sensitive sau case-unsensitive. 5) Se poate nega o condiie IN prin NOT IN i se poate combina cu alte condiii AND i OR 6) NOT care poate precede condiia IN este independent de NOT care precede coloana_test 7) Interogrile cu IN sunt mai uor de citit dect cele care conin nenumrate condiii OR, AND SELECT au_fname, au_lname, state FROM authors WHERE state NOT IN ('NY' , 'NJ', 'CA') ; #listeaz autorii care nu locuiesc ntr-unul din statele New York, New Jersey sau California. SELECT title_id, advance FROM royalities WHERE advance IN (0.00, 1000.00, 5000.00) ; #listeaz titlurile pentru care au fost pltite avansuri de 0 dolari, 1000 i 5000 de dolari SELECT * FROM PERSONS WHERE LastName IN ('Hansen', 'Petterson'); #selecteaz toate datele despre persoanele ale cror nume de familie sunt Hansen sau Petterson

Permit numerotarea rndurilor i a coloanelor, obinerea sumei unor valori provenind de la o singur coloan, calcularea valorii minime i maxime dintr-o coloan, filtrarea rezultatelor returnate de la interogare.. 8.1 Modificarea tipului de liter
UPPER(ir) - returneaz irul primit dup ce a convertit minusculele n majuscule. LOWER(ir) returneaz irul primit dup ce a convertit majusculele n minuscule. 1) Aceste funcii afecteaz numai literele, nu i cifrele, semnele de punctuaie. 2) Se utilizeaz pentru a formata rezultate i a efectua compara ii independente de tipul de liter n cadrul unei clauze Where. 3) Nu au efect asupra irurilor vide i asupra NULL-urilor. 4) Nu au efect pentru alfabetele n care nu exist minuscule sau majuscule. 5) n Micrsoft Access funciile au forma UCase(ir) i LCase(ir). 6) Oracle trateaz un ir vid ca si NULL. Exemplu cu Lower(), Upper() folosit n formatare

FUNCII SCALARE i AGREGAT

UPPER() i LOWER()

Exemplu cu Lower(), Upper folosit n cutare case unsensitive SELECT title_name FROM titles WHERE UPPER(title_name) LIKE '%MO%' ;

8.2

Eliminarea caracterelor nedorite TRIM()

Permite: - eliminarea caracterelor anterioare, posterioare sau ambele mul imi de caractere dar nu se poate utiliza pentru eliminarea caracterelor din interiorul unui ir. - implicit elimin spatiile nedorite dar poate elimina i zerouri sau asterixuri anterioare sau posterioare. - se utilizeaz adesea ntr-o clauz WHERE pentru a formata rezultate. Pentru a elimina spaiile nedorite dintr-un ir de caractere: TRIM ( [ [ LEADING | TRAILING | BOTH] FROM string ) string expresie sir(coloana de iruri de caractere, literar sir, rezultatul unei operaii sau funcii care returneaz un ir)
LEADING elimin spatii anterioare TRAILING elimin spatii posterioare BOTH elimin ambele tipuri de spaii, este opiunea implicit

SELECT '<' || ' AAA ' || '>' AS ''Untrimmed'' '<' || TRIM(LEADING FROM ' AAA ') || '>' AS ''Leading'', '<' || TRIM(TRAILING ' AAA ') || '>' AS ''Trailing'', '<' || TRIM(' AAA ') || '>' AS ''Both'' ; #elimin spaiile anterioare, posterioare i , respectiv, spaiile anterioare i posterioare din sirul ' AAA '. Caracterele '<' i '>' delimiteaz irurile din care s-au eliminat spa iile nedorite. Rezultatul: Untrimmed Leading Trailing Both ---------------------------------------------<AAA> <AAA> <AAA> <AAA> Pentru a elimina caracterele nedorite dintr-un sir de caractere: TRIM ( [ LEADING | TRAILING | BOTH ] 'trim_chars' FROM string) string irul din care trebuie eliminate caracterele nedorite trim_chars unul sau mai multe caractere care trebuie eliminate din string LEADING pentru eliminarea caracterelor anterioare TRAILING pentru eliminarea caracterelor posterioare BOH pentru eliminarea ambelor tipuri de caractere. SELECT Angajat_Prenume, TRIM(LEADING 'G' FROM Angajat_Prenume) AS "Trinmed fname" FROM Angajati; Elimina caracterul 'G' anterior din prenumele angajatilor

SELECT title_id FROM titles WHERE TRIM(title_id) LIKE ' T1_' ; #listeaz codurile de trei caractere ale titlurilor care ncep cu T1 ignornd spaiile anterioare i posterioare. 1) n Microsoft Access i Micrsoft SQL Server funciile de eliminare a caracterelor nedorite sunt LTrim(sir) i RTrim(sir) pentru eliminarea spaiilor anterioare respectiv posterioare i Trim(sir) pentru eliminarea ambelor tipuri de spaii. Replace(sir, find, replacement [, start] [,count] [,compare]) se folosete pentru eliminarea caracterelor care nu sunt spa ii. Operatorul + se utilizeaz pentru concatenarea de iruri. n MySQL utilizm functia CONCAT() pentru a rula interogrile de mai sus CONCAT ('<', 'AAA', '>') CONCAT('<', TRIM(LEADING FROM 'AAA'), '>') CONCAT('<', TRIM(TRAILINGFROM 'AAA'), '>') CONCAT('<', TRIM('AAA'), '>') n Oracle funciile de completare sunt LPAD() i LPAD().

8.3 Calculul lungimii unui sir CHARACTER_LENGTH()


CHARACTER_LENGTH() sau CHAR_LENGTH(). Returneaz numrul de caractere dintr-un ir. Caracteristici: 1) Numr caractere i nu octei, un caracter unicode e un singur caracter. 2) Lungimea unui sir vid este 0, dac un argument este null, func ia returneaz 0. 3) Se poate utiliza n clauzele SELECT, WHERE, ORDER BY.. SELECT au_lname, CHARACTER_LENGTH(au_lname) AS 'Nume' FROM authors ; #listeaz lungimea prenumelui autorilor SELECT title_name, CHARACTER_LENGTH(title) AS 'Len' FROM titles WHERE CHARACTER_LENGTH(title_name) < 30 ORDER BY CHARACTER_LENGTH(title_name) ASC ; #listeaz crile ale cror titluri conin mai putin de 20 caractere, sortate n ordinea ascendent a lungimii titlurilor SQL mai definete i BIT_LENGTH() - returneaz numrul de biti dintr-o expresie, BIT_LENGTH(B'1011100') returneaz 7, OCTET_LENGTH(), OCTET_LENGTH(b'01011111') ==8, OCTET_LENGTH('ABC') ==3. Microsoft Access i Microsoft SQL Server au implementate func ia LEN(sir) pentru calculul lungimii Oracle are implementat funcia LENGTH(sir) pentru calculul lungimii. Numrarea biilor, octeilor difer de la SGBD la SGBD, Microsoft Access folosete Len(), Microsoft SQL Server folosete DATALENGTH(), Oracle folosete LENGTHB(), MySQL folosete BIT_COUNT() i OCTET_LENGTH(), PostrGreSQL folosete OCTET_LENGTH().

8.4

Efectuarea operaiilor cu date i ore

8.5

Funciile pentru prelucrarea intervalelor de timp depinde de la SGBD la SGBD. Operaii cu valori temporale i intervale OPERAIA REZULTAT Valoare temporal Val. Temporal Interval Valoare temporal + - Interval Valoare temporal Interval + Valoare temporal Valoare temporal Interval + - Interval Interval Interval * / Valoare numeric Interval Valoare numeric * Interval Interval SELECT title_id, pubdate FROM titles WHERE EXTRACT(YEAR FROM pubdate) BETWEEN 2001 AND 2002 AND EXTRACT(MONTH FROM pubdate) BETWEEN 1 AND 6 ORDER BY pubdate DESC ; #listeaz crile publicate n prima jumtate a anului pentru anii 2001 si 2002 sortate n ordine descresctoare a datei de publicare. Funcia EXTRACT() izoleaz un singur cmp dintr-o valoare temporal sau dintr-un interval i returneaz acest cmp sub forma unui numr. Extragerea unei pri dintr-o valoare temporal sau dintr-un interval EXTRACT (field FROM datetime_or_interval) field partea ce trebuie returnat din valoarea datetimer_or_interval field poate fi: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, TIMEZONE_HOUR, TIMEZONE_MINUTE. OBServaii: 1) Calculele aritmetice cu date sunt foarte obinuite n lucrul cu bazele de date dar modul cum se fac depind de SGBD-uri 2) n Microsoft Access si Microsoft SQL Server funcia de extragere este DATAPART(datapart, date) ex: DATAPART('yyyy', pubdate) DATAPART('m', pubdate) 3) Oracle, MySQL i PostgreSQL accept valori diferite sau suplimentare pentru argumentul field al funciei EXTRACT(). 4) SGBD-urile au implementate i funcii de adugare de intervale la date:
DATEIFF() n Microsoft Access i SQL Serrver, ADD_MONTHS() n Oracle DATE_ADD() i DATE_SUB() pt. MySQL

CURRENT_USER Se folosete pentru a identifica utilizatorul activ al serverului de baze de date.

Obinerea informaiilor despre utilizator

SQL definete i funciile referitoare la utilizatori SESSION_USER, SYSTEM_USER. Utilizatorul curent semnific utilizatorul care ruleaz momentan interogrile SQL i lui i se atribuie anumite privilegii, mai sus se poate observa c utilizatorul este root, deci are drepturi depline asupra sistemului. OBServaii: 1) n Microsoft Acces : SELECT CurrentUser AS ''User'' ; 2) n Oracle: SELECT USER AS ''User'' FROM DUAL ; 3) n MySQL: SELECT USER() AS ''User'' ; 4) Microsoft SQL Server accept funciile: SESSION_USER i SYSTEM_USER. 5) MySQL accept funciile SESSION_USER() i SYSTEM_USER(). 6) n Oracle SYS_CONTEXT() returneaz atributele referitoare la utilizator ale unei sesiuni. 7) PostgreSQL accept funcia SESSION_USER.

8.6

Conversia tipurilor de date CAST()

n funcie de SGBD, uneori este posibil concatenarea unui sir de caractere cu un numr prin convertirea automat a cifrelor n caractere, pe cnd alte SGBD-uri nu permit nii mcar operaii ntre diverse tipuri de date numerice fr o operaie de conversie de tip. Conversia ntre tipurile de date se face cu funcia CAST(). Converii: - implicite (fr specificarea funciei CAST()) - explicite (utilizm funcia CAST()) Uneori nu poate avea loc conversia, nu putem converti valori la tipuri care nu le pot accepta. Orice tip de dat numeric poate fi convertit la tipul de dat caracter. Dac convertim tipuri caracter la tipuri numerice, SGBD-ul elimin automat spaiile, de asemenea se realizeaz trunchierea sau rotunjirea automat la convertirea din Decimal n Integer.

O conversie VARCHAR la CHAR poate duce la trunchierea sirului. E de preferat s folosim conversiile explicite, prin CAST(), pentru a ocoli posibilitatea pierderii preciziei. CAST ( expresie AS tip_dat ) expresie expresia care trebuie convertit tip_data tipul de dat la care trebuie fcut conversia expresiei. SELECT price AS ''price(DECIMAL)'', CAST(price AS INTEGER) AS ''price(INTEGER)'', '<' || CAST(price AS CHAR(8)) || '>' AS ''price(CHAR(8))'' , FROM titles ; #convertete preturile crilor din tipul de date DECIMAL n tipul de date INTEGER i CHAR(8). Caracterele '>' i '<' delimiteaz irurile de caractere de tip CHAR(8) Rezultat: price(DECIMAL) price(INTEGER) price(CHAR(8)) -----------------------------------------------------------21.99 21 <21.99 > 43.78 43 <43.78 > OBServaii:
CAST() se poate utiliza n clauze SELECT, WHERE sau ORDER BY sau oriunde este permis o expresie. Conversiile de la un tip superior la un tip inferior sunt cele mai periculoase deoarece se pot pierde date i rezultatele pot fi incorecte, exemplu de la INTEGER la SMALLINT. 1) Micrsoft Access nu are implementat func ia CAST() dar are implementate funciile CStr(expr), CInt(expr), CDec(expr), Space(number) pentru a aduga spaii la irul i Left(ir, lung) pentru a trunchia iruri. 2) n Microsoft SQL Server se utilizeaz + pentru concatenarea irurilor: '<' + CAST(price AS CHAR(8) + '>' 3) Oracle nu permite conversia caracterelor la tipul CHAR(lung) cnd lung < lungimea irului iniial de aceea se folose te SUBSTRING() pentru a trunchia irurile prea lungi: CAST(sales AS CHAR(8)) || 'copies sold of' || SUBSTR(title_name, 1, 20). 4) n MySQL CAST() este limitat la tipurile de date binar, temporal i ntreg. Utilizai SIGNED n loc de INTEGER ca data_type. Se poate utiliza RPAD(ir, lung, padstring) pentru adugarea de spaii i func ia LEFT( ir, lung) pentru trunchierea irului. CONCAT() se utilizeaz pentru concatenarea irurilor: CAST(price AS SIGNED) CONCAT('<', RPAD(price, 8,''), '>') 5) n PostgreSQL se utilizeaz SUBSTRING() pentru trunchierea irului i TO_CHAR(nr, format) pentru a converti un numr ntr-un ir CAST(price AS INTEGER) '<' || TO_CHAR(price, '99.99') || '>' i SUBSTRING(title_name FROM 1 FOR 20)

8.7

Evaluarea valorilor condiiilor utiliznd CASE

Aduce o urm de programare structurat n limbajul SQL i a fost introdus odat cu standardul SQL-92. Reprezint echivalentul lui if-the-else dintr-un limbaj structurat i se folosete deci pentru a evalua mai multe condiii i a returna o singur valoare pentru prima condiie adevrat.
Expresia CASE simpl CASE valoare_de_comparat WHEN valoare1 THEN rezultat1 WHEN valoare2 THEN rezultat2 ................................ WHEN valoaren THEN valoaren [ ELSE rezultat_default ] END Exemplu: SELECT title_id, type, price CASE type WHEN 'history' THEN price * 1,5 WHEN 'psyhology' THEN price *2 ELSE price END AS 'New Price' FROM titles ORDER BY type ASC, title_id ASC; #crete pretul crilor de istorie cu 50% i ale celor de psihologie cu 100%lsnd neschimbate pre urile celorlalte cri Expresie CASE cu cutare: CASE WHEN conditie1 THEN rezultat1 WHEN condiie2 THEN rezultat2 ...................... WHEN condiien THEN rezultatn [ ELSE rezultat_default ] END Exemplu: SELECT title_id CASE WHEN sales IS NULL THEN 'Unknown' WHEN sales <= 1000 THEN 'No more than 1000' WHEN sales <=10000 THEN 'Between 1001 and 10000' ELSE 'Over 10000' END AS 'Categorii Vanzari' FROM titles ORDER BY sales ASC ;

#listeaz crile clasificate conform diverselor intervale de vnzri, sortate n ordinea ascendent a vnzrilor. Alte exemple: Prevenirea mpririi la 0(zero) CASE n<>0 THEN expr / n ELSE 0 END Observaii: 1) Microsoft Access nu accept expresia CASE dar se poate utiliza expresia SWITCH(condiie, rezultat1, condiie, rezultat2, ...) SWITCH ( type IS NULL, NULL, type = 'history', price * 1.50 type = 'psyhology', price * 2, type IN ('biography', 'children', 'computer' ) price) #pt CASE simplu SWITCH ( sales IS NULL, 'Unknown' , sales <=1000, 'Not more than 1000' , sales <10000 , 'Between 1001 and 10000' , sales > 10000, 'Over 10000' ) #pt exemplul CASE cu cutare 2) Oracle 9i introduce expresiile CASE, pentru versiunea 8i, exemplele CASE simple trebuie transformate n exemple CASE cu cutare sau trebuie utilizat funcia DECODE(val_de_comparat, valoare1, rezultat1, valoare2, rezultat2, ...) 3) n PostgreSQL numerele n virgul mobil trebuie convertite la DECIMAL, ex: price * CAST((1.5) AS DECIMAL);

2) Micrsoft Access nu accept COALESCE() dar se poate utiliza Switch: SWITCH(state IS NOT NULL, state, state IS NULL, 'N/A') 3) Oracle 9i introduce funcia Coalesce() dar n 8i trebuie s se foloseasc funcia NVL(expr1, expr2) care preia ca argumente numai dou expresii.

8.8

Testarea Null-urilor utiliznd COALESCE()

Returneaz prima expresie non-null din argumentele sale i este utilizat pentru a afia o anumit valoare n locul unui null n rezultat. COALESCE (expresie1, expresie2, expresie3) < ========= echivalent cu ============> CASE WHEN expresie1 IS NOT NULL THEN expresie1 WHEN expresie2 IS NOT NULL THEN expresie2 ELSE espresie3 END Exemplu: SELECT pub_id, city, COALESCE(state, 'N/A') AS 'state' , country FROM publishers ; #listeaz adresele editurilor, dac n coloana state se afl null se tiprete 'N/A' OBServaii 1) Se utilizeaz n clauzele SELECT, WHERE, ORDER BY.

Compararea expresiilor utiliznd NULLIF() Compar dou expresii i returneaz un null dac expresiile sunt egale sau returneaz prima expresie dac expresiile sunt diferite. Se utilizeaz adesea pentru a converti la Null o valoare care trebuie definit de utilizator i care lipsete, e necunoscut sau nu este aplicabil. Adesea cei care ntrein bazele de date prefer s foloseasc -1 sau 'N/A' pentru cmpurile n care ar fi trebuit s adauge NULL. SGBD-urile ofer funcii pentru prelucrarea cmpurilor Null de aceea e de preferat uneori ocuparea acestora cu null-uri. NULLIF(expr1, expr2) <=========== echivalent cu ==========> CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 #nullif verific dac expr1=expr2, dac Da pune n expr1 valoarea NULL dac nu returneaz valoarea expr1. END Exemplu: SELECT title_id, contract, NULLIF(contract, 0) AS 'Null contract' FROM titles ; #modific valorile 0 n Null-uri. OBServaii: 1) NULLIF() se utilizeaz n SELECT, WHERE, ORDER BY 2) Microsoft Access nu accept NULLIF() dar se poate utiliza n schimb IIF(expr1 = expr2, NULL, expr1) Exemplu pt interogarea de mai sus: IIF(contract = 0, NULL, contract) 3) Oracle 9i accept functia NULLIF() dar Oracle 8i nu are aceast funcie implementat, trebuie folosit CASE, exemplu pentru interogarea de mai sus: CASE WHEN contract = 0 THEN NULL ELSE contract END

8.9

Numite i funcii de comasare sau funcii pentru mulimi, ele acioneaz asupra unui grup de valori i genereaz un sigur rezultat. Se pot utiliza pentru: - numrarea rndurilor i a coloanelor; - obinerea unor valori medii pentru coloane; - obinerea unor valori provenind de la o singur coloan; - obinerea valorilor minime sau maxime dintr-o coloan; - filtrarea rezultatelor returnate de o interogare. 1) NU se accept imbricarea funciilor de comasare: !!! NU E PERMIS: SELECT SUM(AVG(salariu)) FROM Angajati 2) Funciile de comasare NU pot aparea n clauzele WHERE: !!!NU E PERMIS: SELECT titled_id FROM titles WHERE sales=MAX(sales) ; 3) Se pot folosi mai multe funcii de comasare n aceeai instruciune SELECT: SELECT MIN(sales), MAX(sales) FROM titles; 4) Oracle permite imbricarea expresiilor de comasare n interogrile GROUP BY: permite de exemplu interogarea: SELECT AVG(MAX(sales)) FROM titles GROUP BY type (legal n Oracle) MySQL 4.0 precum i versiunile anterioare nu accept subinterogri.

Funcii AGREGAT

8.11

Gsirea valorii maxime MAX()

Se folosete pentru gsirea valorilor maxime dintr-o mulime de valori. Se folosete MAX(expresie) i opereaz de asemenea cu tipuri de date caracter, numeric i temporal. Pentru tipurile de date numeric, MAX() caut valoarea maxim iar n cazul datelor de tipul ir de caractere, cutarea este case-sensitive sau case-unsensitive depinznd de SGBD. Utilizarea lui MAX() cu DISTINCT() este fr sens la fel ca si in cazul utilizrii lui DISTINCT() mpreun cu MIN(). SELECT MAX(au_lname) AS 'Max last name' FROM authors; #exemplu de utilizare a lui MAX() pentru iruri de caracter, returneaz ultimul nume n ordine alfabetic SELECT MIN(price) AS 'Min price', MAX(price) AS 'Max price' MAX(price) MIN(price) AS 'Range' FROM titles; #returneaz cel mai mic pre i cel mai mare i diferena dintre ele SELECT MAX(price * sales) AS 'Max history revenue' FROM titles WHERE type = 'history' ; #returneaz cel mai mare venit adus de o carte de istorie

8.10

GSIREA VALORILOR MINIME MIN()

Se folosete pentru gsirea valorii minime dintr-o mul ime de valori. SELECT MIN(criteriu) FROM Tabel; OBServaii: 1) lucreaz cu tipuri de date caracter, numeric i temporal. 2) Pentru coloanele cu date numerice, MIN() gse te valoarea cea mai mic. 3) Pentru coloanele care conin iruri de caractere, cutarea poate fi casesensitive sau case-unsensitive depinznd de SGBD. SELECT MIN(price) AS 'Min price' FROM titles ; #gsete cartea cea mai ieftina din baza de date a librriei SELECT MIN(pubdate) AS 'Earliest pubdate' FROM titles; #gsete cea mai timpurie publicaie din crile avute de librrie n baza de date. SELECT MIN(pages) AS 'Min history pages' FROM titles WHERE type = 'history'; #gsete cartea de istorie cu cele mai puine pagini

OBServaii: 1) La compararea pentru egalitate dou iruri de tipul VARCHAR, s-ar putea ca SGBD-ul s completeze mai nti la dreapta cu spaii irul mai scurt i apoi s compare irurile caracter cu caracter, Astfel irul 'Jack' i 'Jack ' pot fi egale, n funcie de SGBD.

8.14

Calcularea unei sume utiliznd SUM()

8.15

Calculul unei medii utiliznd AVG()

Se folosete pentru a afla suma valorilor dintr-o mulime de valori. SUM(expresie) Se poate folosi cu valori numerice sau literali. SELECT SUM(advance) AS 'Total advances' FROM royalities ; #returneaz suma avansurilor pltite ctre autori. SELECT SUM(sales) AS ' Suma vnzrilor pe 2000 ' FROM titles WHERE pubdate BETWEEN DATE'2000-01-01' AND DATE '2000-12-31' ; #returneaz numrul total de vnzri ale crilor publicate n 2000 SELECT SUM(price) AS 'Total price', SUM(sales) AS 'Total sales', SUM(price *sales) AS 'Total revenue' FROM titles ;#returneaz preul total, vnzrile i suma ncasat. OBServaii: 1) Funcia SUM() lucreaz numai cu tipuri de date numerice. 2) n literalii de tip dat din Microsoft Access se omite cuvntul DATE i se ncadreaz n #, #2001-09-11#. 3) n literalii de tip dat din Microsoft SQL Server se omite DATE i se ncadreaz n '': '2011-09-11'.

Se folosete pentru calculul mediei(aritmetice) a unui set de valori. AVG(expresie) 1) Se folosete de asemenea doar cu valori numerice. 2) Media valorilor dintr-o mulime care nu conine nici un rnd este NULL, nu 0(zero). 3) Dac am schimbat NULL-urile n valori -1 sau 0, rezultatul va fi invalid, trebuie s folosim funcia NULLIF() pentru a repune nulluri. SELECT AVG(price * 2) AS 'AVG (price * 2)' FROM titles ; # returneaz pretul mediu al unei cri SELECT AVG(sales) AS 'Avg(sales)', SUM(sales) AS 'Sum(sales)' FROM titles WHERE type = 'business' ; #returneaz vnzarea medie i vnzarea total pentru crile de afaceri SALES title_id, sales FROM titles WHERE sales > (SELECT AVG(sales) FROM titles) ORDER BY sales DESC ; # utilizeaz o subinterogare perntru a afia toate crile cu vnzare peste medie. OBServaii: 1) MySQL 4.o i versiunile anterioare nu accept subinterogri deci ultima interogare nu va merge.

Exemplu de interogare suma cheltuielilor cu salariile angajailor din tabelul Angajati ai bazei mele de date.

8.16

Numrarea rndurilor COUT()

8.17

Comasarea valorilor distincte DISTINCT

Se utilizeaz pentru numrarea rndurilor dintr-o coloan . COUT(expr) returneaz numrul de rnduri n care expr nu este null COUT(*) - returneaz numrul total de rnduri din mul ime incluznd null-urile i duplicatele. 1) COUT() nu returneaz niciodat null ci doar un nr ntreg sau 0. 2) Utilizarea lui DISTINCT cu COUNT nu are sens SELECT COUNT(title_id) AS 'COUNT(title_id)', COUNT(price) AS 'COUNT(price)', COUNT(*) AS 'COUNT(*)' , FROM titles ; # numrul de rnduri returnate poate diferi dac coloana price conine null-uri SELECTAT COUNT(title_id) AS ''COUT(title_id)'', COUNT(price) AS ''COUT(price)'', COUNT(*) AS ''COUT(*)'' FROM titles WHERE price IS NOT NULL ; # elimin nainte rndurile care conin SELECT COUNT(title_id) AS ''COUNT(title_id)'', COUNT(price) AS ''COUNT(price)'', COUNT(*) AS ''COUNT(*)'' FROM titles WHERE price IS NULL; REZULTATELE interogrilor: COUNT(title_id) COUNT(price) COUNT(*) -------------------------------------------------------13 12 13 COUNT(title_id) COUNT(price) COUNT(*) -------------------------------------------------------12 12 12 COUNT(title_id) COUNT(price) COUNT(*) -------------------------------------------------------1 0 1 COUNT Nu returneaz niciodat null ci un ntreg pozitiv sau zero. Utilizarea clauzei DISTINCT cu funcia COUNT() nu are sens.

Se utilizeaz pentru eliminarea duplicatelor din calcule efectuate de funcii de comasare: agg_functie([ALL | DISTINCT] expr) aff_functie: MIN, MAX, SUM, AVG, COUNT expr: nume de coloan, literar sau expresie numerica ALL are ca efect aplicarea funciei de comasare tuturor valorilor iar prin opiunea DISTINCT se specific luarea n considerare a fiecrei valori o singur dat. Cnd este utilizat cu SUM(), AVG() i COUNT(expr), Distinct elimina valorile duplicate naintea calculrii sumei, mediei respectiv numrrii rndurilor. Utilizarea mpreun cu MIN() sau MAX() nu are sens de moment ce rezultatul nu se modific. Utilizarea mpreuna cu COUNT() duce la eroare.

8.18

Calcularea sumei unui set de valori distincte SUM()

null

SUM(expresie) SELECT SUM(Criteriu_Sumare) FROM Tabel ; SELECT SUM(Crit_Sumare) AS Alias FROM Tabel ;

Pentru funcia SUM nu se poate utiliza operatorul (*) dar se poate specifica ALL sau DISTINCT pentru a aduna toate valorile sau doar valorile distincte SELECT SUM(ALL salariu) FROM Angajati ; SELECT SUM(DISTINCT salariu) FROM Angajati;

8.19 Determinarea valorii maxime/minime MAX() MIN()


SELECT MAX(Criteriu) FROM Tabel ; SELECT MIN(Criteriu) FROM Tabel ;

Max, Min funcioneaz i cu valori iruri de caractere, ordonarea fcndu-se alfabetic

8.19 Calcularea mediei unui set de valori distincte AVG()


AVG(expresie) AVG(DISTINCT expresie) expresie nume de coloan, literal, expresie numeric Rezultatul este un tip de date cel puin la fel de precis ca cel mai precis tip de date utilizat n expresie. Face media salariilor angajatilor din tabel, de moment ce nu am specificat cuvntul cheie DISTINCT, funcia adun toate valorile, fie c au mai aprut odat, i le mparte la cte sunt. Exemple de utilizare a funciilor AVG(), COUNT(), MIN(), MAX(), SUM() mpreun cu DISTINCT: SELECT COUNT(*) AS ''COUNT(*)'', COUNT(price) AS ''COUNT(price)'' SUM(price) AS ''SUM(price)'', AVG(price) AS ''AVG(price)'' FROM titles ; SELECT COUNT(DISTINCT price) AS ''COUNT(DISTINCT)'', SUM(DISTINCT price) AS ''SUM(DISTINCT)'', AVG(DISTINCT price) AS ''AVG(DISTINCT)'' FROM titles; --------------------------------------------------------------SELECT COUNT(au_id) AS ''COUNT(au_id)'' FROM titles_authors ; SELECT DISTINCT COUNT(au_id)AS ''DISTINCT COUNT(au_id)'' FROM titles_authors ; SELECT COUNT(DISTINCT au_id) AS ''COUNT(DISTINCT au_id)'' FROM title_authors ; Clauza DISTINCT are nelesuri diferite daca este utilizat ntr-o clauz SELECT sau ntr-o funcie de comasare.

OBServaii: 1) Microsoft Access nu accept utilizarea lui distinct n funciile de comasare: SELECT SUM(DISTINCT price) FROM Preturi ; NU va merge, interogarea trebuie transformat n; SELECT SUM(price) FROM(SELECT DISTINCT price) FROM titles; Aceast alternativ nu permite combinarea unciilor de comasare care utilizeaz clauza DISTINCT. 2) n Microsoft SQL dac folosim DISTINCT expresie, expresie nu poate fi dect o coloan, nu va functiona: SELECT COUNT(DISTINCT price * sales) FROM titles; 3) MySQL accept construcia COUNT(DISTINCT expr) dar nu i construcia AVG(DISTINCT expr) MAX(), MIN(), COUNT, AVG() NU pot fi n clauza WHERE SELECT Angajat_Nume, Angajat_Prenume, salariu FROM Angajati WHERE salariu = MAX(salariu) ; #<--- GRESIT !!!!!!! Pentru a afla numele, prenumele i salariul salariatului cu cel mai mare salariu folosim urmtoarea interogare:

Pentru a afla salariaii cu salariu peste medie:

9.

SINTEZA i GRUPAREA DATELOR GROUP BY

Se utilizeaz pentru a mpri tabelul n grupuri(categorii) logice i a obine rezultate statistic pentru fiecare grup cu ajutorul funciilor de comasare. Sintaxa: SELECT CampA, FuncAgregat(ArgFuncAgregat) FROM Tabel WHERE ConditieWhere GROUP BY CampA ; #Sunt parcurse valorile din CampA i sunt formate grupuri de nregistrri corespunztoare fiecrei valori posibile din CampA SELECT AngajatID, COUNT(*) AS ProiecteImportante FROM AngajatiProiecte WHERE nrOreSaptamana > 10 GROUP BY AngajatID; # n primul rnd sunt grupate nregistrrile avnd acelai AngajatID apoi se execut funcia COUNT pentru a afla numrul de proiecte la care fiecare angajat lucreaz mai mult de 10 ore/saptamana. AngajatID ProiecteImportante ---------------------------------1 3 2 2 SELECT au_id, COUNT(*) AS ''num_books'' FROM title_authors GROUP BY au_id ; #afieaz numrul de cri pe care le-a scris fiecare autor(singur sau n calitate de coautor): au_id num_books -------------------A01 3 A02 4 A03 1 Clauza GROUP BY determin calcularea valorii din coloana num_books pentru fiecare autor n parte OBServaii: 1) Clauza GROUP BY trebuie s se afle dup clauza WHERE i nainte de clauza ORDER BY. 2) Coloanele de grupare pot fi specificate prin nume de coloane sau de coloane derivate 3) Clauza GROUP BY trebuie s conin toate coloanele care nu sunt de comasare din clauza SELECT, exemplu de interogare gresit: SELECT type, pub_id, COUNT(*) FROM titles GROUP BY type <--

GRESIT deoarece coloana pub_id nu face parte din clauza GROUP BY Deoarece GROUP BY nu poate returna dect un singur rnd pentru fiecare valoare din coloana type, nu exist nicio modalitate prin care se pot returna mai multe valori din coloana pub_id asociate cu o anumit valoare din coloana type. Dac o coloan conine un null, rndul respectiv devine un grup n cadrul rezultatului, dac respectiva coloan conine mai multe grupuri, ele vor fi incluse n acelai grup chiar dac null-urile nu sunt identice. Pentru a elimina anumite rnduri se folosete clauza WHERE. Nu se pot folosi alias-urile de coloan n cadrul clauzei GROUP BY Pentru gruparea rndurilor SELECT coloane FROM Tabel [WHERE conditie_de_cautare] GROUP BY coloane_de_grupare [HAVING conditie_de_cautare] [ORDER BY coloane_sortare] ; Coloanele din lista coloane care nu sunt coloane de comasare trebuie s apar i n lista coloane_de_grupare. 4) Clauza GROUP BY restricioneaz numrul de rnduri al rezultatului: pentru fiecare valoare distinct din coloana sau coloanele de grupare exist un singur rnd n rezultat. 5) Dac instruciunea cuprinde o clauz WHERE, SGBD-ul grupeaz valorile dup aplicarea condiiei specificate de coloane_de_cautare rndurilor din tabel. 6) Dac instruciunea cuprinde o clauz ORDER BY atunci coloanele din lista coloane_de_sortare trebuie s apar i n lista coloane. 7) n Microsoft SQL Server se poate utiliza cuvntul cheie ALL pentru a include toate nregistrrile ntr-un grup: SELECT CampA, FunctAgregat(Criteriu) FROM Tabel WHERE ConditieWhere GROUP BY ALL CampA ; SELECT state, COUNT(state), COUNT(*) FROM publishers GROUP BY state ; # va genera un rezultat asemntor: state COUNT(state) COUNT(*) -------- ------------------------------NULL 0 1 CA 2 2 NY 1 1

SELECT type, SUM(sales), AVG(sales) FROM titles GROUP BY type; # calculeaz cteva statistici de sintez pentru fiecare tip de carte i va genera un rezultat de forma: TYPE SUM(sales) AVG(sales) COUNT(sales) -------------------- -------------- -----------------biography 1611521 537173.67 3 children 9095 4547.50 2 computer 25667 25667.00 1 SELECT type, SUM(sales) AS ''Sum(sales)'', AVG(sales) AS ''Avg(sales)'', COUNT(sales) AS ''Count(sales)'' FROM titles WHERE price >= 13 GROUP BY type ORDER BY ''Sum(sales)'' DESC ; # s-au adugat clauzele ORDER BY i WHERE pentru a elimina crile cu pre mai mic de 13USD i pentru a sorta rezultatul final. SELECT pub_id, type, COUNT(*) AS ''Count(*)'' FROM titles GROUP BY pub_id, type ORDER BY pub_id ASC, ''Count(*)'' DESC ; #listeaz numrul de cri de fiecare tip publicate de fiecare editur sortate n ordinea cresctoare a codurilor editurilor i apoi n ordinea descresctoare a numrului pub_id type Count(*) -----------------------P01 biography 3 P01 history 1 P02 computer 1 P03 history 2 Dou interogri care returneaz acelai rezultat SELECT type FROM titles GROUP BY type;
type --------biography childre computer

domeniu de valori ale vnzrilor sortate n ordinea corespunztoare a vnzrilor, rezultatul va fi de genul: Sales category Num titles ------------------------------------Unknown 1 No more than 1000 1 Between 1001 and 10000 3 Between 10001 and 100000 5 Over 100000 2 Observaii: 1) n Microsoft Access se va utiliza funcia Switch() n locul clauzei CASE 2) MySQL nu permite utilizarea expresiei CASE n cadrul unei clauze GROUP BY 3) MySQL i PostgreSQL permit utilizarea aliasurilor n clauze GROUP BY.

SELECT CASE WHEN sales IS NULL THEN 'Unknown' WHEN sales <=1000 THEN 'No more than 1000' WHEN sales <= 10000 THEN 'Between 1001 and 10000' WHEN sales <= 100000 THEN 'Between 10001 and 100000' ELSE 'Over 100001' END AS 'Sales category', COUNT(*) AS 'Num titles' FROM titles GROUP BY CASE WHEN sales IS NULL THEN 'Unknown' WHEN sales <=1000 THEN 'No more than 1000' WHEN sales <= 10000 THEN 'Between 1001 and 10000' WHEN sales <= 100000 THEN 'Between 10001 and 100000' ELSE 'Over 1000010 END ORDER BY MIN(sales) ASC ; Afieaz numrul de cri din fiecare

SELECT DISTINCT type FROM titles;

9.2

HAVING

Clauza HAVING impune o condiie clauzei GROUP BY la fel cum WHERE impune o condiie clauzei SELECT. 1) Clauza HAVING se plaseaz dup clauza GROUP BY i naintea clauzei ORDER BY 2) La fel cum WHERE limiteaz numrul de rnduri afiate de clauza SELECT, HAVING limiteaz numrul de grupuri afiate de clauza GROUP BY. 3) Condiia de cutare specificat de clauza WHERE este aplicat nainte de efectuarea operaiei de grupare iar condiia de cutare specificat de clauza HAVING este aplicat dup efectuarea gruprii. 4) Condiia HAVING e asemntoare celei WHERE doar c HAVING poate conine funcii de comasare. 5) HAVING poate referi oricare din elementele care apar n cadrul listei SELECT. Ordinea n care sunt aplicate clauzele WHERE, GROUP BY i HAVING: 1) Clauza WHERE filtreaz rndurile rezultate n urma operatiilor specificate de clauzele FROM i JOIN. 2) Clauza GROUP BY grupeaz rndurile returnate de clauza WHERE. 3) Clauza HAVING filtreaz rndurile din grupurile rezultate. HAVING (conditie_de_cautare) SELECT au_id, COUNT(*) AS ''num_books'' FROM titles_authors GROUP BY au_id HAVING COUNT(*) >= 3; #listeaz numrul de cri pe care le-a scris fiecare autor(singur sau n calitate de coautor), dar numai pentru autorii care au scris cel puin 3 cri au_id num_books --------------------A01 3 A02 4 A04 4 A06 3 n loc de a realiza listarea numrului de cri pe care le-a scris fiecare autor, singur sau drept coautor, acest exemplu utilizeaz clauza HAVING pentru a lista numai autorii care au scris cel puin 3 cri.

SELECT type, COUNT(price), AVG(price*sales) FROM titles GROUP BY type HAVING AVG(price*sales) > 100000 ; #listeaz numrul de titluri i ncasrile medii pentru f\tipurile de cri cu ncasri medii mai mari de 100000USD Condiia specificat prin HAVING este o expresie de comasare prezent i n clauza SELECT. type COUNT(price) AVG(price*sales) ----------------------------------------------biography 3 12484879.00 computer 1 10253996.65 Putem elimina expresia AVG(price*sales) din expresia de mai sus: SELECT type, COUNT(price), FROM titles GROUP BY type HAVING AVG(price*sales) > 100000 ; type COUNT(price) --------------------------biography 3 computer 1 Utilizarea Clauzei HAVING mpreun cu clauza WHERE: SELECT type, SUM(sales), AVG(price) FROM titles WHERE pub_id IN ('P03' , 'P04') GROUP BY type HAVING SUM(sales) > 10000 AND AVG(price) < 20 ; #Pentru crile publicate de editurile cu codurile P03 i P04 se listeaz totalul vnzrilor i preul mediu pe tip de carte, pentru tipurile de cri caracterizate prin vnzri mai mari de 10000USD i printr-un pre mediu mai mic de 20USD type SUM(sales) AVG(price) ---------------------------------psychology 308564 9.31 OBServaii: Having ar trebui utilizat doar cu funcii comasate, singurele condiii care ar trebui specificate ntr-o clauza Having sunt acelea care trebuie aplicate dup efectuarea operaiei de grupare. Specificarea n clauza WHERE a condiiilor care pot fi aplicate naintea efecturii operaiei de grupare este mai eficient Urmtoarele dou interogri sunt echivalente dar prima este mai rapid:

SELECT pub_id, SUM(sales) FROM titles #<<<Mai rapid WHERE pub_id IN('P03', 'P04') GROUP BY pub_id HAVING SUM(sales) > 10000; < ============ Echivalent cu ========== > SELECT pub_id, SUM(sales) FROM titles #<<<Mai lent GROUP BY pub_id HAVING SUM(sales) > 10000 AND pub_id IN('P03' , 'P04') ;

10

REGSIREA DATELOR DIN MAI MULTE TABELE

Toate interogrile de pn acum au regsit rnduri doar dintr-un tabel. n continuare se vor studia metodele de interogare a mai multor tabele( join ) - operaia de compunere. Numele de coloan trebuie sa fie unice n cadrul unui tabel dar dou sau mai multe tabele pot avea coloane cu acelai nume, pentru identificarea unei coloane din cadrul mai multor tabele se folosete notaia: tabel.coloana ntr-o instruciune de regsire a datelor n mai multe tabele, putem utiliza i numele de coloan simplu dac nu exist ambiguiti, dac dou sau mai multe tabele nu au coloane cu acest nume. Instruciunea JOIN este folosit n SQL pentru a retrage date din dou sau mai multe tabele pe baza relaiei dintre anumite coloane din aceste tabele. SELECT coloana1, coloana2, ..., coloanan FROM Tabel1 INNER JOIN Tabel2 ON Tabel1.coloana_test = Tabel2.coloana_test ; SELECT au_id, authors.city FROM authors INNER JOIN publishers ON author.city = publishers.city ; va genera: au_id city -------- -----A03 San Francisco A04 San Francisco A05 New York Diferite tipuri de JOIN: JOIN: returneaz rnd atunci cnd exist cel puin o egalitate ntre cmpurile din coloanele de test LEFT JOIN: returneaz toate rndurile din tabelul din stnga chiar dac nu exist nicio asemnare in tabelul din dreapta RIGHT JOIN returneaz toate rndurile din tabelul din dreapta chiar dac nu exist nicio asemnare n tabelul din stnga FULL JOIN: returneaz rnduri cnd exist o asemnare n unul din tabele.

Fie tabelele: Persons P_Id LastName 1 2 Hansen Svendson

FirstName Ola Tove

Address Borgvn23

City Sandnes

Timoteivn10 Sandnes

3 Petterson Kari Storgt20 Stavanger Orders: O_Id OrderNo P_Id P_ID este cheie strin pentru tabelul Orders: 1 77895 3 SELECT Persons.LastName, 2 44678 3 Persons.FirstName, Orders.OrderNo FROM Persons 3 22456 1 INNER JOIN Orders 4 24562 1 ON Persons.P_Id = Orders.P_Id ORDER BY Persons.LastName; 5 34764 15 Va genera un rezultat de genul: LastName FirstName OrderNo -----------------------------------------Hansen Ola 22456 Hansen Ola 24562 Pettersen Kari 77895 Pettersen Kari 44678 OBServaii: 1) Clarificarea numelor de coloane funcioneaz i n cazul interogrilor care implic un singur tabel: SELECT authors.au_fname, authors.au_lname FROM authors; 2) Uneori e nevoie de mai multe elemente de clarificare, uneori e nevoie ca s se includ n clarificatori pe lng numele tabelului i numele serverului, numele bazei de date i numele proprietarului. n Microsoft SQL Server un nume de tabel complet arat astfel: NumeServer.DBname.OwnerName.Tabel 3) Oracle 8i necesit sintaxa WHERE pentru compuneri: SELECT au_id, authors.city FROM authors, publishers WHERE authors.city = publishers.city; Din Oracle 9i a fost introdus i cuvntul cheie JOIN.

Crearea alias-urilor de tabele utiliznd AS Table [AS] Alias SELECT au_fname, a.city SELECT au_fname, a.city FROM authors a FROM authors AS a INNER JOIN publishers p INNER JOIN publishers AS p ON a.city = p.city ; ON a.city = p.city ; Unele SGBD-uri nu accept AS deci e de preferat forma din partea stng.

10.2

Pe larg despre mecanismul compunerilor:


O interogare care retrage date din dou sau mai multe tabele se numete compunere. Caracteristici: * Cei doi operanzi ai compunerii(tabelele surs) sunt denumii de obicei primul tabel i al doilea tabel, dar n compunerile externe, n care ordinea conteaz, aceti operanzi sunt denumii tabelul stng i tabelul drept. * Tabelele sunt "puse unul lng altul" i compuse rnd cu rnd prin satisfacerea(ndeplinirea) condiiei/lor de compunere specificat/e n interogare. * Rndurile care nu corespund pot fi incluse n rezultat sau excluse din rezultat, n funcie de tipul compunerii. * O echicompunere este o condiie de compunere care utilizeaz operatorul "=" pentru combinarea rndurilor cu valori echivalente n coloanele care se compun. * Coloanele care se compun sunt de multe ori coloanele asociate dintr-o cheie, dar se pot compune oricare coloane care au tipuri de date comparabile(excepie fiind compunerile ncruciate care nu necesit coloane specifice de compunere). TIPURI DE COMPUNERI: Compunere ncruciat - Returneaz toate rndurile din primul tabel, fiecare rnd din primul tabel fiind combinat cu toate rndurile din al doilea tabel. Compunere natural - O compunere care compar, pentru egalitate, toate coloanele din primul tabel cu coloanele corespunztoare din al doilea tabel care au acelai nume. Compunere intern - O compunere care utilizeaz un operator de comparaie pentru a compara rndurile din dou tabele pe baza valorilor din coloanele comune din fiecare tabel. Compunerile interne reprezint cel mai obinuit tip de compuneri. Compunere extern stnga - Returneaz toate rndurile din tabelul stng, nu doar pe cele pentru care coloanele de compunere corespund. Dac un rnd din tabelul stng nu are niciun rnd

corespunztor n tabelul drept, rndul asociat al rezultatului conine NULL pentru coloanele din clauza SELECT care provin din tabelul drept. Compunerea extern dreapta - Inversul compunerii externe stnga. Returneaz toate rndurile din tabelul drept. Sunt returnate NULL-uri pentru tabelul stng dac un rnd din tabelul drept nu are niciun rnd corespondent n tabelul stng. Inversul compunerii externe stnga - Returneaz toate rndurile att din tabelul stng ct i din tabelul drept. Dac un rnd dintr-un tabel nu are niciun rnd corespunztor n cellalt tabel, coloanele din clauza SELECT care provin din cellalt tabel conin NULL-uri. Dac exist o coresponden ntre rndurile din cele dou tabele, ntregul rnd al rezultatului conine valori din ambele tabele. Compunerea extern complet - Compunerea tabelului cu al nsui. Reuniunea - Toate rndurile returnate de ambele interogri, duplicatele fiind eliminate. Intersecie - Toate rndurile comune n ambele interogri(mai exact, toate rndurile distincte regsite de ambele interogri) Diferen - Toate rndurile din prima interogare, fiind eliminate din rezultat rndurile care apar n dou interogri i duplicatele. > O condiie de compunere tipic specific o cheie extern dintr-un tabel i cheia primar asociat din celalalt tabel. > Dac cheia este compus putem compune toate coloanele cheii. > Coloanele care se compun nu trebuie s aib acelai nume de coloan(excepie compunerile naturale). > NULL-urile nu particip niciodat la compunere. > Compunerile se pot imbrica pentru a crea compuneri complexe dar SGBD-ul ruleaz interogarea executnd doar compunerea a dou tabele la un moment dat. > SQL nu limiteaz numrul de tabele(sau de compuneri) din cadrul unei compuneri dar SGBD-ul s-ar putea s limiteze acest lucru. > Pentru a crea o compunere putem utiliza att JOIN ct i WHERE dup cum vom putea vedea n continuare.

Operaii cu mulimi:

OBServaii

10.3

Compuneri cu JOIN sau WHERE

Se pot crea compuneri att cu JOIN ct i cu WHERE. ANSI SQL-92 prescrie utilizarea lui JOIN dar standardele anterioare de SQL prescriu utilizarea lui WHERE. SELECT col1, col2, ..., coln SELECT col1, col2, ..., coln FROM Tabel1 TipJOIN Tabel2 FROM Tabel1 , Tabel2 ON conditii_join [WHERE conditii_join] [WHERE conditii_cautare] [GROUP BY coloane_grupare] [GROUP BY coloane_grupare] [HAVING conditii_cautare] [HAVING conditii_cautare] [ORDER BY conditii_sortare] [ORDER BY conditii_sortare] ; TipJOIN: CROSS JOIN, NATURAL JOIN, INNER JOIN, LEFT OUTER JOIIN, RIGHT OUTER JOIN, FULL OUTER JOIN Exemplu de utilizare al ambelor tipuri:
SELECT au_fname, au_laneme, a.city FROM authors a INNER JOIN publishers p ON a.city = p.city ; SELECT au_fname, au_lname, a.city FROM authors a, publishers p WHERE a.city = p.city ;

Rezultatul va fi de tipul: au_fname au_lname -----------------------Hallie Hull Klee Hull Christian Kells

city -----------San Francisco San Francisco New York

COMPUNERI NCRUCIATE CROSS JOIN Returneaz toate combinaiile posibile de rnduri din cele doua tabele. Rezultatul conine toate rndurile din primul tabel, fiecare rnd din primul tabel este combinat cu toate rndurile din al doilea tabel. Se omite clauza ON dac se utilizeaz sintaxa JOIN sau clauza WHERE dat ce utilizeaz sintaxa WHERE. Pentru dou tabele de m respectiv n rnduri se genereaz m x n rezultate motiv pentru care se numete i produs cartezian sau produs ncruciat. SELECT coloane FROM Tabel CROSS JOIN Tabel2 ; SELECT au_id, pub.id, a.state, p.state FROM authors a CROSS JOIN publishers p ; au_id pub_id au_state pub_state --------- ------------------ -----------A01 P01 NY NY A02 P01 CO NY A03 P01 CA NY A01 P02 NY NY ........................................................... <========== Echivalent n sintaxa WHERE cu =========> SELECT au_id, pub_id, a.state, p.state FROM authors, publishers; 10.4 Pentru a gsi toate coloanele din cele dou tabele : SELECT * FROM authors CROSS JOIN publishers; <========== Echivalent n sintaxa WHERE cu =========> SELECT * FROM authors, publishers ; Pentru a regsi toate datele dintr-un tabel SELECT table.* , p.pub_id FROM authors CROSS JOIN publishers ; <===========Echivalent cu ================> SELECT authors.*, p.pub_id FROM authors, publishers p; Produsul cartezian a n tabele: SELECT coloane FROM Tabel1 CROSS JOIN Tabel2 .... CROSS JOIN Tabeln < ======= Echivalent cu n sintaxa Where ======> SELECT coloane FROM Tabel1, Tabel2, ... , TabelN Observaii: Microsoft Access accept compuneri ncruciate numai cu sintaxa WHERE.

JOIN este de preferat fa de WHERE deoarece precizeaz explicit tipul de compunere. Construcia A LEFT OUTER JOIN B este mai clar dect A *= B. Dac tipurile de date nu sunt compatibile se poate utiliza funcia CAST(). Pentru sintaxa JOIN, SQL definete i clauza USING care poate fi utilizat n locul clauzei ON n cazul n care coloanele care se compun au acelai nume i sunt comparate pentru egalitate: FROM Tabel1 TipJoin Tabel2 USING coloane

COMPUNERI NATURALE NATURAL JOIN Este un caz special de echicompunere, este o compunere care compar, pentru egalitate, toate coloanele din primul tabel cu coloanele corespondente din al doilea tabel care au acelai nume. Funcioneaz numai n cazul n care cele dou tabele surs au una sau mai multe perechi de coloane cu nume identice i cu semnificaii comparabile. ntr-o compunere natural nu trebuie specificat clauza ON sau clauza USING. Mai poate fi reprodus utiliznd clauze USING ON sau WHERE. SELECT coloane FROM Tabel1 CROSS JOIN Tabel2 ; NATURAL JOIN creeaz compuneri naturale interne. Ex.1SELECT t.title_id, t.pub_id, p.pub_name FROM publishers p NATURAL JOIN titles t; title_id pub_id pub_name ------------------ -----------T01 P01 Abatis Publishers T02 P03 Schadenfreude Press T03 P02 Core Dump Books ...................................................................... <====== Echivalent cu n clauza WHERE =====> SELECT t.title_id, t.pub_id, p.pub_name FROM publishers, titles ; Ex.2SELECT t.title_id, t.pub_id, p.pub_name, r.advance FROM publishers p NATURAL JOIN titles t NATURAL JOIN royalties r WHERE r.advance < 20000; # listeaz pentru fiecare carte pentru care s-a pltit un avans mai mic de 20000USD, editura care a publicat-o i avansul platit. <========= Echivalent cu n clauza WHERE =======> SELECT t.title_id, t.pub_id, p.pub_name, r.advance FROM publishers p, titles t, royalities r WHERE p.pub_id = t.pub_id AND t.title_id = r.title_id AND R>ADVANCE < 20000 ; Pentru a replica o compunere natural utiliznd sintaxa JOIN pentru compuneri interne sau externe, vom utiliza o echicompunere cu o clauz ON care utilizeaz operatori AND pentru combinarea condiiilor

10.5

de compunere. Fiecare condiie de compunere compar pentru egalitate fiecare pereche de coloane cu acelai nume din tabelul surs. Echiv1: SELECT t.title_id, t.pub_id, p.pub_name FROM publishers p INNER JOIN titles t ON p.pub_id = t.pub_id; Echiv2: SELECT t.title_id, t.pub_id, p.pub_name, r.advance FROM publishers p INNER JOIN titles t ON p.pub_id = t.pub_id; INNER JOIN royalities r ON t.title_id = r.title_id WHERE r.advance < 20000 ; Se poate utiliza clauza JOIN mpreun cu clauza USING, lista using trebuie sa constea tocmai n numele de coloane care apar n ambele tabele: Echiv1: SELECT t.title_id, t.pub_id, p.pub_name FROM publishers p INNER JOIN titles t USING (pub_id); Echiv2: SELECT t.title_id, t.pub_id, p.pub_name, r.advance FROM publishers p INNER JOIN titles t USING (pub_id) INNER JOIN royalities r USING (title_id) WHERE r.advance < 20000 ; Sintaxa NATURAL JOIN creeaz n realitate o compunere intern, NATURAL JOIN este echivalent cu NATURAL INNER JOIN. Se pot crea compuneri naturale externe cu construciile: NATURAL LEFT [OUTER] JOIN NATURAL RIGHT [OUTER] JOIN NATURAL FULL [OUTER] JOIN Pentru a realiza o compunere natural trebuie s ne asigurm c toate coloanele asociate(care pot fi compuse) au nume identice n ambele tabele i toate coloanele neasociate au nume unice. Microsoft Access i Microsoft SQL Server nu accepta sintaxa Natural JOIN dar se poate folosi sintaxa WHERE. n MySQL este necesar clarificarea numelor de coloane ambigue, chiar i n compunerile naturale. n PostgreSQL, clarificarea numelor de coloane ambigue n compunerile naturale este opional.

COMPUNERI INTERNE INNER JOIN Utilizeaz un operator de comparaie(=, <=, >=, <>, >, <) pentru a compara rndurile din cele dou tabele pe baza valorilor din coloanele comune celor dou tabele. Se pot gsi toate rndurile pentru care codul autorului(au_id) este identic n tabelele authors si titles. Returneaz rnduri cnd exist cel puin o brodire ntre ambele(sau mai multele) tabele. SELECT coloana1, coloana2, ..., coloanaN FROM Tabel1 INNER JOIN Tabel2 ON conditii_join ; Pentru crearea unor compuneri ntre 3 sau mai multe tabele: SELECT coloana1, coloana2, ... , coloanaN FROM Tabel1 INNER JOIN Tabel2 ON conditii_join1 INNER JOIN Tabel3 ON conditii_join2 .... <====== Echivalent cu n sintaxa WHERE =======> SELECT coloana1, coloana2, ..., coloanaN FROM Tabel1, Tabel2 WHERE conditii_join1 AND conditii_join2 .... <====== Echivalenta necesara n Microsoft Access pentru compunerile interne ntre 3 sau mai multe tabele ==========> SELECT coloane FROM Tabel1 INNER JOIN (Tabel2 INNER JOIN (Tabel3 INNER JOIN (Tabel4 INNER JOIN .... ) ON Tabel3.coloana3 operator Tabel4.coloana4 ) ON Tabel2.coloana2 operator Tabel3.coloana3 ) ON Tabel1.coloana1 operator Tabel2.coloana2 ) Sintaxa aceasta este permis i de alte SGBD-uri dar este obligatorie n Access.
Ex.1:SELECT a.au_id, a.au_fname, a.au_lname, ta.title_id FROM authors a INNER JOIN title_authors ta ON a.au_id = ta.au_id ORDER BY a.au_id ASC, ta.title_id ASC; au_id au_fname au_lname title_id -------- ------------------------------A01 Sarah Buchman T01 A01 Sarah Buchman T02 A02 Wendy Heydemark T06 A03 Hallie Hull T04 A03 Halie Hull T11 A06 Kellsey T08

10.6

Exemplul precedent compune dou tabele pe baza coloanei au_id pentru a lista crile scrise de fiecare autor(singur sau drept coautor). Codul fiecrui autor(au_id) din tabelul authors corespunde cu zero sau mai multe rnduri din tabelul title_authors. Ex.2:SELECT Person.LastName, Person.FirstName, Orders.OrderNo FROM Persons INNER JOIN Orders ON Persons.P_Id = Orders.P_Id ORDER BY Persons.LastName ; LastName FirstName OrderNo

-------------------------------------Hansen Ola 22456 Hansen Ola 24562 Petterson Kari 77895


INNER JOIN returneaz rnduri atunci cnd exist cel puin o brodire n ambele tabele, dac exist rnduri n Persons care nu au rnd corespondent n rndul Orders, acel rnd nu va fi afiat. Ex.3:SELECT a.au_id, a.au_fname, a.au_lname, a.city, a.state FROM authors a INNER JOIN publishers p ON a.city = p.city AND a.state = p.state ORDER BY a.au_id ASC ; #listeaz autorii care locuiesc n acelai ora i stat n care se afl o editur(oricare editur). Ex.4:SELECT t.title_id, t.title_name, p.state, p.country FROM titles t INNER JOIN publishers p ON t.pub_id = p.pub_id WHERE p.state = 'CA' OR p.country NOT IN ('USA', 'Canada', 'Mexico') ORDER BY t.title_id ASC ; #listeaz crile publicate n California sa n afara Americii de Nord. Ex.5:SELECT a.au_id, COUNT(ta.title_id) FROM author a INNER JOIN title_authors ta ON a.au_id = ta.au_id GROUP BY a.au_id ORDER BY a.au_id ASC; # listeaz numrul crilor scrise de fiecare autor(singur sau drept coautor) Ex.6:SELECT t.title_id, t.title_name, r.advance FROM royalities r INNER JOIN titles t ON r.title_id = t.title_id WHERE t.tipe = 'biography' AND r.advance IS NOT NULL ORDER BY r.advance DESC; #listeaz avansul platit pentru fiecare carte de biografie

Ex.7:SELECT t.type, COUNT(r.advance), SUM(r.advance) FROM royalities r INNER JOIN titles t ON r.title_id = t.title_id WHERE r.advance IS NOT NULL GROUP BY t.type ORDER BY t.type ASC ; #listeaz numrul i totalul avansurilor pltite pentru fiecare tip de carte. Ex.8:SELECT ta.title_id, COUNT(ta.au_id) FROM authors a INNER JOIN title_authors ta ON a.au_id = ta.au_id GROUP BY ta.title_id HAVING COUNT(ta.au_id) > 1 ORDER BY ta.title_id ASC ;#listeaz numrul de coautori ai fiecrei cri scrise de doi sau mai multi autori. Ex.9:SELECT t.title_id, t.title_name, t.advance, t.price *t.sales FROM titles t INNER JOIN royalities r ON t.price * t.sales > r.advance * 10 AND t.titles_t = r.title_id ORDER BY t.price * t.sales DESC ; #listeaz fiecare carte pentru care ncasrile, calculate ca produs dintre price i sales sunt de cel puin 10 ori mai mari dect avansul pltit. Ex.10:SELECT a.au_fname, a.au_lname, t.title_name, p.pub_name FROM authors a INNER JOIN title_authors ta ON a.au_id = ta.au_id INNER JOIN titles t ON t.title_id = ta.title_id INNER JOIN publishers p ON p.pub_id = t.pub_id ORDER BY a.au_lname ASC, a.au_fname ASC, t.title_name ASC; #listeaz numele autorilor, numele carilor scrise de fiecare(singur sau drept coautor) i numele editorulor. Ex.11:SELECT ta.au_id, COUNT(sales), SUM(t.sales*t.price* r.royalty_rate*ta.royalty_share), SUM(r.advance*ta.royalty_share), SUM((t.sales*t.price*r.royalty_rate*ta.royalty_share) - (r.advance* ta.royalty_share)) FROM title_author ta INNER JOIN titles t ON t.title_id = ta.title_id INNER JOIN royalties r ON r.title_id = t.title_id WHERE t.sales IS NOT NULL GROUP BY ta.au_id ORDER BY ta.au_id ASC ; #calculeaz totalul drepturilor de autor ctigate de fiecare autor pentru fiecare carte pe care autorul a scris-o(singur sau drept coautor)

COMPUNERI EXTERNE OUTER JOIN Compunerile interne returneaz rnduri doar dac cel putin un rnd din ambele tabele satisface condiia de compunere, ele elimin rndurile dintr-un tabel care nu corespund cu un rnd din cellalt tabel. Compunerile externe returneaz toate rndurile din cel puin unul dintre tabele(cu condiia ca rndurile respective s satisfac una din condiiile de cutare specificate prin clauzele WHERE sau HAVING). Se utilizeaz pentru a rspunde la ntrebri n care sunt implicate cantiti lips: autori care nu au scris nicio carte, clase n care nu s-a nscris niciun elev. Spre deosebire de alte compuneri, n cazul compunerilor externe, ordinea n care se specific tabelele este important iar cei doi operanzi ai compunerii sunt denumii tabelul stng i tabelul drept. Compunerea extern stnga Rezultatul include toate rndurile din tabelul stng specificate n clauza LEFT OUTER JOIN, nu numai rndurile pentru care valorile din coloanele care se compun sunt identice. Dac un rnd din tabelul stng nu are niciun rnd corespondent n tabelul drept, rndul asociat din rezultat conine NULL-uri pentru toate coloanele din lista SELECT care provin din tabelul drept. Compunerea extern dreapta Sunt returnate toate rndurile din tabelul drept. Dac un rnd din tabelul drept nu are niciun rnd corespondent n tabelul stng, rndul asociat din rezultat contine NULuri pentru toate coloanele din lista SELECT care provin din tabelul stng. Compunerea extern complet Returneaz toate rndurile, att din tabelul stng ct i din tabelul drept. Dac un rnd dintr-un tabel nu are nici un rnd corespondent n cellalt tabel, rndul asociat din rezultat conine NULL-uri pentru toate coloanele din lista SELECT care provine din cellalt tabel. Dac exist o corespondent ntre tabele, ntregul rnd din rezultat conine valorile datelor din ambele tabele. ntr-o compunere extern stnga sunt regsite toate rndurile din tabelul stng, ntr-o compunere extern dreapta sunt regsite toate rndurile din tabelul drept iar ntr-o compunere extern complet sunt regsite toate rndurile, att din tabelul stng ct i din tabelul drept.

10.7

COMPUNEREA EXTERN STNGA: SELECT coloana1, coloana2, ... , coloanaN FROM TabelStanga LEFT [OUTER] JOIN TaberlDreapta ON ConditiiJoin ; Dac TabelStnga i Tabel Dreapta au nume de coloane identice, ele trebuie clarificate SELECT Person.LastName, Person.FirstName, Orders.OrderNo FROM Persons LEFT JOIN Orders ON Persons.P_Id = Oerders.P_Id ORDER BY Persons.LastName ;
LastName Hansen Pettersen Pettersen Svendson FirstName Ola Kari Kari Tove OrderNo 22456 77895 44678

COMPUNEREA EXTERN DREAPTA: SELECT coloana1, coloana2, ... , coloanaN FROM TabelStanga RIGHT [OUTER] JOIN TabelDreapta ON ConditiiJoin ; SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons RIGHT JOIN Orders ON Persons.P_Id = Orders.P_Id ORDER BY Persons.LastName ;
LastName Hansen Pettersen Pettersen FirstName Ola Kari Kari OrderNo 22456 77895 44678 34764

Ex.1:SELECT a.au_fname, a.au_lname, p.pub_name FROM authors a LEFT OUTER JOIN publishers p ON a.city = p.city ORDER BY p.pub_name ASC, a.au_lname ASC, a.au_fname ; # include n rezultat toate rndurile din tabelul authors indiferent dac n publishers exist sau nu o coresponden n coloana city au_fname au_lname pub_name Sarah Buchman NULL Wendy Heydemark NULL Kellsey NULL Christian Kells Abatis Publishers Ex.2:SELECT a.au_id, .au_fname, a.au_lname FROM authors a LEFT OUTER JOIN title_authors ta ON a.au_id = ta.au_id WHERE ta.au_id IS NULL ; #listeaz autorii care nu au scris (individual sau drept coautor) nicio carte au_id au_fname au_lname A07 Paddy O'Furniture Ex.3:SELECT a.au_id, COUNT(ta.title_id), FROM authors a LEFT OUTER JOIN title_authors ta ON a.au_id = ta.au_id GROUP BY a.au_id ORDER BY a.au_id ASC ; #listeaz numrul de cri pe care lea scris fiecare autor(singur sau drept coautor) inclusiv pentru autorii care nu au scris nicio carte.

Ex.1:SELECT a.au_fname, a.au_lname, p.pub_name FROM authors a RIGHT OUTER JOIN publishers p ON a.city = p.city ORDER BY p.pub_name ASC, a.au_laname ASC, a.au_fname ; #include n rezultat toate rndurile din tabelul publishers indiferent dac n tabelul authors exist sau nu o coresponden n coloana city
au_fnameau_lname pub_name Christian Kells Abatis Publishers Hallie Hull Core Dump Books NULL NULL Schadenfreude Press NULL NULL Tenterhooks Press < ====== Echivalent n Microsoft SQL Server ====> SELECT a.au_fname, a.au_lname, p.pub_name FROM authors a, publishers p WHERE a.city =* p.city ORDER BY p.pub_name ASC, a.au_lname ASC, au_fname ; <======== Echivalent n Oracle 8i ============> SELECT a.au_fname, a.au_lname, p.pub_name FROM authors a, publishers p WHERE a.city (+) = p.city ORDER BY p.pub_name ASC, a.au_lname ASC, a.au_fname ;

-------------------------------------------Microsoft SQL Server: LEFT JOIN: ... WHERE TabelSt.col *= TabelDr.col ... RIGHT JOIN: ... WHERE TabelSt.col =* TabelDr.col ... Oracle 8i: LEFT JOIN: ... WHERE TabelSt.col = TabelDr.col (+)... RIGHT JOIN: ... WHERE TabelSt.col (+)= TabelDr.col ...

COMPUNEREA COMPLET SELECT coloana1, coloana2, ... , coloanaN FROM TabelStanga FULL [OUTER] JOIN TabelDreapta ON ConditiiJoin ; Dac: Persons:
P_Id LastName FirstName Address 1 2 3 O_Id 1 2 3 4 5 Hansen Svendson Petterson Ola Tove Kari OrderNo 77895 44678 22456 24562 34764 Timoteivn 10 Borgvn 23 Storgt 20 P_Id 3 3 1 1 15 City Sandnes Sandnes Stavanger

10.8 AUTOCOMPUNERI O autocompunere este o compunere SQL normal care compune un tabel cu el nsui i regsete rndurile dintr-un tabel prin compararea valorilor dintr-una sau mai multe coloane ale aceluiai tabel. SELECT coloana1, coloana2, ... , coloanaN FROM Tabel [AS] alias INNER JOIN Tabel [AS] alias ON ConditiiJoin ; Presupunem tabelul Employees:
emp_id emp_name E01 E02 E03 E04 E05 Lord Copper Jocelyn Hitchcoc Mr. Salter William Boot Mr. Corker boss_id NULL E01 E01 E03 E03 SELECT e1.emp_name AS 'Employee name', e2.emp_name AS'Boss name' FROM Employees INNER JOIN Employees e2 ON e1.boss_id = e2.emp_id;

Orders:

Echivalent n WHERE:

SELECT Persons.LastName, Persons.FirstName, OrderNo FROM Persons FULL JOIN Orders ON Persons.P_Id = Orders.P_Id ORDER BY Persons.LastName ;
LastName Hansen Hansen Pettersen Pettersen Svendson FirstName Ola Ola Kari Kari Tove OrderNo 22456 24562 77895 44678

34764 n limbajul SQL nu exist sintaxa WHERE standardizat pentru compunerile externe. Operaia de compunere extern NU este comutativ,trebuie s avem grij la specificarea tabelelor stng i drept. Ex.1:SELECT a.au_fname, a.au_lname, p.pub_name FROM authors a FULL OUTER JOIN publishers p ON a.city = p.city ORDER BY p.pub_name ASC, a.au_lname ASC, a.au_fname ; #include n rezultat toate rndurile din tabelele authors i publishers indiferent dac exist sau nu o egalitate de valori n coloanele city.

Rezultatul va fi: Employee name Boss name SELECT Jacelyn Hitchcock Lord Copper e1.emp_name AS 'Employee name', Mr. Salter Lord Copper e2.emp_name AS 'Boss name' William Boot Mr. Salter FROM Employees Mr. Corker Mr. Salter WHERE e1.boss_id = e2.emp_id; 10.9 Combinarea rndurilor cu UNION UNION, INTERSECT i EXCEPT sunt operatori care combin rezultatele a dou instruciuni SELECT ntr-un singur rezultat. UNION combin rezultatele a dou interogri ntr-un singur rezultat care cuprinde rndurile rezultate din ambele interogri. Union simplu elimin din rezultat rndurile duplicate, UNION ALL nu elimin din rezultat rndurile duplicate. Restricii: 1) Listele din clauzele SELECT trebuie s aib acelai nr de coloane. 2) Coloanele corespondente trebuie s aib acelai tip de date. 3) Coloanele corespondente trebuie listate n aceeai ordine. SELECT state FROM authors UNION SELECT state FROM publishers; # listeaz statele pentru toi autorii i toate editurile, n mod implicit UNION elimin din rezultat rndurile duplicate, UNION ALL nu va face acest lucru si .
state NULL deci vor putea aprea n lista mai multe coloane NULL, CA,.. CA CO FL

NY

10.10

Cutarea rndurilor comune cu INTERSECT

11

SUBINTEROGRI

INTERSECT combin rezultatele a dou interogri ntr-un singur rezultat care cuprinde rndurile comune ambelor interogri. Se impun aceleai restricii ca i la union SELECT city FROM autors INTERSECT SELECT city FROM publishers ; #listeaz oraele n care locuiete un autor I n care se afl i o editur-Rezultatul va fi de genul: city New York San Francisco OBServaii: 1) INTERSECT este comutativ 2) INTERSECT poate fi vzut ca un operator AND 3) UNION poate fi vzut ca un operator OR 4) EXCEPT poate fi vzut ca o operaie de diferen 10.11 Cutarea rndurilor diferite utiliznd EXCEPT

Interogrile de pn acum au utilizat o singur instruciune SELECT. Acum vor fi studiate interogrile imbricate care permit regsirea sau modificarea datelor pe baza rezultatului unei alte interogri. O nou interogare SELECT poate fi plasat n: * n clauz SELECT, n clauza FROM, n clauza WHERE sau n clauza HAVING a unei alte instruciuni SQL; * ntr-o alt subinterogare; * ntr-o instruciune INSERT, UPDATE sau DELETE; Exemplu de problem: Listarea editurilor care public i cri de bibliografie. utilizarea a dou interogri: SELECT pub_id FROM titles pub_id P01 WHERE type = 'biography'; SELECT pub_name FROM publishers WHERE pub_id IN('P01', 'P03');
P03 P01 P01

EXCEPT denumit i diferen, combin rezultatele a dou interogri ntr-un singur rezultat care cuprinde rndurile ce aparin numai primei interogri. A EXCEPT B conine rndurile din tabelul A care nu sunt duplicate n tabelul B. EXCEPT se supune acelorai restricii ca i UNION i NU este comutativ. SELECT city FROM authors EXCEPT SELECT city FROM publishers ; #listeaz oraele n care locuiete un autor i n care nu se afl o editur Rezultatul este de genul: city: Boulder Bronx Palo Alto Saraota

pub_name Abatis Publishers Schadenfreude Press utilizarea unei compuneri interioare: SELECT DISTINCT pub_name FROM publishers p INNER JOIN titles t ON p.pub_id = t.pub_id WHERE t.type = 'biography' ; utilizarea uneisubinterogri SELECT pub_name FROM publishers WHERE pub_id IN ( SELECT pub_id FROM titles WHERE type = 'biography' ; ); Rezultatul ultimelor dou interogri: pub_name Abatis Publishers Schadenfreude Press OBServaii: MySQL 4.0 i versiunile anterioare NU accept subinterogri, codul urmtor trebuie rescris ca INNER JOIN, se mai poate utiliza crearea unui tabel temporar pentru a stoca rezultatul subinterogrii sau se poate utiliza un OUTER JOIN sau se poate simula subinterogarea n limbajul gazd de tip procedural Perl, PHP, Java care e utilizat pentru crearea aplicaiei cu baze de date.

> O subinterogare trebuie neaprat inclus n paranteze () ; > Nu trebuie inclus o clauz ORDER BY ntr-o interogare deoarece o subinterogare returneaz un rezultat care nu este niciodat vizualizat aa c nu are sens ordonarea lui; > O subinterogare conine o singur instruciune SELECT, NU se pot utiliza uniuni de instruciuni SELECT ; > O subinterogare poate utiliza coloanele din tabelele listate n propria clauz FROM sau n clauza FROM a interogrii exterioare; > SQL nu prevede un numr maxim de interogri imbricate dar SGBD-ul utilizat s-ar putea s limiteze acest numr, Microsoft SQL limiteaz numrul de imbricri la 32. 11.1 Comparaie ntre subinterogri i compuneri SELECT * FROM Tabel1 WHERE id IN (SELECT id FROM Tabel2) ; < ========= Echivalent cu =========== > SELECT Tabel1.* FROM Tabel1 INNER JOIN Tabel2 ON Tabel1.id = Tabel2.id ; Exemple: SELECT au_id, city FROM authors WHERE city IN (SELECT city FROM publichers) ; < ========= Echivalent cu =========== > SELECT a.au_id, a.city FROM authors a INNER JOIN publishers p ON a.city = p.city; #listeaz autorii care locuiesc n acelai ora n care are sediul o editur. au_id city A03 San Francisco A04 San Francisco A05 New York SELECT * FROM Table1 WHERE id NOT IN(SELECT id FROM Table2) ; <========== Echivalent cu ==========> SELECT * FROM Table1 WHERE NOT EXISTS(SELECT * FROM Table2 WHERE Table1.id = Table2.id ); <========== Echivalent cu ==========> SELECT Table1.* FROM Table1 LEFT OUTER JOIN Table2 ON Table1.id = Table2.id WHERE Table2.id IS NOT NULL; Exemple:

SELECT au_id, au_fname, au_lname FROM authors WHERE au_id NOT IN (SELECT au_id FROM title_authors); < ========== Echivalent cu ========== > SELECT au_id, au_fname, au_lname FROM authors a WHERE NOT EXISTS (SELECT * FROM titles_authors ta WHERE a.au_id = ta.au_id) ; < ========== Echivalent cu ========== > SELECT a.au_id, a.au_fname, a.au_lname FROM autors a LEFT OUTER JOIN title_authors ON a.au_id = ta.au_id WHERE ta.au_id IS NOT NULL; #listeaz autorii care nu au scris nici o carte(nici singur nici drept coautori) - din cele care se afl n baza de date au_fname au_lname Paddy O'Furniture Alt exemplu: SELECT au_id, au_fname, au_lname, state FROM authors WHERE state IN (SELECT state FROM authors WHERE au_id = 'A04') ; listeaz autorii care locuiesc n acelai stat ca i autorul cu codul A04. <======= Echivalent cu ======= > SELECT a1.au_id, a1.au_fname, a1.au_lname, a1.state FROM authors a1 INNER JOIN authors a2 ON a1.state = a2.state WHERE a2.au_id = 'A04' ; au_id au_fname au_lname state A03 Hallie Hull CA A04 Klee Hull Ca A06 Kellsey CA OBServaii: 1) O autocompunere poate fi reformulat ca i subinterogare. 2) O compunere intern poate fi reformulat ntotdeauna ca subinterogare dar nu i viceversa deoarece compunerile interne sunt asociative pe cnd subinterogrile nu au aceast proprietate. Alt exemplu: SELECT title_id, price FROM titles WHERE price = (SELECT MAX(price) FROM titles ) ; #listeaz toate crile al cror pre este egal cu preul celei mai scumpe cr i SELECT a.au_id, a.city, p.pub_id FROM authors a INNER JOIN publishers p ON a.city = p.city ; #listeaz autorii care locuiesc n acelai ora n care are sediul o editur i include n rezultat i numele editurii au_id A07

11.2

Subinterogri simple si corelate

O subinterogare simpl (necorelat) poate fi evaluat independent de interogarea sa exterioar i este procesat o singur dat pentru ntreaga instruciune. SELECT au_id, city FROM authors WHERE city IN (SELECT city FROM publishers) ; O subinterogare corelat nu poate fi evaluat independent de interogarea sa exterioar; este o interogare interioar care depinde de datele din interogarea sa exterioar. Se utilizeaz n situaiile n care o instruciune trebuie s proceseze un tabel n interogarea interioar pentru fiecare rnd din interogarea exterioar. SELECT outer_columns FROM outer_table WHERE outer_columns_value IN ( SELECT inner_column FROM inner_table WHERE inner_column = outer_column ) ; Exemplu de interogare corelat: SELECT candidate.title_id, candidate.type, candidate.sales FROM titles candidate WHERE sales >= (SALES AVG(sales) FROM titles average WHERE average.type = candidate.type); #listeaz crile care au cifre de vnzri mai bune dect media vnzrilor pentru crile de tipul respectiv. Variabila candidate.type definete condiiile iniiale care trebuie ndeplinite de rndurile tabelului average din interogarea interioar. Conditia WHERE exterioar(sales>=) definete condiia final care trebuie ndeplinit de rndurile tabelului average din interogarea interioar title_id type sales T02 history 9566 T03 computer 25667 T05 psyhology 201440 T07 biography 1500200 T09 children 5000 T13 history 10467

Ex.2:SELECT au_id, au_fname, au_lname FROM authors WHERE au_id IN (SELECT au_id FROM title_authors WHERE royalty_share = 1.0); #este o subinterogare simpl care listeaz autorii care ctig 100% din drepturile de autor pentru o carte. < ======= Echivalent cu ====== > SELECT au_id, au_fname, au_lname FROM authors WHERE 1.0 IN (SELECT royalty_share FROM title_authors WHERE title_authors.au_id = authors.au_id); #este o subinterogare corelat echivalent cu exemplul de mai sus au_id au_fname au_lname A01 Sarah Buchman A02 Wendy Heydemark A04 Klee Hull A05 Christian Kells A06 Lellsey Ex.3:SELECT pub_name FROM publishers WHERE pub_id IN (SELECT pub_id FROM titles WHERE type = 'biography'); #Tabelele publishers i titles conin fiecare o coloan cu numele pub_id dar nu suntem obligai s clarificm numele pub_id n aceast interogare datorit presupunerilor implicite referitoare la tabele pe care le efectueaz SQL. < ========= Echivalent cu ======== > SELECT pub_name FROM publishers WHERE publishers. pub_id IN ( SELECT titles.pub_id FROM titles WHERE type = 'biography' ) ; # introgarea este echivalent cu precedenta dar se utilizeaz clarificatori explicii pentru numele pub_id. Rezultat: pub_name Abatis Publishers Schadenfreude Press

11.3 Null-urile n subinterogri NU trebuie eliminate null-urile din cutrile prin subinterogri, sar putea genera rezultate eronate. 11.4 Utilizarea subinterogrilor ca expresii coloan Ex.1:SELECT title_id, price, (SELECT AVG(price) FROM titles), price - (SELECT AVG(price) FROM titles) AS 'Diference' FROM titles WHERE type = 'biography'; Rezultat: title_id price AVG(price) Difference T06 19.95 18.3875 1.5625 T07 23.95 18.3875 5,5625 T10 NULL 18,3875 NULL T12 12,99 18,3875 -5,3975 Ex.2:SELECT title_id, (SELECT au_id FROM title_author ta WHERE au_order=1 AND title_id=t.title_id) AS 'Author 1', (SELECT au_id FROM title_authors ta WHERE au_order=2 AND title_id=t.title_id) AS 'Author 2', (SELECT au_id FROM title_authors ta WHERE au_order=3 AND title_id=t.title_id) AS 'Author 3' FROM titles t; #listeaz toi autorii fiecrei cri pe cte un singur rnd pentru fiecare carte Rezultat: title_id Author 1 Author 2 Author 3 T01 A01 NULL NULL T02 A01 NULL NULL T03 A05 NULL NULL T04 A03 A04 NULL ....................................................................... Ex.3:SELECT au_id, (SELECT MAX(pubdate) FROM titles t INNER JOIN title_authors ta ON ta.title_id = t.title_id WHERE ta.au_id = a.au_id) AS "Latest pubdate" FROM authors a; #listeaz fiecare autor i data cea mai recent la care a fost publicat o carte scris de autorul respectiv au_id Latest pub date A01 2000-08-01 A02 2000-08-31 .............................................

Compararea valorii returnate de o subinterogare utiliznd un operator de comparaie Putem utiliza operatorii >, <, <=, >=, <>, = pentru a filtra informaiile n clauza WHERE a unei subintrogri. Ex.1:SELECT au_id, au_fname, au_lname, state FROM authors WHERE state = (SELECT state FROM publishers WHERE pub_name = 'Tenterhooks Press'); #listeaz autorii care locuiesc n statul n care are sediul editura Tenterhooks Press Ex.2:SELECT title_id, sales FROM titles WHERE sales > (SELECT AVG(sales) FROM titles); #listeaz crile care au cifre de vnzri peste valoarea medie a vnzrilor Ex.3:SELECT ta.au_id, ta.title_id FROM titles t INNER JOIN title_authors ta ON ta.title_id=t.title_id WHERE sales > (SELECT AVG(sales) FROM titles) ORDER BY ta.au_id ASC, ta.title_id ASC; #listeaz autorii care au cifre de vnzri peste valoarea medie a vnzrilor, utiliznd o compunere i o interogare Rezultat: au_id title_id A02 T07 A04 T05 A04 T07 < ======== Echivalent cu ========= > SELECT au_id, title_id FROM title_authors ta WHERE (SELECT AVG(sales) FROM titles t WHERE ta.title_id=t.title_id) > (SELECT AVG(sales) FROM titles) ORDER BY au_id ASC, title_id ASC; Ex.4:SELECT title_id, price FROM titles WHERE price > ( SELECT MAX(price) FROM titles GROUP BY type HAVING type = 'biography'); #listeaz crile care au preul mai mare dect preul celei mai scumpe biografii. Ex.5:SELECT pub_id, AVG(sales) AS 'AVG(sales)' FROM titles GROUP BY pub_id HAVING AVG(sales) > (SELECT AVG(sales) FROM titles); listeaz editurile ale cror medii de vnzri sunt mai mari dect mediile globale ale vnzrilor

11.5

11.6

Testarea apartenenei la o mulime

IN

IN acioneaz la fel asupra valorilor din rezultatul unei subinterogri ca i asupra valorilor dintr-o list cuprinsa ntre paranteze. Subinterogarea asupra creia acioneaza IN trebuie s returneze o singur coloan. Se poate utiliza i NOT IN pentru a inversa efectul testului IN. Ex.1:SELECT pub_name FROM publishers WHERE pub_id IN ( SELECT pub_id FROM titles WHERE type = 'biography'); #listeaz numele editurilor care au publicat biografii Rezultat pub_name Abatis Publishers Schadenfreude Press Ex.2:SELECT pub_name FROM publishers WHERE pub_id NOT IN (SELECT pub_id FROM titles WHERE type='biography'); #listeaz numele editurilor care nu au publicat biografii. Ex.3:SELECT DISTINCT a.au_id, au_fname, au_lname FROM title_authors ta INNER JOIN authors a ON ta.au_id = a.au_id WHERE title_id IN (SELECT title_id FROM titles WHERE pub_id = 'P03');
#listeaz numele autorilor care au publicat o carte la editura cu codul P03

EX.4:SELECT DISTINCT a.au_id, au_fname, au_lname FROM authors a INNER JOIN title_authors ta ON a.au_id = ta.au_id WHERE ta.royalty_share < 1.0 AND a.au_id IN ( SELECT a.au_id FROM authors a INNER JOIN title_authors ta ON a.au_id = ta.au_id AND ta.royalty_share = 1.0); #listeaz numele autorilor care au scris cri att singuri ct i n calitate de coautori. Ex.5:SELECT DISTINCT t1.type FROM titles t1 WHERE t1.type IN ( SELECT t2.type FROM titles t2 WHERE t1.pub_id <> t2.pub_id; #listeaz tipurile de cri publicate de mai mult de o singur editur

Compararea tuturor valorilor returnate de o subinterogare utiliznd ALL Putem utiliza ALL pentru a determina dac o valoare este mai mic sau mai mare dect toate valorile din rezultatul unei subinterogri. 1) ALL modific un operator de comparaie dintr-un test de comparaie pentru rezultatul unei subinterogri i este plasat dup =, <>, <,>,<=,>=. 2) Combinaia dintr un operator de comparaie i ALL indic SGBD-ului modul n care trebuie s aplice testul de comparaie valorile returnate de subinterogare, < ALL ... indic mai mic ca fiecare din valorile returnate de subinterogare. 3) ALL pus dup <, >, <=, >= este echivalent cu cea mai mic sau cea mai mare valoare returnat de subinterogare Ex.1:SELECT au_id, au_lname, au_fname, city FROM authors WHERE city <> ALL ( SELECT city FROM publishers ); #listeaz autorii care locuiesc n acelai ora n care are sediul o editur au_id au_lname au_fname city A01 Buchman Sarah Bronx A02 Heydemark Wendy Boulder A06 Kellsey Palo Alto A07 O'Furniture Paddy Sarasota Ex.2:SELECT title_id, title_name FROM titles WHERE type <> 'biography' AND price < ALL ( SELECT price FROM titles WHERE type = 'biography' AND price IS NOT NULL ); #listeaz crile non-biografice care au preul mai mic dect toate biografiile. Ex.3:SELECT title_id, title_name FROM titles WHERE sales > ALL ( SELECT sales FROM title_authors ta INNER JOIN titles t ON t.title_id = ta.title_id WHERE ta.au_id = 'A06' AND sales IS NOT NULL); #listeaz crile care au avut cifre de vnzri mai mari dect crile scrise de autori cu codul A06 Ex.4:SELECT t1.type FROM titles t1 GROUP BY t1.type HAVING MAX(t1.sales) >= ALL (SELECT 2.0 * AVG(t2.sales) FROM titles t2 WHERE t1.type = t2.type ); #listeaza tipurile de cri pentru care cea mai mare cifr de vnzare e mai mare dect dublul mediei vnzrilor pentru tipul respectiv de cri.

11.7

11.8

Compararea unora dintre valorile returnate de o subinterogare utiliznd ANY

11.9

ANY acioneaz similar cuvntului cheie ALL doar c determin dac o valoare este egal cu, mai mic dect sau mai mare dect oricare(cel puin una) dintre valorile rezultate din subinterogare. 1) ANY modific un operator de comparaie dintr-un test de comparaie pentru rezultatul unei subinterogri i este plasat dup =, <, >, <=, >=, <>. 2) < ANY ... nseamn mai mic dect cel puin o valoare din rezultatul subinterogrii, > ANY nseamn mai mare dect cel puin o valoare din rezultatul interogrii. 3) Cnd este utilizat mpreun cu <,<=,>,>= comparaia este echivalent cu evaluarea valorii maxime sau minime a rezultatului interogrii, < ANY nseamn mai mic dect cel puin o valoare din rezultatul subinterogrii, mai mic dect valoarea maxim. > ANY nseamn mai mare dect cel puin o valoare din rezultatul subinterogrii 4) = ANY < === Echivalent cu ====> IN Ex.1:SELECT au_id, au_lname, au_fname, city FROM authors WHERE city = ANY (SELECT city FROM publishers); #listeaz autorii care locuiesc n acelai ora n care are sediul o editur au_id au_lname au_fname city A03 Hull Hallie San Francisco A04 Hull Klee San Francisco A05 Kells Christian New York Ex.2:SELECT title_id, title_name FROM titles WHERE type <> 'biography' AND price < ANY ( SELECT price FROM titles WHERE type = 'biography'); #listeaz crile non-biografice care au preul mai mic dect cel puin o biografie. Ex.3:SELECT title_id, title_name FROM titles WHERE sales > ANY ( SELECT sales FROM title_authors ta INNER JOIN titles t ON t.title_id = ta.title_id WHERE ta.au_id = 'A06'); #listeaz crile care au avut cifre de vnzri mai mari dect cel puin una din crile scrise de autorul cu codul A06

EXISTS i NOT EXISTS testeaz existena sau inexistena rndurilor n rezultatul unei subinterogri. Ele nu compar valori i deci nu sunt preceda i de o expresie de test. Dac subinterogarea nu returneaz niciun rnd testul EXISTS este evaluat ca fals iar NOT EXISTS este evaluat ca adevrat. Ex.1:SELECT pub_name FROM publishers p WHERE EXISTS (SELECT * FROM titles t WHERE t.pub_id = p.pub_id AND type = 'biography'); #listeaz numele editurilor care au publicat biografii Ex.2:SELECT au_id, au_fname, au_lname FROM authors a WHERE NOT EXISTS ( SELECT * FROM title_authors ta WHERE ta.au_id=a.au_id); #listeaz autorii care nu au scris nicio carte, nici n calitate de coautori.

Testarea existenei utiliznd EXISTS

11.10 Compararea interogrilor echivalente Urmtoarele interogri sunt echivalente, ele listeaz toi autorii care au scris (singuri sau drept coautori) cel puin o carte SELECT DISTINCT a.au_id FROM authors a INNER JOIN title_authors ta ON a.au_id = ta.au_id; SELECT DISTINCT a.au_id FROM authors a, title_autors ta WHERE a.au_id = ta.au_id; SELECT au_id FROM authors WHERE au_id IN (SELECT au_id FROM title_authors); SELECT au_id FROM authors a WHERE au_id = ANY (SELECT au_id FROM title_authors); SELECT au_id FROM authors a WHERE EXISTS ( SELECT * FROM title_authors ta WHERE a.au_id = ta.au_id ); SELECT au_id FROM authors a WHERE 0 < ( SELECT COUNT(*) FROM title_authors ra WHERE a.au_id = ta.au_id au_id A01 A02 A03

12.

Rndurile unui tabel sunt stocate n mod dezordonat conform modelului relaional. Aceast lips de organizare permite SGBD-urilor s efectueze rapid operaii de tipul INSERT, UPDATE, DELETE dar cutrile i sortrile au de suferit n sensul c vor fi ncetinite. Pentru mrirea vitezei de cutare i sortare SGBD-urile pun la dispoziie mecanismele de tip INDEX. Indexul este o list sortat n care fiecare valoare distinct dintr-o coloan indexat este stocat mpreun cu adresa sa de pe disc(HDD). Astfel SGBD-ul va citi numai indexul pentru a regsi adresele n vederea accesului direct la date. 12.1 Crearea unui index utiliznd CREATE INDEX Utilizarea indecilor este adecvat pentru coloanele: 1) utilizate frecvent ; 2) utilizate frecvent drept coloane de sortare ; 3) utilizate cu regularitate n cadrul compunerilor ; Indecii sunt inadecvai pentru coloanele care: 1) conin numai cteva valori distincte(sex, jude); 2) sunt utilizate rar n interogri; 3) fac parte dint-un tabel mic cu numai cteva rnduri. OBServaii: 1) Operaiile de indexare modific obiectele din baza de date i deci s-ar putea s avem nevoie de prioriti de super-user. 2) Indexul nu modific datele, el doar permite accesarea mai rapid a datelor. 3)Nu trebuie creai mai muli indeci dect e nevoie, se vor crea indeci doar pentru coloanele de care e nevoie frecvent. 4) Dup crearea unui index, SGBD-ul l va ntreine i-l va actualiza automat iar utilizarea lor este transparent pentru utilizator, nu impune folosirea unor instruciuni anume pentru utilizarea lor. 5) Un index poate referi mai multe coloane dintr-un tabel, index simplu - refer o singur coloan dintr-un tabel, un index compus refer mai multe coloane dintr-un tabel. 6) Index unic - impune ca valorile din coloana(coloanele) care intr n compunerea indexului s fie distincte. 7) SGBD-ul creeaz automat indeci unici cnd definim o cheie primar sau o restricie unic. 8) SGBD-ul n general nu creaz indeci pentru chile externe dar ar fi de dorit s crem aa ceva pentru c majoritatea compunerilor implic folosirea cheilor externe. 9) n Oracle i PostgreSQL numele indecilor trebuie s fie unice.

INDECII

Crearea unui index: CREATE [UNIQUE] INDEX index ON Tabel ( coloana1, coloana2, ..., coloanaN ) ; Ex.1:CREATE INDEX pub_id_idx ON titles (pub_id); #creaz un index simplu pentru coloana pub_id Ex.2:CREATE UNIQUE INDEX title_name_idx ON titles (title_name); #creeaz un index simplu unic pentru coloana title_name Ex.3:SELECT INDEX state_city_idx ON authors(state, city); #creeaz un index pentru coloana state i city din tabelul authors

10) Indecii sunt fiiere stocate pe disc i ocupa spa iu, uneori chiar mult, dar utilizate n mod corespunztor pot reduce uzura discului scurtnd cutarea informaiei pe el. 11) Cei mai muli indeci sunt implementai ca arbori B. 12) Microsoft SQL Server consider c mai multe null-uri reprezint duplicate i nu va permite prezenta a mai mult de un null ntr-un index UNIQUE. Microsoft Access, Oracle, MySQL, PostgreSQL permit existen a a mai multor null-uri n astfel de coloane.

12.2

tergerea unui index utiliznd DROP INDEX

DROP INDEX index ON Tabel ; #MySQL i Microsoft Access DROP INDEX Tabel.index ; #Microsoft SQL Server DROP INDEX index ; #Oracle i PostgreSQL tergerea tergerea unui index nu afecteaz datele din tabelul asociat, de asemenea interogrile din programele gazd vor continua s funcioneze, mai greu datorit lipsei indexrii dar vor functiona fr probleme. Ex.1:DROP INDEX pub_id_idx ON titles; #terge indexul pub_id_idx n Microsoft Access i MySQL Ex.2:DROP INDEX titles.pub_id_idx ; #terge indexul pub_id_idx n Microsoft SQL Server Ex.3:DROP INDEX pub_id_idx; #terge pub_id_idx n Oracle i PostgreSQL, aceste SGBD-uri nu accept indexuri cu acelai nume pentru aceeai baza de date aa ca indexurile nu pot fi confundate.

13.

VEDERILE

O vedere este o instruciune SELECT stocat care returneaz un tabel ce contine date obinute dintr-unul sau mai multe tabele(tabele componente). 1) Tabelele componente ale unei vederi pot fi tabele de baz, tabele temporale sau alte vederi. 2) SGBD-ul stocheaz o vedere sub forma unei instruciuni SELECT nu sub forma unei mulimi de valori. 3) O vedere se manifest dinamic sub forma unui tabel atunci cnd este referit prin nume. 4) O vedre este ntotdeauna reprezentata ca un singur tabel indiferent de numrul de tabele componente la care face referire. 13.1 Crearea unei valori utiliznd CREATE VIEW CREATE VIEW vedre [(lista_coloana)] AS Interogare ; vedere - reprezint numele vederii i trebuie s fie unic n cadrul unei baze de date. lista coloane - este o list opional, cuprins ntre paranteze, de nume de coloane, separate prin virgul, care trebuie utilizate pentru coloanele din vederea view Ex.1:CREATE VIEW au_name AS SELECT au_id, au_fname, au_lname FROM authors ; #creeaz o vedre care ascunde informaiile personale(nr. tel. i adresa) despre autori Ex.2:CREATE VIEW cities (au_id, au_city, pub_id, pub_city) AS SELECT a.au_id, a.city, p.pub_id, p.city FROM authors a INNER JOIN publishers p ON a.city = p.city; #creeaz o vedre care listeaz autorii care locuiesc n orae n care se afl i sedii de edituri. n aceast vedre sunt utilizate numele de coloane au_city i pub_city, redenumirea acestor coloane elimina ambiguitatea carea ar fi aprut dac ambele coloane ar fi motenit acelai nume. Ex.3:CREATE VIEW revenues (Publishers, BookType, Revenue) AS SELECT pub_id, type, SUM(price * sales) FROM titles GROUP BY pub_id, type ; #creeaz o vedre care listeaz venitul total(=pre x vnzri) pentru fiecare editur, grupat dup tipul carii
Ex.4:CREATE VIEW au_titles(LastName, Title) AS SELECT an.au_lname, t.title_name FROM title_authors ta INNER JOIN au_names an ON ta.au_id = an.au_id INNER JOIN titles t ON t.title_id = ta.title_id WHERE a.au_id IN ('A02','A05') ; #creeaz o vedre care listeaz numele de familie ale autorilor cu codurile A02, A05 i cr ile pe care le-a scris fiecare din ei.

13.2 Regsirea datelor prin intermediul unei vederi SELECT coloana1, coloana2, ... , coloanaN FROM Vedere [JOIN compunere] [WHERE conditii_cautare] [GROUP BY coloane_grupare] [HAVING conditii_cautare] [ORDER BY conditii_sortare] ; Vedere - numele vederii care trebuie interogate
Ex.1:SELECT BookType, AVG(Revenue) FROM revenue GROUP BY BookType HAVING AVG(Revenue) > 1000000 ; #afieaz tipurile de cr i pentru care media vnzrilor a depit un milion de deloari, revenue din FROM refenue este vederea Ex.2:SELECT address3 FROM mailing_labels WHERE adress1 LIKE '%Kell%' ; #afieaz altreilea rnd al adresei potale a fiecrui autor al crui nume conine irul Kell. Ex.3:SELECT DISTINCT an.au_fname, an.au_lname FROM au_names an INNER JOIN title_authors ta ON an.au_id = ta.au_id WHERE ta.au_order > 1 ;#afieaz numele fiecrui autor care nu a fost autor principal al cel puin unei cri.

13.3

Actualizarea datelor prin intermediul vederilor

O vedere actualizabil este o vedere care permite modificarea tabelelor componente prin intermediul instruciunilor INSERT, UPDATE i DELETE. O modificare efectuat asupra unei vederi actualizabile se propag ntotdeauna n tabelele componente.

CREATE VIEW ny_authors AS SELECT au_id, au_fname, au_lname, state FROM authors WHERE state = 'NY' ; #am creat o vedere ny_authors care listeaz codul, numele i statul de reedin numai pentru autorii care locuiesc n statul New York. SELECT * FROM ny_authors ; #afieaz vederea ny_authors INSERT INTO ny_authors VALUES('A08', 'Don', 'Dawson', 'NY'); #insereaz un rnd prin intermediul vederii ny_authors INSERT INTO ny_authors VALUES ('A09', 'Jill', 'LeFlore', 'CA'); #insereaz un rnd nou prin intermediul vederii ny_authors. SGBD-ul ar fi anulat inserarea dac la crearea vederii ny_authors ar fi fost utilizat opiunea WITH CHECK

1) O vedere neactualizabil este o vedere care nu permite modificarea tabelelor prin intermediul utilizrii instruciunilor INSERT, UPDATE i DELETE, se mai numete i vedere read-only. 2) Pentru ca o vedere s fie actualizabil, instruc iunea SELECT trebuie s ndeplineasc condiiile: - vederea trebuie definit numai pe baza unui singur tabel(nu trebuie s conin compuneri); - instruciunea SELECT nu poate conine clauza GROUP BY sau HAVING; - utilizarea instruciunii SELECT DISTINCT este interzis; - utilizarea interogrilor care conin clauza UNION, INTERSECT i EXCEPT este interzis; - instruciunea SELECT poate conine numai referine la coloane simple, nu i la coloane rezultate n urma calculelor, din func ii de comasare; -dac tabelul de baz este el nsui o vedere, ce trebuie actualizat.

OBServaii:

14

TRANZACIILE

O tranzacie este o succesiune de una sau mai multe instruciuni SQL executate ca o singur unitate logic. Presupunem c dorim s scoatem 500USD dintr-un cont i s-i introducem n alt cont: UPDATE savings_accounts SET balance = balance - 500.00 WHERE account_number = 1009 ; UPDATE savings_accounts SET balance = balance + 500.00 WHERE account_number = 6482 ; Dac apare o pan de curent, o problem de hard sau orice fel de ntrerupere exist riscul ca setul de operaiuni s nu se execute complet, exist riscul ca prima operaiune financiara s aib loc i a doua s nu aib loc ceea ce ar duce la probleme grave. De aceea e nevoie de un mecanism care s permit derularea napoi, contracararea efectelor primei operaii dac a doua nu a avut loc. Termeni: 1) Permanentizarea - commit - permanentizarea unei tranzacii presupune ca toate modificrile de date efectuate de la nceputul tranzaciei s devin o parte permanent a bazei de date. 2) Derularea napoi - roll back - reprezinta anularea tuturor modificrilor efectuate de o tranzacie, este un fel de Undo. 3) Jurnalul de tranzacii - este o nregistrare secvenial a tuturor modificrilor efectuate asupra bazei de date prin intermediul tranzaciilor. Conine nceputul fiecrei tranzacii, modificrile efectuate asupra datelor precum i suficient informaie pentru refacerea modificrilor efectuate. La executarea unei tranzacii este uneori nevoie de prioritti de super-user. Procesarea tranzaciei se refer numai la instruciunile INSERT, UPDATE, DELETE, NU pot fi derulate napoi instruciunile de tipul SELECT, CREATE, ALTER sau DROP. Fiecare instruciune INSERT, UPDATE i dELETE ar trebui executat ca parte a unei tranzacii. SGBD-ul permite salvarea datelor prin copii de back-up, e de preferat salvarea acestor copii pe diskuri diferite.

SGBD-ul ar fi anulat operaia de inserare dac vederea ny_authors ar fi fost definit astfel: CREATE VIEW ny_authors AS SELECT au_id, au_fname, au_lname, state FROM authors WHERE state = 'NY' WITH CHECK OPTION; #absena check option indic faptul c SGBD-ul nu este obligat s pstreze coerena cu definiia original a vederii. Actualizarea unui rnd prin intermediul unei vederi UPDATE ny_authors SET au_fname = 'Yasmin', au_lname = 'Howcomely' WHERE au_id = 'A01' ; #actualizeaz un rnd existent prin intermediul vederii ny_authors. De asemenea, dac vederea ar fi fost creat with check option, rndurile nu ar fi putut fi modificate dac acest lucru le-ar face s fie elimitate din vedere tergerea unui rnd prin intermediul unei vederi DELETE FROM ny_authors WHERE au_id = 'A05'; #terge un rnd existent prin intermediul vederii ny_authors TERGEREA UNEI VEDERI CU DROP VIEW DROP VIEW Vedere ; tergerea vederilor nu afecteaz tabelele, n
SQL nu exist nicio instruciune ALTER VIEW deci vederile nu pot fi modificate, Microsoft SQL Server i Oracle conine aceast instruc iune iar MySQL 4.0 nu accept vederile

Pentru nceperea unei tranzacii - n Microsoft Access i Microsoft SQL Server se folosete BEGIN TRANZACTION; - n MySQL i PostgreSQL: BEGIN: Permanentizarea tranzaciei: COMMIT; Pentru derularea napoi a tranzaciei: ROLLBACK; SELECT SUM(pages), AVG(price) FROM titles; BEGIN: UPDATE titles SET pages = 0; UPDATE titles SET price = price * 2; SELECT SUM(pages), AVG(price) FROM titles ; ROLLBACK ; SELECT SUM(pages), AVG(price) FROM titles; # executarea scriptului urmtor face s afieze prima dat informaia nainte de efectuarea tranzaciei, dup efectuarea tranzaciei(al doilea select), dup efectuarea unei comenzi ROLLBACK, al treilea select. Dup cum putei observa, NU am dat COMMIT, operaiile tranzaciei nu sunt finale. Rezultat: SUM(pages) AVG(price) 5107 18.3875 SUM(pages) AVG(price) 0 36,7750 SUM(pages) AVG(price) 5107 18,3875 Este obligatoriu s ncheiem ntotdeauna o tranzacie cu ROLLBACK sau COMMIT, lipsa punctului de ncheiere poate conduce la tranzacii uriae, cu rezultate imprevizibile asupra datelor sau, n cazul terminrii anormale a programului, la derularea napoi a ultimei tranzacii nepermanentizate. Marea majoritate a SGBD-urilor opereaz implicit n modul de permanentizare automat(autocommit), cu excepia situaiilor n care acest mod de lucru este suprimat temporar de tranzaciile implicite sau explicite. n modul de permanentizare automat, fiecare instruciune este executat ca fiind propria sa tranzacie. Dac o instruciune se execut cu succes, SGBD-ul o va permanentiza, dac SGBD-ul ntmpin probleme, deruleaz napoi instruciunea respectiv.

BEGIN: DELETE FROM title_authors WHERE title_id IN ( SELECT tiutle_id FROM titles WHERE pub_id = 'P04' ); DELETE FROM royalties WHERE title_id IN ( SELECT title_id FROM titles WHERE pub_id = 'P04'); DELETE FROM titles WHERE pub_id = 'P04' ; DELETE FROM publishers WHERE pub_id = 'P04' ; COMMIT; #utilizeaz o tranzacie pentru a terge editura cu codul P04 din tabelul publishers i pentru a terge rndurile asociate din alte tabele - se elimin astfel erorile de tipul integritate referenial. Deoarece unele valori ale cheii externe din tabelul titles refer editura cu codul P04 din tabelul publishers, mai nti trebuie terse rndurile asociate din tabelele titles, titles_authors i royalties. Pentru a executa toate instruciunile DELETE se utilizeaz o tranzacie. Dac numai unele instruciuni au fost executate cu succes, datele vor fi incorecte datorit nerespectrii integritii refereniale. Pentru tranzaciile lungi se pot stabili n mod arbitrar marcaje intermediare(puncte de salvare) care permit mprirea tranzaciei n pri mai mici i derularea napoi a modificrilor efectuate de la punctul curent din cadrul tranzaciei pn la un puct anterior din cadrul tranzaciei.