Sunteți pe pagina 1din 32

50 Partea l Utilizarea general a sistemului MySQL

mysql> SHOW TABLES;


Tables_in_samp_db
membru preedinte
Dac nu reuii nici mcar s v reamintii numele bazei de date, invocai mysql fr specifica un nume al bazei
de date n linia de comand; apoi emitei o interogare SH( DATABASES:
mysql> SHOW DATABASES;
Database
menajerie mysql samp_db test
Lista cu baze de date variaz de la un server la altul, dar trebuie ca n list s apar ( puin samp_db i mysql;
ultima conine tabelele de acordare, care controleaz privilegi de acces MySQL.
Interogrile DESCRIBE i SHOW au echivalente n linie de comand pe care le putei folc din interpreter:
Afieaz toate bazele de date, ca SHOW DATABAS
Afieaz tabelele din baza de date dat, ca SH TABLES
Afieaz coloanele din tabelul dat, ca DESCRI nume tabel
% mysqlshow
% mysqlshow nume_db
% mysqlshow nume_db nume_tabel
Tabele pentru proiectul de eviden a rezultatelor colare
Pentru a vedea care sunt tabelele de care avem nevoie pentru proiectul de eviden a rez aelor colare, s
examinm modul n care se pot scrie punctajele atunci cnd folosii catalog pe hrtie. Figura 1.2 prezint o
pagin din catalogul dumneavoastr. Coninu principal al acestei pagini este o matrice pentru nregistrarea
punctajelor. De asemenea, mai afl i alte informaii necesare pentru nelegerea punctajelor. Numele elevilor
numerele de identificare sunt prezentate n partea de jos a matricei. (Pentru simplitate, fost prezentate numai
notele a patru elevi.) De-a lungul prii de sus a matricei, ser datele chestionarelor i ale testelor. Figura arat c
ai dat chestionare pe 3, 6,16 i 23 si tembrie, respectiv teste pe 9 septembrie, respectiv l octombrie.
Pentru a pstra evidena acestor tipuri de informaii folosind o baz de date, av nevoie de un tabel puncte. Ce
trebuie s conin nregistrrile din acest tabel? Simp Pentru fiecare rnd, avem nevoie de numele elevului, data
chestionarului sau a testu si punctajul obinut. Figura 1.3 prezint aspectul unor note din catalog atunci cnd si]
reprezentate ntr-un tabel ca acesta. (Datele sunt scrise n modul n care le reprezh MySQL, respectiv "AAAA-
LL-ZZ".)
Capitolul 1 Introducere n MySQL i SQL
51
Elevi Puncte
C C T C C T
ID Nume 9/3 9/6 9/9 9/16 9/23 10/1 ...
1 Billy 14 10 73 14 15 67
2 Missy 17 10 68 17 14 73
3 Johnny 15 10 78 12 17 82
4 Jenny 14 13 85 13 19 79
Figura 1.2 Exemplu de catalog. Tabelul puncte
Nume Data Puncte
Billy 1999-09-23 15
Missy 1999-09-23 14
Johnny 1999-09-23 17
Jenny 1999-09-23 19
Billy 1999-10-01 67
Missy 1999-10-01 73
Johnny 1999-10-01 82
Jenny 1999-10-01 79
Figura 1.3 Aspectul initial al tabelului puncte.
Totui, la configurarea tabelului n acest mod apare o problem. Se pare c tabelul omite i unele informaii. De
exemplu, dac examinm nregistrrile din figura 1.3, nu ne putem da seama dac punctajele au fost obinute la
un chestionar sau la un test. Este important s tim tipurile de punctaje la determinarea notelor finale, dac
chestionarele i testele au ponderi diferite. Putem ncerca s deducem tipul examinrii din plaja de rezultate de la
o anumit dat (de regul, la chestionare se obin mai puine puncte dect la teste), dar nu este convenabil,
deoarece ne bazm pe deducie si nu pe date explicite.
Se poate face deosebire ntre punctaje menionnd tipul acestora n fiecare nregistrare, de exemplu prin
adugarea unei coloane n tabelul puncte care conine literele T sau C n fiecare rnd, pentru a indica test" sau
chestionar", aa cum se poate vedea n figura 1.4. Acest procedeu are avantajul c tipul punctajului devine
explicit n cadrul datelor. Dezavantajul este c aceste informaii sunt oarecum redundante. Remarcai c, pentru
toate nregistrrile cu o anumit dat, coloana cu tipul punctajului are ntotdeauna aceeai valoare. Punctajele
pentru 23 septembrie au toate tipul C, iar rezultatele pentru l octombrie sunt toate de tipul T. Neplcut. Dac
nregistrm un set de punctaje pentru un chestionar sau pentru un test n acest mod, nu numai c vom scrie
aceeai dat pentru fiecare nregistrare nou din set, dar vom scrie mereu si mereu acelai tip de punctaj. Uf...
Cine s scrie toate aceste informaii redundante?
S ncercm o reprezentare alternativ, n loc de a nregistra tipurile de punctaje n tabelul puncte, le vom deduce
din datele calendaristice. Putem pstra o list cu date calendaristice si o putem folosi pentru a pstra evidena
tipului de examinare" (chestionar sau test) care a avut loc la fiecare dat. Apoi, putem determina dac un anumit
punctaj a fost obinut la un chestionar sau la un test prin combinarea acestuia cu informaiile din "sta noastr cu
evenimente: se stabilete o echivalen ntre data din tabelul puncte cu
!*-'
52 Partea l Utilizarea general a sistemului MySQL
data din tabelul eveniment pentru a determina tipul de punctaj. Figura 1.5 prezii aceast machet de tabel si
demonstreaz modul n care aceast asociere functione; pentru o nregistrare din tabelul puncte care poart data
de 23 septembrie. Prin coroh rrea nregistrrii cu nregistrarea echivalent din tabelul eveniment, vedem c
puncta a fost obinut la un chestionar.
Tabelul puncte
Nume Data Puncte Tip
Billy 1999-09-23 15 C
Missy 1999-09-23 14 C
Johnny 1999-09-23 17 C
Jenny 1999-09-23 19 C
Billy 1999-10-01 67 T
Missy 1999-10-01 73 T
Johnny 1999-10-01 82 T
Jenny 1999-10-01 79 T
Figura 1.4 Macheta tabelului puncte, revizuit pentru a include tipurile de punctaje.
Tabelul puncte
Tabelul eveniment
Nume Data Puncte
Billy 1999-09-23 15
Missy 14
Johnny 1999-09-23 17 19 67
Jenny Billy 1999-09-23 73 82 79
Missy 1999-10-01
Johnny 1999-10-01
Jenny 1999-10-01
1999-10-01
Data
1999-09-03 1999-0946 1999-09-09

1999-10-01
T/P
CC
T JL
Figura 1.5 Tabelele puncte i eveniment, legate prin dat.
Este mult mai bine dect s ncercai a deduce tipul punctajului pe ghicite"; n schir obinem tipul direct din
datele nregistrate n mod explicit n baza noastr de date. asemenea, este o opiune de preferat fa de
nregistrarea tipurilor de punctaje n tabe puncte, deoarece trebuie s nregistrm fiecare tip o singur dat.
Totui, dac suntei ca mine, cnd auzii pentru prima dat de acest lucru (combir informaiilor din mai multe
tabele), v gndii: Mda, bun idee, dar e mult munc faci mereu toate cutrile alea; nu complicm lucrurile?"
ntr-un fel, avei dreptate. Folosirea a dou liste cu nregistrri este mai complicat i folosirea unei singure liste.
Dar s mai privim o dat la catalog (vezi figura l .2). Nu aii deja dou seturi de nregistrri? inei cont de
urmtoarele aspecte:
Pstrai evidena punctajelor folosind celulele din matricea tabelului puncte, ui fiecare celul este indexat de
numele elevului i dat (n jos pe lateral i de-a lur prii superioare a matricei). Acesta reprezint un set de
nregistrri; este analog coninutul tabelului punctaj.
Cum procedai pentru a ti tipul de eveniment pe care l reprezint fiecare dat? i scris un T sau un C mic
deasupra fiecrei date! Astfel, pstrai i evidena asocierii i dat si tipul punctajului, de-a lungul prii de sus a
matricei. Acesta reprezint doilea set de nregistrri; este analog cu coninutul tabelului eveniment.
Capitolul 1 Introducere n MySQL i SQL
53
i Cu alte cuvinte, chiar dac nu contientizai acest lucru, n realitate utilizai catalogul | ntr-un mod absolut
similar cu cel propus de mine, de pstrare a informaiilor n dou tabele. Singura diferen real este c acele
dou categorii de informaii nu sunt separate n mod att de explicit n catalog.
Pagina din catalog ilustreaz ntr-un fel modul n care noi gndim informaiile, precum i dificultatea
determinrii modului de a plasa informaiile ntr-o baz de date: noi tindem s integrm diferitele categorii de
informaii i s le interpretm ca pe un ntreg. Bazele de date procedeaz altfel, motiv pentru care par uneori
artificiale i nenaturale. Tendina noastr natural de a unifica informaiile ngreuneaz uneori pn si sesizarea
faptului ca avem mai multe tipuri de date, nu doar unul singur. Din aceast cauz, ncercarea de a gndi ca o
baz de date" n ceea ce privete modul de reprezentare a datelor poate fi o mare problem.
O cerin impus tabelului eveniment de macheta prezentat n figura 1.5 este aceea ca datele s fie unice,
deoarece data este folosit pentru a corela nregistrrile din tabelele puncte si eveniment. Cu alte cuvinte, nu
putei da dou chestionare n aceeai zi, respectiv un chestionar i un test. Dac o facei, vei avea dou seturi de
nregistrri n tabelul puncte si dou nregistrri n tabelul eveniment, toate cu aceeai dat, si nu vei mai putea
stabili o coresponden ntre nregistrrile din cele dou tabele.
Aceasta este o problem care nu va aprea niciodat dac ntr-o zi survine o singur examinare, dar putem
presupune n mod corect c acest lucru nu se va ntmpla? n aparen rspunsul este afirmativ; la urma urmelor,
nu suntei att de sadic nct s dai un chestionar i un test n aceeai zi. Dar sper c m vei ierta dac sunt
sceptic. Am auzit deseori oameni care spun despre datele lor: Acest caz ciudat nu se va ntmpla niciodat."
Apoi, se dovedete c acel caz ciudat chiar se produce cu o anumit ocazie si de regul este necesar s v re-
proiectai tabelele pentru a remedia problema pe care a cauzat-o acel caz ciudat.
Este mai bine s anticipai posibilele probleme i modul de a le rezolva. Deci, s presupunem c uneori suntei n
situaia de a nregistra dou seturi de punctaje pentru aceeai zi. Cum ne putem descurca? Aa cum se va vedea,
nu este o problem chiar att de dificil. Cu o mic modificare n modul de dispunere a datelor, apariia mai
multor evenimente la o anumit dat nu va provoca necazuri:
l- Adugai o coloan la tabelul eveniment si folosii-o pentru a-i atribui un numr unic fiecrei nregistrri din
tabel. Astfel, fiecare eveniment va avea propriul su numr de identificare, deci coloana va avea numele
eveniment_id. (Dac pare ciudat, catalogul din figura 1.2 are deja aceast proprietate: identificatorul de
eveniment este similar numrului coloanei din matricea cu punctaje din catalog. Se poate ca numrul s nu ne
scris n mod explicit i denumit identificator de eveniment", dar este chiar un identificator de evenimente.)
2. Cnd inserai punctaje n tabelul puncte, nregistrai identificatorul de eveniment n locul datei.
Rezultatul acestor modificri este prezentat n figura 1.6. Acum, coroborai tabelele puncte i eveniment folosind
identificatorul de eveniment n locul datei i utilizai tabelul eveniment pentru a determina nu numai tipul
fiecrui punctaj, dar si data la care a *ost obinut acesta. De asemenea, elementul unic din tabelul eveniment nu
mai trebuie
54
Partea l Utilizarea general a sistemului MySQL
s fie data, ci identificatorul de eveniment. Aceasta nseamn c putei avea zece teste i chestionare n aceeai
zi; putei pstra evidena lor corect n scriptele dumneavoastr. (Indiscutabil, elevii dumneavoastr vor fi extrem
de ncntai s afle acest lucru.) Din pcate, din punct de vedere al operatorului uman, macheta de tabel din
figura 1.6 pare mai puin satisfctoare dect cele anterioare. Tabelul puncte este mai abstract, deoarece conine
mai puine coloane cu o semnificaie evident. Macheta de tabel prezentat anterior n figura 1.4 era uor de
examinat si de neles, deoarece tabelul puncte avea coloane att pentru date, ct i pentru tipurile de punctaj.
Tabelul puncte actual, prezentat n figura 1.6, nu are coloane pentru nici una din aceste informaii, ceea ce pare
serios deplasat fa de normal. Cine vrea s citeasc un tabel puncte care conine identificatoare de eveniment"?
Pentru noi, aceast informaie nu are o semnificaie prea important.
Tabelul puncte
Tabelul eveniment
Nume eveniment id Puncte
Billy 5 15
Missy :5 ' 14
Johnny 556666 17 19
Jenny 67 73
Billy 82 79
Missy
Johnny
Jenny
eveniment id Data Tip
123 1999-09- C C
4 03 1999- T C
09-06
1999-09-
09 1999-
09-15
5 1999-09- C
23
6 1999-10- T
01
Figura 1.6 Tabelele puncte i eveniment, legate dup identificatorul de eveniment.
Acum ai ajuns la o rscruce. Suntei interesat de posibilitatea de a putea pstra evidena electronic a
rezultatelor colare i de a nu trebui s efectuai tot felul de calcule manuale obositoare atunci cnd atribuii
notele. Dar, dup ce v gndii la modul n care vei reprezenta informaiile despre punctaje ntr-o baz de date,
suntei descurajat de aspectul abstract i discontinuu al informaiei reprezentate n acel mod.
Natural, aceasta duce la o ntrebare: N-ar fi bine s nu folosesc deloc o baz de date? Poate c MySQL nu este
pentru mine." Aa cum putei intui, voi rspunde negativ la aceast ntrebare, deoarece altfel cartea de fa ar
ajunge rapid la final. Dar, atunci cnd v gndii cum s facei un lucru anume, este bine s avei n vedere
diferite alternative i s v ntrebai dac n-ar fi mai bine s folosii un sistem de baze de date, cum este SQL, sau
altceva, cum ar fi un program de calcul tabelar:
Catalogul are rnduri i coloane, ca i o foaie de calcul tabelar. De aceea, o foaie de calcul tabelar i un catalog
sunt foarte asemntoare att vizual, ct i conceptual.
Intr-o foaie de calcul tabelar se pot efectua calcule, deci putei nsuma punctajele fiecrui elev folosind un cmp
de calcul. Este puin mai greu s acordai o pondere diferit chestionarelor si testelor, dar nu imposibil.
Pe de alt parte, dac dorii s examinai numai o parte a datelor dumneavoastr (numai chestionarele sau numai
testele, de exemplu), s facei comparaii (ntre notele bieilor i cele ale fetelor) sau s afiai informaii de
sumar ntr-un mod flexibil, datele problemei se schimb. O foaie de calcul tabelar nu funcioneaz att de bine,
n timp ce sistemele de baze de date relaionale execut cu uurin aceste operaii.
Capitolul 1 Introducere n MySQL i SQL
55
LJn alt element care trebuie avut n vedere este aceea c natura abstract i discontinu a datelor reprezentate
ntr-o baz de date relaional nu este, la urma urmelor, o problem att de mare. Trebuie s v gndii la acea
reprezentare atunci cnd configurai baza de date, astfel nct s nu v dispunei datele ntr-un mod lipsit de sens
n raport cu felul n care dorii s le utilizai. Totui, dup ce ai determinat modul de reprezentare, vei conta pe
motorul de baze de date pentru adunarea i reprezentarea datelor dumneavoastr ntr-un mod semnificativ. Nu
vei mai privi datele ca pe o aduntur de componente fr legtur ntre ele.
De exemplu, cnd regsii punctaje din tabelul puncte, nu dorii s vedei identificatoare de eveniment; dorii s
vedei date. Aceasta nu este o problem. Baza de date va cuta datele din tabelul eveniment n funcie de
identificatorul de eveniment si vi le va prezenta. De asemenea, putei don s vedei dac punctajele au fost
obinute la chestionare sau teste. Nici aceasta nu este o problem. Baza de date va cuta tipurile de punctaje n
acelai mod: folosind identificatorul de eveniment. Nu uitai, acesta este punctul forte" al unui sistem de baze
de date relaionale ca MySQL: corelarea unui lucru cu altul pentru a extrage informaii din mai multe surse si de
a v prezenta datele pe care dorii s le vedei. In cazul datelor noastre de eviden a rezultatelor colare, MySQL
este cel care adun informaiile la un loc folosind identificatorii de eveniment, pentru ca dumneavoastr s nu
mai efectuai aceast operaie.
Acum, pentru a da o mic idee n avans" cu privire la modul n care cerei sistemului MySQL s execute aceast
corelaie ntre lucruri, s presupunem c dorii s vedei punctajele obinute la data de 23 septembrie 1999.
Interogarea pentru extragerea punctajelor aferente unui eveniment produs la o anumit dat se prezint astfel:
SELECT puncte.nume, eveniment.data, puncte.puncte, eveniment.tip
FROM puncte, eveniment
WHERE eveniment.data = "1999-09-23"
AND puncte.eveniment_id = eveniment.eveniment_id
Cam de speriat, este? Aceast interogare regsete numele elevului, data, punctajul i tipul punctajului prin
alturarea (corelarea) nregistrrilor din tabelul puncte cu nregistrrile din tabelul eveniment. Rezultatul arat
astfel:
Nume Data Puncte Tip
Billy 1999-09-2315 15 C
Missy 1999-09-2314 14 C
Johnny 1999-09-2317 17 C
Jenny 1999-09-2319 19 c
Formatul acestor informaii v sun" cunoscut? Ar fi i cazul; este acelai cu macheta tabelului prezentat n
figura 1.4! Nu trebuie s cunoatei identificatorul de eveniment pentru a obine acest rezultat. Specificai data
care v intereseaz si lsai sistemul MySQL s determine nregistrrile din tabelul puncte care corespund datelor
respective. Dac v-ai ntrebat n ce msur din cauza aspectului abstract i discontinuu se pierde" ceva n ceea
ce privete preluarea informaiilor dintr-o baz de date ntr-o form semnificativ pentru noi, rspunsul este: nu
se pierde nimic.
56 Partea l Utilizarea general a sistemului MySQL
Desigur, dup ce ai examinat aceast interogare, v mai putei pune i alt ntrebare. Instruciunea pare cam
lung i complicat; nu pare o cantitate cam mare de munc numai pentru regsirea punctajelor obinute la o
anumit dat? Ba da, este. Totui, exist metode de a evita tastarea mai multor rnduri de instruciuni SQL de
fiecare dat cnd dorii s emitei o interogare, n general, determinai o singur dat modul de a executa o
interogare ca aceea i apoi o stocai, pentru a o putea repeta cu uurin atunci cnd este necesar. Vom vedea cum
se procedeaz n seciunea Sugestii pentru interaciunea cu MySQL".
n realitate, am cam exagerat punnd pe tapet acea interogare. Si totui interogarea respectiv este, credei sau
nu, ceva mai simpl dect cea pe care o vom folosi efectiv pentru extragerea punctajelor. Motivul este c trebuie
s mai facem o modificare n structura tabelului, n loc de a nregistra numele elevului n tabelul puncte, vom
folosi un identificator de elev unic. (Adic vom folosi valoarea din coloana ID a catalogului n locul valorii din
coloana Nume.) Apoi vom crea un alt tabel, denumit elev, care conine coloanele nume si elev_id (Figura 1.7).
Tabelul elev Tabelul puncte
Tabelul eveniment
Nume Sex elev_id elev_id eveniment_id Puncte
Billy M 1 1 5 15
Missy F 2 H 2 <ysJSjSiSB! 14 L
B
"
Johnny M 3 34567 556666 17 19
Jenny F 4 8 67 73
82 79

eveniment id

Data
1999-09-03 1999-09-06 1999-09-09 1999-09-16
1999-09-23
1999-10-01
Tip
CC
TC
Figura 1.7 Tabelele elev, puncte i eveniment, legate prin identificatorul de elev i identificatorul de eveniment.
De ce s facem aceast modificare? n primul rnd pentru c pot fi doi elevi cu acelai nume. Utilizarea unui
numr unic de identificare a elevului v ajut s facei diferena dintre punctajele elevilor. (Este exact acelai
lucru ca i diferenierea ntre punctajele obinute la un test i la un chestionar date n aceeai zi prin utilizarea n
locul datei a unui identificator unic de eveniment.)
Dup aceast modificare a machetei tabelului, interogarea pe care o vom folosi efectiv pentru extragerea
punctajelor aferente unei anumite date devine puin mai complex:
SELECT elev.nume, eveniment.data, puncte.puncte, eveniment.tip
FROM eveniment, puncte, elev
WHERE eveniment.data = "1999-09-23"
AND eveniment.eveniment_id = puncte.eveniment_id
AND puncte.elev_id = elev.elev_id
Dac v ngrijoreaz faptul c nu putei determina imediat semnificaia acelei interogri, linitii-v. Majoritatea
oamenilor nu sunt n stare de aa ceva. Vom revedea interogarea dup ce vom continua parcurgerea acestui
manual, dar diferena ntre acum i mai trziu este c mai trziu o vei nelege. Nu, nu m in de bancuri.
Capitolul 1 Introducere n MySQL i SQL
57
Din figura 1.7, vei observa c am adugat ceva la tabelul elev care nu exista n catalog: o coloan pentru sex.
Aceasta va permite efectuarea unor operaii simple, precum numrarea bieilor i a fetelor din clas, respectiv
mai complexe, precum compararea punctajelor bieilor cu cele ale fetelor.
Suntem aproape gata cu tabelele pentru proiectul de eviden a rezultatelor colare. Mai avem nevoie de un
singur tabel, pentru nregistrarea absenelor n vederea determinrii prezenei la curs. Coninutul acestuia este
relativ simplu: un identificator numeric al elevului i o dat (vezi figura 1.8). Fiecare rnd din tabel arat c
elevul respectiv a fost absent la acea dat. La sfritul perioadei de notare, vom apela la caracteristicile de
numrare ale sistemului MySQL pentru a rezuma coninutul tabelului, astfel nct s tim de cte ori a fost
absent fiecare elev.
Tabelul absente
elev_id Data
"2 4 2 1999-09-02
1999-09-15
1999-09-20
Figura 1.8 Tabelul absente.
Suntem gata de a crea tabelele noastre de eviden a rezultatelor colare, acum cnd tim cum vor arta acestea.
Instruciunea CREATE TABLE pentru tabelul elev arat astfel: CREATE TABLE elev
nume VARCHAR(20) NOT NULL, sex ENUMCFVM1) NOT NULL,
elev_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ) Tastai aceast instruciune
n mysql sau executai urmtoarea comand de interpreter:
% mysql samp_db < creat e_student.sql
Instruciunea CREATE TABLE creeaz un tabel denumit elev cu trei coloane: nume, sex i elev_id.
nume este o coloan ir de lungime variabil, care poate conine maximum 20 de caractere. Aceast reprezentare
a numelor este mai simpl dect cea folosit pentru tabelele Ligii istorice, folosind o singur coloan n locul
unor coloane separate pentru nume i prenume. Aceasta deoarece tiu dinainte c nici un exemplu de interogare
privind evidena rezultatelor colare nu va trebui s efectueze vreo operaie care s-ar preta mai bine la dou
coloane. (Da, triez. Recunosc.)
sex determin dac un elev este biat sau fata. Este o coloan de tip ENUM (enumerare), ceea ce nseamn c
poate lua numai una din valorile enumerate explicit n specificaia coloanei, n spe M sau F, adic de sex
masculin sau feminin. ENUM este util cnd avei un set limitat de valori pe care le poate conine o coloan. Am
fi putut folosi n schimb CHAR(1 ), dar ENUM specific mai exact care pot fi valorile din coloan. Dac emitei
o instruciune DESCRIBE numejtabel pentru un tabel care conine o coloan ENUM, MySQL v va indica exact
care sunt valorile posibile.
58
Partea l Utilizarea general a sistemului MySQL
Apropo, valorile dintr-o coloan ENUM nu trebuie s fie neaprat compuse dintr-un singur caracter. Coloana tip
ar fi putut fi declarat astfel: ENUM (' feminin', ' masculin').
elev_id este o coloan de tip ntreg care va conine numere unice de identificare a elevilor, n mod normal, vei
primi numerele de identificare a elevilor de la o surs central, cum ar fi secretariatul scolii, dar noi vom folosi
valori inventate. Declaraia coloanei elev_id are numeroase pri, chiar dac nu conine dect numere:
I NT arat c n coloan sunt incluse numere ntregi (valori fr parte fracionar)
UNSIGNED interzice utilizarea numerelor negative.
NOT NULL nseamn c valoarea coloanei trebuie completat. (Nici un elev nu poate fi lipsit de un numr de
identificare.)
AUTO_INCREMENT este un atribut special n MySQL si funcioneaz astfel: dac valoarea din coloana
elev_id lipsete (sau este NULL), atunci cnd creai o nou nregistrare n tabelul elev, MySQL genereaz
automat un numr unic cu o unitate mai mare dect valoarea maxim care se afl n coloan la momentul
respectiv. Vom folosi acest fapt la ncrcarea tabelului elev, specificnd valori numai pentru coloanele nume i
sex si permind sistemului MySQL s genereze automat valoarea coloanei elev_id.
PRIMARY KEY arat c acea coloan este indexat pentru cutri rapide i c fiecare valoare din coloan
trebuie s fie unic. Aceasta ne mpiedic s folosim din greeal acelai identificator de dou ori, ceea ce este o
proprietate necesar a numerelor de identificare a elevilor. (Nu numai att; MySQL impune ca fiecare coloan
AUTO_INCREMENT s aib un indice unic.)
Dac nu nelegei toate chestiile astea despre AUTO_INCREMENT si PRIMARY_KEY, gndii-v c ele
reprezint o modalitate magic de a genera numere de identificare pentru fiecare elev. Nu conteaz valorile n
sine, atta vreme ct sunt unice.
Not: Dac aveai de gnd s luai identificatoarele numerice ale elevilor de la secretariat (fr s le generai
automat), putei declara coloana elev_id n acelai mod, cu deosebirea c vei omite atributul
AUTO_INCREMENT.
Tabelul eveniment se prezint astfel: CREATE TABLE eveniment
data DATE NOT NULL
tip ENUM('T','C1) NOT NULL,
eveniment_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
Tastai instruciunea de mai sus n mysql sau executai urmtoarea comand de interpreter:
% mysql samp_db < create_event.sql
Toate coloanele sunt declarate ca NOT NULL, deoarece nu poate lipsi valoarea nici uneia dintre ele.
Coloana data conine o valoare DATE standard MySQL, n format "AAAA-LL-ZZ" (cu anul scris primul).
tip reprezint tipul punctajului. Ca si sex din tabelul elev, tip este o coloan de tip enumerare. Valorile permise
sunt T si C, reprezentnd test", respectiv chestionar".
Capitolul 1 Introducere n MySQL i SQL
59
eveniment_id este o coloan AUTO_INCREMENT, similar coloanei elev_id din tabelul elev. Utilizarea opiunii
AUTO_INCREMENT ne permite s generm cu uurin valori unice ale identificatorilor de eveniment. Ca n
cazul coloanei elev_id din tabelul elev, valorile particulare sunt mai puin importante dect unicitatea lor.
Tabelul puncte arat astfel: CREATE TABEL puncte (
elev_id INT UNSIGNED NOT NULL, eveniment_id INT UNSIGNED NOT NULL, punctaj INT NOT
NULL, PRIMARY KEY (eveniment_id, elev_id) ) Tastai acea instruciune n mysql sau executai urmtoarea
comand de interpreter:
% mysql samp_db < creat e_score.sql
puncte este o coloan INT (ntreg). Cu alte cuvinte, se presupune c valorile punctajelor sunt ntotdeauna ntregi.
Dac dorii s permitei includerea unor punctaje precum 58 , 5, care conin o pane fracionar, vei folosi unul
din tipurile de coloan cu virgul mobil, precum FLOAT sau DECIMAL.
Coloanele elev_id i eveniment_id sunt ntregi care reprezint elevul i evenimentul pentru care a fost acordat
fiecare punctaj. Folosindu-le pentru a stabili legturi ntre tabelele elev si eveniment, vom putea determina
numele elevului si data evenimentului. De asemenea, am transformat combinaia dintre cele dou coloane ntr-o
cheie primar (PRIMARY KEY). Astfel, ne asigurm c nu vom avea punctaje repetate pentru un elev la un test
sau chestionar dat. De asemenea, modificarea ulterioar a unui punctaj este mai simpl. De exemplu, cnd un
punctaj a fost introdus incorect, putem elimina nregistrarea veche atunci cnd inserm nregistrrile noi,
folosind instruciunea MySQL REPLACE. Nu este necesar s folosim o instruciune DELETE combinat cu
INSERT; MySQL execut automat aceast operaie.
Reinei unicitatea combinaiei ntre coloanele eveniment_id si elev_id. n tabelul puncte, nici o valoare nu este
intrinsec unic. Vor exista mai multe nregistrri de punctaje pentru fiecare valoare eveniment_id (cte una
pentru fiecare elev), respectiv mai multe nregistrri pentru fiecare valoare elev_id (cte una pentru fiecare
chestionar i test).
Tabelul absente pentru determinarea prezenei la curs se prezint astfel: CREATE TABLE absente
elev_id INT UNSIGNED NOT NULL, data DATE NOT NULL, PRIMARY KEY (elev_id, data) )
Tastai instruciunea respectiv n mysql sau executai urmtoarea comand de interpreter: % mysql sarap_db <
create_absence.sql
60
Partea l Utilizarea general a sistemului MySQL
Coloanele elev_id i data sunt ambele declarate NOT NULL pentru a interzice absena valorilor. Vom transforma
combinaia dintre cele dou coloane ntr-o cheie primar, astfel nct s nu crem din greeal nregistrri
dublate. La urma urmelor, nu-i frumos s pui absen unui elev de dou ori ntr-o zi!
Adugarea de noi nregistrri
n acest moment, baza noastr de date si tabelele au fost create, iar n seciunea urmtoare, Regsirea
informaiilor", vei afla cum se pot extrage datele din baza de date. Mai nti ns, trebuie s inserm unele
nregistrri n tabele.
Exist numeroase modaliti de a aduga date ntr-o baz de date. Putei insera manual nregistrri ntr-un tabel
emind instruciuni INSERT. De asemenea, putei aduga nregistrri citindu-le dintr-un fiier, fie sub form de
valori de date brute pe care le ncrcai folosind instruciunea LOAD DATA sau utilitarul mysqlimport, fie n
form de instruciuni INSERT redactate anterior, pe care le introducei n mysql.
Aceast seciune ilustreaz fiecare metod de inserie a nregistrrilor n tabelele dumneavoastr. Ce avei
dumneavoastr de fcut este s v jucai cu diferitele metode, pentru a vedea cum funcioneaz. Apoi, deplasai-
v la sfritul seciunii i rulai comenzile pe care le gsii acolo pentru a terge coninutul tabelelor si pentru a le
rencrca. Astfel, v vei asigura c tabelele conin aceleai nregistrri la care am lucrat cnd am scris seciunea
urmtoare, iar dumneavoastr vei obine aceleai rezultate.
S ncepem s adugm rezultate folosind INSERT, o instruciune SQL pentru care specificai tabelul n care
dorii s inserai un rnd de date i valorile care vor fi plasate n rndul respectiv.
Instruciunea INSERT are mai multe forme:
Putei specifica valori pentru toate coloanele:
INSERT INTO nume_tabel VALUES(valoare1,valoare2,...) De exemplu:
mysql> INSERT INTO elev VALUES('Minai1,'M1,NULL);
mysql> INSERT INTO eveniment VALUESC11999-9-3","C",NULL); Cuvntul INTO este opional ncepnd de
la MySQL 3.22.5. (Acest lucru este valabil si pentru celelalte forme ale instruciunii INSERT.) Lista VALUES
trebuie s conin o valoare pentru fiecare coloan din tabel, n ordinea n care sunt stocate coloanele n tabel, (n
mod normal, aceasta este ordinea n care au fost specificate coloanele la crearea tabelului. Folosii DESCRIBE
nume_tabel pentru a afla ordinea, dac nu o cunoatei cu exactitate.)
Putei ncadra ntre ghilimele valorile de tip ir i dat n MySQL, folosind ghilimele simple sau duble. Valorile
NULL din exemplul precedent sunt destinate coloanelor AUTO_INCREMENT din tabelele elev si eveniment.
(Inseria unei valori lips" determin generarea urmtorului numr elev_id sau eveniment_id.)
Versiunile MySQL ncepnd de la 3.22.5 v permit s inserai mai multe rnduri ntr-un tabel cu o singur
instruciune INSERT, prin specificarea mai multor liste de valori: INSERT INTO nume_tabel VALUES(...),
(...),...
Capitolul 1 Introducere n MySQL i SQL
61
De exemplu: mysql> INSERT INTO elev VALUES('Ana1,'F1,NULL),("Mihai',"M",NULL);
Acest procedeu necesit introducerea de la tastatur a unei cantiti mai reduse de text dect cea impus de mai
multe instruciuni INSERT, iar execuia sa de ctre server este mai eficient.
Putei denumi coloanele crora dorii s le atribuii valori, apoi enumerai valorile. Acest procedeu este util
cnd dorii s creai o nregistrare pentru care numai cteva coloane trebuie configurate iniial.
INSERT INTO nume_tabel (nume_col1 ,nume_col2,...) VALUES(valoare7,valoare2,...) De exemplu:
mysql> INSERT INTO membru (nume,prenume) VALUES('Tache','tefan'); De la MySQL 3.22.5, aceast
form a instruciunii INSERT permite de asemenea mai multe liste cu valori:
mysql> INSERT INTO elev (nume,sex) VALUES('Ana1,'F'),("Mihai","M"); Coloanele care nu sunt specificate
n lista de coloane primesc o valoare prestabilit.
De la MySQL 3.22.10, putei denumi coloanele i valorile sub forma nume_coloana=valoare.
INSERT INTO nume_tabel SET nume_col1=valoare1, nume_co!2=valoare2,... De exemplu:
mysql> INSERT INTO membru SET nume='Tache',prenume='tefan'; Toate coloanele care nu sunt specificate n
clauza SET primesc o valoare prestabilit. Nu putei insera mai multe rnduri folosind aceast form a
instruciunii INSERT.
O alt metod pentru ncrcarea nregistrrilor ntr-un tabel este citirea valorilor datelor direct dintr-un fiier.
Putei ncrca nregistrri n acest mod cu ajutorul instruciunii LOAD DATA sau cu utilitarul mysqlimport.
Instruciunea LOAD DATA se comport ca un ncrctor de mare capacitate, care citete date dintr-un fiier.
Folosii aceast instruciune din interiorul programului mysql:
mysql> LOAD DATA LOCAL INFILE "membru.txt" INTO TABLE membru; Aceast instruciune citete
coninutul fiierului de date membru. txt localizat n catalogul dumneavoastr curent din gazda programului
client i o trimite serverului, pentru a fi ncrcat n tabelul membru.
LOAD DATA LOCAL nu va avea efect dac versiunea dumneavoastr de MySQL este anterioar versiunii
3.22.15, deoarece posibilitatea de citire a fiierelor de la client a fost adugat la instruciunea LOAD DATA
ncepnd de la versiunea respectiv. (Fr cuvntul cheie LOCAL, fiierul trebuie localizat pe gazda serverului si
dumneavoastr avei nevoie de un privilegiu de acces la server, de care majoritatea utilizatorilor MySQL nu
dispun.)
n mod prestabilit, instruciunea LOAD DATA presupune c valorile coloanelor sunt separate prin tabulator! i c
rndurile se ncheie cu un caracter linie nou. De asemenea, presupune c valorile exist n ordinea n care
coloanele sunt stocate n tabel. Este posibil citirea fiierelor n alte formate sau specificarea unei alte ordini a
coloanelor. Vezi rubrica aferent comenzii LOAD DATA din Anexa D, Referin de sintax SQL", pentru mai
multe detalii.
62 Partea l Utilizarea general a sistemului MySQL
Utilitarul mysqlimport este o interfa n linie de comand pentru instruciunea LOAD DATA. Acest utilitar se
invoc din interpretor i genereaz automat o instruciune LOAD DATA:
% mysqlimport --local sarap_db nembru.txt
mysqlimport genereaz automat o instruciune LOAD DATA, care determin ncrcarea fiierului membru. txt n
tabelul membru. Acest lucru nu este posibil dac programul dumneavoastr MySQL este anterior versiunii
3.22.15, deoarece opiunea --local necesit LOAD DATA LOCAL. Ca si n cazul programului mysql, dac
trebuie s specificai parametri de conexiune, indicai-i n linia de comand, anterior numelui bazei de date.
mysqlimport extrage numele tabelului din numele fiierului de date. (Ca nume al tabelului, se folosesc toate
caracterele, pn la primul punct din numele fiierului.) De exemplu, membru.txt va fi ncrcat n tabelul
membru, iar presedinte.txt va fi ncrcat n tabelul preedinte. Dac avei mai multe fiiere de ncrcat ntr-un
singur tabel, alegei numele fiierelor cu atenie; n caz contrar, mysqlimport nu va folosi numele corect de tabel.
Cu nume ca membrul .txt sau membru2.txt, mysqlimport va presupune c numele tabelelor sunt membrul,
respectiv membru2. Totui, putei folosi nume precum membru. 1 .txt i membru.2.txt, respectiv membru.txt! i
membru.txt2.
Dup ce ai testat aceste metode de adugare a nregistrrilor, trebuie s tergei coninutul tabelelor i apoi s le
rencrcai, astfel nct coninutul lor s fie cel presupus n seciunea urmtoare.
Din interpretorul dumneavoastr, executai urmtoarele comenzi:
% ntysql sarap_db < insert_president.sql
% mysql samp_db < insertjnember.sql
% mysql samp_db < insert_student.sql
% mysql samp_db < insert_score.sql
% mysql samp_db < insert_event.sql
% mysql samp_db < insert_absence.sql
Fiecare fiier conine o instruciune DELETE pentru tergerea tuturor nregistrrilor pe care le-ai inserat n tabel,
urmat de un set de comenzi INSERT pentru reiniializarea coninutului tabelului. Dac nu dorii s scriei
fiecare din aceste comenzi n parte, ncercai urmtoarea comand:
% cat insert_*.sql | mysql samp_db
Regsirea informaiilor
Acum, tabelele noastre au fost create i ncrcate cu date, deci haidei s vedem ce putem face cu acele date.
Instruciunea SELECT v permite s regsii si s afiai informaii din tabelele dumneavoastr, ntr-o manier
orict de general sau de specific dorii. Putei afia ntregul coninut al unui tabel:
SELECT * FROM preedinte Sau putei selecta o singur coloan a unui singur rnd:
SELECT data_nastere FROM preedinte WHERE nume = "Eisenhower"
Capitolul 1 Introducere n MySQL i SQL
63
Instruciunea SELECT are numeroase clauze (pri) pe care le combinai conform necesitilor pentru a regsi
informaia care v intereseaz. Fiecare dintre aceste clauze poate fi simpl sau complex, deci instruciunile
SELECT n totalitatea lor pot fi simple sau complexe. Totui, putei sta linitit; nu vei gsi n aceast carte
interogri lungi de o pagin, pentru care avei nevoie de o or pentru a le pricepe. (Cnd gsesc ntr-un material
interogri lungi de-un cot, n general le omit fr mustrri de contiin si bnuiesc c si dumneavoastr
procedai la fel.)
Forma general a instruciunii SELECT este:
SELECT ce se selecteaz
FROM tabel sau tabele
WHERE condiii pe care trebuie sa le satisfac datele
Nu uitai c SQL este un limbaj cu "format liber; deci, cnd v scriei propriile dumneavoastr interogri
SELECT, nu este necesar s inserai salturile la linie nou acolo unde le-am inserat eu.
Pentru a scrie o instruciune SELECT, specificai ce anume dorii s regsii i apoi unele clauze opionale.
Clauzele prezentate mai sus (FROM, WHERE) sunt cel mai frecvent folosite, dei mai pot fi specificate si altele,
cum sunt GROUP BY, ORDER BY si LIMIT.
Clauza FROM este de regul prezent, dar acest lucru nu este necesar dac nu selectai date din tabele. De
exemplu, interogarea urmtoare afieaz pur si simplu valorile unor expresii care pot fi calculate fr referire la
vreun tabel, deci nu este necesar nici o clauz FROM:
mysql> SELECT 2+2, "Salut, lume', VERSION();
2+2 i Salut, lume j VERSION()
4 j Salut, lume i 3.23.0'-alpha-log
Cnd folosii o clauz FROM pentru a specifica un tabel de unde vor fi regsite datele, forma cea mai generic"
a instruciunii SELECT este aceea prin care se regsesc toate datele. Pentru aceasta, folosii caracterul *, care
este o abreviere de la toate coloanele". Interogarea urmtoare regsete toate rndurile din tabelul elev si le
afieaz: mysql> SELECT * FROM elev;
nume sex elev_id
Megan F 1
Joseph M 2
Kyle M 3
Katie p 4

Coloanele sunt returnate n ordinea n care MySQL le-a stocat n tabel. Aceasta este ordinea n care coloanele
sunt afiate atunci cnd se emite o instruciune DESCRIBE elev. Punctele de suspensie de la sfritul exemplului
arat c interogarea returneaz mai multe rnduri dect cele prezentate.
Putei denumi n mod explicit coloana sau coloanele pe care dorii s le vedei. Pentru a selecta numai numele
elevilor, procedai astfel:
64 Partea l Utilizarea general a sistemului MySQL
mysql> SELECT nume FROM elev;
nume
Megan Joseph Kyle Katie
Dac precizai mai mult de o coloan, separai numele coloanelor prin virgule. Instruciunea urmtoare este
echivalent cu SELECT * FROM elev, dar fiecare coloan este specificat n mod explicit:
mysql> SELECT nume,sex,elev_id FROM elev;
nume sex elev_id
Megan F 1
Joseph M 2
Kyle M 3
Katie F 4

Putei denumi coloanele n orice ordine:


SELECT nume,elev_id FROM elev
SELECT elev_id,nume FROM elev
Putei chiar specifica o coloan de mai multe ori, dac dorii, dei acest lucru este, n general, inutil.
Numele coloanelor nu sesizeaz diferena ntre majuscule si minuscule n MySQL. Urmtoarele interogri sunt
echivalente:
SELECT nume,elev_id FROM elev
SELECT NUME,ELEV_ID FROM elev
SELECT nUinE, eLeV_iD FROM elev
Numele bazelor de date i ale tabelelor pot sesiza diferena ntre majuscule i minuscule; depinde de sistemul de
fiiere folosit pe gazda serverului. Un server care ruleaz n UNIX trateaz numele tabelelor i ale bazelor de
date ca sensibile la diferena ntre majuscule i minuscule, deoarece numele de fiiere UNIX sunt sensibile la
aceast diferen. Numele de fiiere Windows nu sesizeaz aceast diferen, deci un server care ruleaz n
Windows nu va trata numele tabelelor i ale bazelor de date ca sensibile la diferena dintre majuscule i
minuscule.
MySQL va permite s selectai coloane din mai multe tabele simultan. Vom discuta despre aceasta n seciunea
Regsirea informaiilor din mai multe tabele".
Specificarea criteriilor de regsire
Pentru a limita setul de nregistrri regsite de instruciunea SELECT, folosii o clauz WHERE care specific
criteriile pentru selectarea rndurilor. Putei selecta rnduri examinnd acele valori din coloane care satisfac
diverse criterii.
Capitolul 1 Introducere n MySQL i SQL
65
Putei cuta valori numerice:
mysql> SELECT * FROM puncte WHERE puncte > 95;
elev_id eveniment_id puncte
5 3 97
18 3 96
1 6 100
5 6 97
11 6 98
16 6 98
Alternativ, putei cuta valori ir. (Reinei: comparaiile ntre iruri nu sunt, n mod normal, sensibile la diferena
ntre majuscule si minuscule.) mysql> SELECT nune, prenume FROM preedinte -> WHERE
nume="ROOSEVELT";
prenume nume
Roosevelt Theodore Roosevelt Franklin D.
mysql> SELECT nume, prenume FROM preedinte -> WHERE nume="roosevelt";
prenume nume
Roosevelt Theodore Roosevelt Franklin D.
Sau putei cuta valori ale unor date calendaristice:
mysql> SELECT nume, prenume, data_nastere FROM preedinte -> WHERE data_nastere < "1750-1-1";
nume prenume data_nastere
Washington George 1732-02-22 Adams John 1735-10-30
Jefferson Thomas 1743-04-13
Sau putei cuta o combinaie de valori:
mysql> SELECT nume, prenume, data_nastere, stat FROM preedinte
-> WHERE data_nastere < "1750-1-1" AND (stat="VA" OR stat="M");
nume prenume data_nastere stat
Washington George 1732-02-22 VA
Adams John 1735-10-30 M
Jefferson Thomas 1743-04-13 VA
Expresiile din clauzele WHERE pot folosi operatori aritmetici, ca n tabelul 1.1, operatori de comparaie, ca n
tabelul 1.2, respectiv operatori logici, ca n tabelul 1.3. De asemenea, putei folosi paranteze pentru a grupa pri
ale unei expresii. Operaiile pot fi efectuate folosind constante, coloane de tabel i apeluri la funcii. Vom avea
ocazia de a folosi numeroase funcii MySQL n interogri pe parcursul acestui manual, dar ele sunt
66
Partea l Utilizarea general a sistemului MySQL
mult prea numeroase pentru a le prezenta aici. Vezi Anexa C, Referin de operatori i funcii", pentru o list
complet.
Tabelul 1.1 Operatori aritmetici
Operator
Semnificaie
Adunare Scdere nmulire mprire
Tabelul 1.2 Operatori de comparaie
Operator
<
<=
!= sau <> >=
Semnificaie
Mai mic
Mai mic sau egal
Egal
Diferit
Mai mare sau egal
Mai mare
Tabelul 1.3 Operatori logici
Operator
AND
OR
NOT
Semnificaie
l logic SAU logic Negaie logic
Cnd formulai o interogare care necesit operatori logici, fii atent s nu confundai semnificaia operatorului
logic AND cu modul n care folosim cuvntul si" n vorbirea zilnic. S presupunem c dorii s gsii
preedinii nscui n statul Virginia i preedinii nscui n statul Massachusetts". Observai modul de utilizare
a lui si"; nseamn aceasta c vei scrie interogarea dup cum urmeaz?:
SELECT nume, prenume, stat FROM preedinte
WHERE Stat="VA" AND Stat="MA"
Nu, deoarece aceast interogare nseamn selecteaz preedinii nscui att n Virginia, ct si n
Massachusetts", ceea este lipsit de sens. n limbajul uzual putei exprima interogarea folosind cuvntul i", dar
n SQL cele dou condiii se leag folosind OR (sau):
mysql> SELECT nume, prenume, stat FROM preedinte -> WHERE stat="VA" OR stat="MA";
Capitolul 1 Introducere n MySQL i SQL
67

nume prenume stat


Washington George VA
Adams John MA
Jefferson Thomas VA
Madison James VA
Monroe James VA
Adams John Quincy MA
Harrison William H. VA
Tyler John VA
Taylor Zachary VA
Wilson Wood row VA
Kennedy John F M
Bush George W. M
Acesta este un aspect la care trebuie s fii atent, nu numai cnd v formulai propriile dumneavoastr interogri,
dar si cnd scriei interogri pentru alte persoane. Cel mai bine este s ascultai cu atenie ce anume doresc s
afle acestea, dar nu este necesar s le transcriei descrierile n SQL folosind aceiai operatori logici. Pentru
exemplul descris anterior, echivalentul n limba vorbit al interogrii este Selecteaz preedinii care s-au nscut
n Virginia sau Massachusetts."
Valoarea NULL
Valoarea NULL este special; deoarece nseamn fr valoare", nu o putei compara cu valori cunoscute n
modul n care comparai una cu alta dou valori cunoscute. Dac ncercai s folosii NULL cu operatorii uzuali
de comparaie aritmetic, rezultatul este nedefinit:
mysql> SELECT NULL < O, NULL = O, NULL != O, NULL > 0;
NUL < 0 NUL = 0 NUL 1= 0 NUL > 0
L L L L
NUL NUL NUL NUL
L L L L
De fapt, nu putei compara NULL nici mcar cu sine nsui, deoarece rezultatul comparaiei ntre dou valori
necunoscute nu poate fi cunoscut: mysql> SELECT NULL = NULL, NULL!= NULL;
NULL = NULL NULL != NULL NULL NULL
Pentru a efectua cutri ale valorilor NULL, trebuie s folosii o sintax special, n loc de a folosi = sau ! =
pentru a testa egalitatea sau inegalitatea, folosii IS NULL sau IS NOT NULL.
De exemplu, deoarece am reprezentat data decesului pentru preedinii aflai n via sub forma NULL, le putem
gsi dup cum urmeaz:
mysql> SELECT nune, prenune, FROM preedinte -> WHERE data_deces IS NULL;
68 Partea l Utilizarea general a sistemului MySQL
nume prenume
Ford Gerald R
Carter James E.
Reagan Ronald W.
Bush George W.
Clinton William J.
Pentru a gsi numele care au un sufix, folosii IS NOT NULL: mysql> SELECT nume, prenume, sufix FROM
preedinte -> WHERE sufix IS NOT NULL;
nume prenume i sufix
Carter James E. j Jr.
MySQL 3.23 i versiunile superioare au un operator de comparaie special, specific programului MySQL, si
anume <=>, care este adevrat chiar si pentru comparaiile ntre valori NULL. Cele dou interogri precedente
pot fi re-scrise folosind acest operator dup cum urmeaz:
mysql> SELECT nume, prenume, FROM preedinte -> WHERE data_deces <=> NULL;
nume prenume
Ford Gerald R
Carter James E.
Reagan Ronald W.
Bush George W.
Clinton William J.
mysql> SELECT nume, prenume, sufix FROM preedinte -> WHERE NOT (sufix <=> NULL);
; nume i prenume sufix >.......................-,.......................................
i Carter i James E. Jr.
Sortarea rezultatelor unei interogri
Uneori se observ c, dac se emite o interogare SELECT * FROM numejtabel asupra unui tabel dup
ncrcarea n tabel a unui set iniial de date, rndurile sunt regsite n aceeai ordine n care au fost inserate.
Acest fapt nu este ntotdeauna adevrat. Dac tergei i inserai rnduri dup ncrcarea iniial a tabelului, se
observ modificarea ordinii n care serverul returneaz rndurile tabelului. (Prin tergerea nregistrrilor, n tabel
sunt inserate goluri" de spaiu nefolosit, goluri pe care MySQL ncearc s le umple ulterior, cnd inserai
nregistrri noi.)
n mod prestabilit, cnd inserai rnduri, serverul nu garanteaz ordinea n care vor fi returnate rndurile. Pentru
a sorta rndurile, folosii o clauz ORDER BY: mysql> SELECT nume, prenume FROM preedinte -> ORDER
BY nume;
Capitolul 1 Introducere n MySQL i SQL
69
nume prenume
Adams John
Adams John Quincy
Arthur Chester A.
Buchanan James

Putei specifica dac sortarea unei coloane se va face n ordine ascendent sau descendent folosind cuvintele
cheie ASG sau DESC dup numele coloanelor din clauza ORDER BY. De exemplu, pentru a sorta numele
preedinilor n ordine invers (descresctoare), folosii DESC astfel:
mysql> SELECT nune, prenume FROM preedinte -> ORDER BY nume DESC;
nume prenume
Wilson Wood row
Washington George
Van Buren Martin
Tyler John

Ordinea ascendent este cea prestabilit dac nu specificai ASC sau DESC pentru un nume de coloan ntr-o
clauz ORDER BY.
Dac sortai o coloan care poate conine valori NULL, toate valorile NULL apar la nceputul coloanei, respectiv
la sfrit, dac sortai n ordine descendent.
Rezultatele interogrii pot fi sortate pe mai multe coloane, iar fiecare coloan poate fi sortat n ordine
ascendent sau descendent, independent de celelalte coloane. Interogarea urmtoare regsete rnduri din
tabelul preedinte, le sorteaz n sens descendent n funcie de statul de natere i dup numele de familie n
cadrul fiecrui stat: mysql> SELECT nume, prenume, stat FROM preedinte -> ORDER BY stat DESC, nume
ASC;
nume prenume stat
Arthur Chester A. VT
Coolidge Calvin VT
Harrison William H. VA
Jefferson Thomas VA
Madison James VA
Monroe James VA
Taylor Zachary VA
Tyler John VA
Washington George VA
Wilson Woodrow VA
Eisenhower Dwight D. TX
Johnson Lyndon B. TX

70 Partea l Utilizarea general a sistemului MySQL


Limitarea rezultatelor unei interogri
Cnd o interogare returneaz mai multe rnduri, dar dumneavoastr dorii s vedei numai cteva, clauza LIMIT
este util, mai ales n conjuncie cu ORDER BY. MySQL v permite s limitai datele de ieire ale unei
interogri la primele n rnduri ale rezultatului returnat. Interogarea urmtoare selecteaz pe primii cinci nscui
preedini americani: mysql> SELECT nume, prenune, data_nastere FROM preedinte -> ORDER BY
data_nastere LIMIT 5;
nume
Washington
Adams
Jefferson
Madison
Monroe
prenume
George
John
Thomas
James
James
data natere
1732-02-22 1735-10-30 1743-04-13 1751-03-16 1758-04-28
Dac sortai n ordine invers, folosind ORDER BY datajiastere DESC, vei obine pe ultimii cinci nscui
preedini americani.
De asemenea, LIMIT v permite s extrageri o seciune de nregistrri din mijlocul unui set de rezultate. Pentru
aceasta, trebuie s specificai dou valori. Prima valoare este numrul nregistrrii iniiale din setul de rezultate
pe care dorii s-1 vedei. (Prima nregistrare este numerotat cu O, nu 1.) Cea de-a doua valoare indic numrul
de nregistrri care vor fi returnate. Interogarea urmtoare este similar cu precedenta, dar returneaz cinci
nregistrri, ncepnd de la al unsprezecelea rnd al rezultatului: mysql> SELECT nume, prenune, data_nastere
FROM preedinte -> ORDER BY data_nastere LIMIT 10,5;
nume prenume datajiastere
Tyler John 1790-03-29
Buchanan James 1791-04-23
Polk James K. 1795-11-02
Fillmore Miliard 1800-01-07
Pierce Franklin 1804-11-23
ncepnd cu MySQL versiunea 3.23.2, putei ordona rezultatele interogrilor n funcie de o formul. De
exemplu, pentru a extrage o nregistrare selectat aleator din tabelul preedinte, folosii ORDER BY RAND() n
conjuncie cu LIMIT: mysql> SELECT nume, prenume FROM preedinte -> ORDER BY RAND() LIMIT
1;
nume prenume
McKinley William
Capitolul 1 Introducere n MySQL i SQL
71
Calculul i denumirea valorilor din coloanele de ieire
Majoritatea interogrilor precedente au produs date de ieire prin regsirea valorilor din tabele. MySQL v mai
permite s calculai o valoare din coloana de ieire ca rezultat al unei expresii. Expresiile pot fi simple sau
complexe. Interogarea urmtoare evalueaz o expresie simpl (o constant) i o expresie mai complex, care
implic numeroase operaii aritmetice si cteva apeluri la funcii:
mysql> SELECT 17, FORMAT(SORT(3*3+4*4),0);
17 FORMAT(SQRT(3*3+4*4),0) 17 5
De asemenea, expresiile se pot referi la coloanele din tabele: mysql> SELECT CONCAT(prenume,"
",nume),CONCAT(oras, -> FROM preedinte;
',stat)
CONCAT ( prenume , , nume) i CONCAT (ora," , ",stat)
""
George Washington iwakefield, VA iBraintree, M
John Adams Thomas iAlbemarle County, VA j Port
Jefferson James Conway, VA
Madison

Aceast interogare formateaz numele preedinilor sub forma unui singur ir, prin concatenarea numelui si a
prenumelui separate printr-un spaiu i formateaz locul naterii sub forma oraelor i statelor separate prin
virgul.
Cnd folosii o expresie pentru a calcula valoarea unei coloane, expresia este folosit pentru antetul coloanei.
Aceasta poate duce la o coloan foarte lat, dac expresia este lung (aa cum o arat interogarea precedent).
Pentru a rezolva problema, capului de coloan i se poate atribui un nume, folosind construcia AS nume.
Asemenea nume se numesc aliasuri de coloan. Rezultatul interogrii anterioare poate deveni astfel mai
semnificativ:
mysql> SELECT CONCAT(prenume," ",nuBe), AS Nume,
-> CONCAT(ora,', ",stat) As Loculnasterii
-> FROM preedinte;
Nume i Loculnasterii

George Washington John iwakefield, VA JBraintree,


Adams Thomas Jefferson M iAlbemarle County, i VA
James Madison Port Conway, VA

n cazul n care aliasul coloanei conine spaii, acestea vor trebui inserate ntre ghilimele: mysql> SELECT
CONCAT(prenume," *,nune), AS 'Nunele preedintelui* -> CONCAT(oras,", ",stat) As "Locul naterii" ->
FROM preedinte;
72 Partea 1 Utilizarea general a sistemului MySQL

Numele preedintelui Locul naterii


George Washington John jWakefield, VA JBraintree, M
Adams Thomas Jefferson jAlbemarle County, VA jPort
James Madison Conway, VA

Lucrul cu date calendaristice


Principalul aspect pe care trebuie s-1 reinei atunci cnd lucrai cu date n MySQL este c acestea sunt
ntotdeauna reprezentate ncepnd cu anul. Data de 27 iulie 1999 este reprezentat sub forma '1999-07-27".
Datele nu se scriu nici sub forma "07-27-1999" i nici sub forma "27-07-1999", aa cum poate c erai obinuit
s le scriei.
MySQL ofer numeroase moduri de efectuare a operaiilor cu date. Unele dintre acestea sunt urmtoarele:
Sortare dup dat. (Deja am vzut aceast operaie de mai multe ori.)
Cutarea unei anumite date sau a unui domeniu de date.
Extragerea unei pri dintr-o valoare de tip dat, precum anul, luna sau ziua.
Calcularea diferenei ntre date.
Calcularea unei date prin adunarea sau scderea unui interval dintr-o alt dat. n continuare sunt prezentate
exemple cu aceste operaii.
Pentru a cuta anumite date, fie n funcie de valoarea exact, fie prin comparaie cu o alt valoare, comparai o
coloan DATA cu valoarea care v intereseaz: mysql> SELECT * FROM eveniment WHERE data="1999-10-
01";
data tip eveniment_id
1999-10-01 T 6
mysql> SELECT nume, prenume, data_deces -> FROM preedinte -> WHERE data_deces >= '1970-01-01'
AMD data_deces < '1980-01-01';
nume prenume data_deces
Truman Harry S. 1972-12-26
Johnson Lyndon B. 1973-01-22
Pentru a testa sau pentru a regsi pri ale datelor calendaristice, putei folosi funcii precum YEAR () (an),
MONTH () (lun) sau DAYOFMONTH() (ziua din lun). De exemplu, pot gsi preedinii care s-au nscut n
aceeai lun ca mine (martie) cutnd datele a cror valoare a lunii este egal cu 3:
mysql> SELECT nume, prenume, data_nastere
-> FROM preedinte WHERE MONTH(data_nastere) = 3;
Capitolul 1 Introducere n MySQL i SQL
73
nume prenume data_nastere
Madison James 1751-03-16
Jackson Andrew 1767-03-15
Tyler John 1790-03-29
Cleveland Grover 1837-03-18
De asemenea, interogarea poate fi scris i n funcie de numele lunii: mysql> SELECT nune, prenume,
data_nastere -> FROM preedinte -> WHERE MONTHNAME(data_nastere) = "March";
...........................................:...........................
nume prenume data_nastere
Madison James 1751-03-16
Jackson Andrew 1767-03-15
Tyler John 1790-03-29
Cleveland Grover 1837-03-18
Pentru a fi mai exact - specificnd chiar ziua naterii - pot combina interogrile pentru MONTH () i
DAYOFMONTH () pentru a gsi preedinii nscui n ziua mea de natere: mysql> SELECT nune, prenume,
data_nastere
-> FROM preedinte WHERE MOHTH(data_nastere) = 3
-> AND DAYOFMONTH(data_nastere) = 29;
l nume ! prenume ; data_nastere
j Tyler j John i 1790-03-29
Acesta este tipul de interogare pe care l folosii pentru a genera liste cu persoanele nscute ntr-o anumit zi,
list pe care o vedei n seciunea de divertisment a ziarelor. Totui, nu trebuie s scriei o anumit zi, aa cum s-a
procedat n interogarea anterioar. Pentru a cuta preedinii nscui astzi, indiferent de ziua din an n care ne
gsim, comparai data naterii lor cu valoarea CURRENT_DATE (dat curent):
SELECT nume, prenume, data_nastere
FROM preedinte WHERE MONTH(data_nastere) = MONTH(CURRENT_DATE)
ANO DAYOFMONTH(data_nastere) = DAYOFMONTH(CURRENT_DATE)
Putei scdea o dat dintr-o alt dat. Aceasta v permite s gsii intervalul dintre date, care este util pentru
determinarea vrstelor. De exemplu, pentru a determina preedintele care a trit cel mai mult, se scade data
naterii din data decesului. Pentru aceasta, convertii data_nastere si data_deces n zile folosind funcia
TO_DAYS(), luai diferena si o mprii la 365 pentru a obine vrsta aproximativ, n ani:
mysql> SELECT nume, prenume, data_nastere, data_deces,
-> FLOOR((TO_DAYS(data_deces) - TO_DAYS(data_nastere))/365 -> AS vrsta FROM preedinte WHERE
data_deces IS NOT NULL -> ORDER BY vrsta DESC LIMIT 5;
74 Partea l Utilizarea general a sistemului MySQL
nume prenume data_nastere data_deces vrsta
Adams John 1735-10-30 1826-07-04 90
Hoover Herbert C. 1874-08-10 1964-10-20 90
Truman Harry S. 1884-05-08 1972-12-26 88
Madison James 1751-03-16 1836-06-28 85
Jefferson Thomas 1743-04-13 1826-07-04 83
Funcia FLOOR () folosit n aceast interogare elimin toate prile fracionare din valoarea vrstei, pentru a
genera un ntreg.
Stabilirea diferenei ntre date este de asemenea util pentru determinarea distanei n raport cu o anumit dat de
referin. Astfel, v putei da seama care sunt membrii Ligii istorice care trebuie s-i plteasc n curnd
cotizaia. Calculai diferena ntre datele de expirare i data curent, iar dac aceasta este mai mic dect o
anumit valoare de prag, nseamn c plata cotizaiei va fi n curnd necesar. Urmtoarea interogare i gsete
pe membrii care trebuie s-i achite cotizaia n termen de 60 de zile: SELECT nume j prenume, data_expirare
FROM membru WHERE (TO_DAYS(data_expirare) - TO_DAYS(CURRENT_DATE)) < 60 ncepnd de la
MySQL 3.22, putei folosi DATE_ADD() sau DATE_SUB() pentru a calcula o dat pornind de la alta. Aceste
funcii preiau o dat si un interval si produc o dat nou. De exemplu:
mysql> SELECT DATE_ADD("1970-1-1", INTERVAL 10 YEAR);
DATE_ADD("1970-1-1", INTERVAL 10 YEAR) 1980-01-01
mysql> SELECT DATE_SUB("1970-1-1", INTERVAL 10 YEAR);
DATE_SUB("1970-1-1", INTERVAL 10 YEAR)
1960-01-01
O interogare prezentat anterior n aceast seciune selecta preedinii care au decedat n timpul anilor '70,
folosind date literale pentru extremitile domeniului de selecie. Acea interogare poate fi reformulat folosind o
dat de pornire literal i o dat final calculat pe baza datei de pornire i a unui interval: mysql> SELECT
nume, prenume, data_deces
-> FROM preedinte
-> WHERE data_deces >= "1970-1-1"
-> AND data_deces < DATE_ADD("1970-1-1", INTERVAL 10 YEAR)
nume prenume data_deces
Truman Harry S. 1972-12-26
Johnson Lyndon B. 1973-01-22
Interogarea pentru plata cotizaiei membrilor poate fi scris folosind DATE_ADD(): SELECT nume, prenume,
data_expirare FROM membru WHERE data_expirare < DATE_ADD(CURRENT_DATE, INTERVAL 60
DAY)
Capitolul 1 Introducere n MySQL i SQL
75
Anterior n acest capitol, a fost prezentat o interogare pentru determinarea pacienilor unui medic stomatolog
care nu s-au mai prezentat la control n ultimul timp: SELECT nume, prenume, ultima_vizita FROM pacient
WHERE ultima_vizita < DATE_SUB(CURRENT_DATE, INTERVAL 6 MONTH) n acel moment,
interogarea respectiv nu era prea semnificativ. Acum este?
Stabilirea corespondenei cu un model
MySQL v permite s cutai valori care corespund unui anumit model. Astfel, putei selecta nregistrri fr a
furniza o valoare exact. Pentru a executa o operaie de stabilire a corespondenei cu un model, folosii operatori
speciali (LIKE si NOT LIKE) i specificai un ir care conine caractere de nlocuire. Caracterul _ corespunde
oricrui caracter, iar % corespunde oricrei secvene de caractere (inclusiv o secven vid). Stabilirea
corespondenei cu un model folosind LIKE i NOT LIKE nu face diferena ntre majuscule i minuscule.
Acest model gsete numele care ncep cu W (sau cu w, dac ar exista): mysql> SELECT nume, prenume
FROM preedinte -> WHERE nume LIKE "WV;
nume prenume
Washington George
Wilson Woodrow
Aceast coresponden cu un model este eronat:
mysql> SELECT nume, prenume FROM preedinte -> WHERE nune = "WV;
Empty set (0.00 sec)
Interogarea ilustreaz o eroare comun, i anume folosirea unui model cu un operator aritmetic de comparaie.
Unica posibilitate ca aceast operaie s reueasc este ca n coloan s se afle chiar irul "WV sau "wV.
Acest model corespunde numelor de familie care conin litera W sau w oriunde n interiorul numelui:
mysql> SELECT nume, prenume FROM preedinte -> WHERE nume LIKE "%WV;
nume prenume
Washington George
Wilson Woodrow
Eisenhower Dwight D.
Acest model corespunde numelor de familie care conin exact patru caractere: mysql> SELECT nume, prenume
FROM preedinte -> WHERE nume LIKE '____";
nume prenume
Polk Taft Ford James K.
Bush William H.
Gerald R.
George W.
76 Partea l Utilizarea general a sistemului MySQL
De asemenea, MySQL furnizeaz o alt metod de stabilire a corespondenei cu un model, n funcie de
expresiile regulate extinse. Expresiile regulate sunt prezentate n descrierea operatorului REGEXP din Anexa C.
Generarea de sumare
Una dintre cele mai utile operaii pe care MySQL le poate face pentru dumneavoastr este s rezume mari
cantiti de date brute i s realizeze sumarul acestora. MySQL devine un aliat puternic atunci cnd vei nva
s-1 folosii pentru a genera sumare, deoarece aceasta este o activitate extrem de obositoare, consumatoare de
timp si supusa la erori atunci cnd este efectuat manual.
O form simpl de creare a unui sumar const n a determina valorile unice prezente ntr-un set de valori. Folosii
cuvntul cheie DISTINCT pentru a elimina rndurile care se repet dintr-un rezultat. De exemplu, statele
distincte n care s-au nscut preedinii americani se pot gsi astfel:
mysql> SELECT DISTINCT stat FROM preedinte ORDER BY stat; stat
AR CA GA IA L KY M MO NC NE NH NJ NY OH PA SC TX VA VT
O alt form de realizare a unui sumar este numrarea, folosind funcia COUNT (). Dac folosii COUNT(*),
aceasta v indic numrul de rnduri selectat de interogarea dumneavoastr. Dac interogarea nu are nici o
clauz WHERE, COUNT(*) v indic numrul rndurilor din tabelul dumneavoastr.
Interogarea urmtoare v indic numrul tuturor preedinilor americani: mysql> SELECT COUNT(*) FROM
preedinte;
COUNT(*)i 41 i
Dac o interogare are o clauz WHERE, COUNT(*) indic numrul de rnduri pe care l selecteaz clauza.
Aceast interogare v arat numrul de chestionare pe care le-ai dat elevilor dumneavoastr pn acum:
Capitolul 1 Introducere n MySQL i SQL
77
mysql> SELECT COUNT(*) FROM eveniment WHERE type = 'C';
COUNT(*) 4
Funcia COUNT(*) numr fiecare rnd selectat. Prin contrast, COUNT(nume_coloana) numr numai valorile
diferite de NULL. Urmtoarea interogare demonstreaz aceste diferene:
mysql> SELECT COUNT(*),COUNT(sufix),COUNT(data_deces) -> FROM preedinte;
COUNT(*) i COUNT(sufix) COUNT(datajJeces) i 41 i 1 36 j
Aceast interogare arat c n total au fost 41 de preedini, c numele unui singur preedinte are un sufix,
precum si c majoritatea preedinilor nu mai sunt n via.
ncepnd de la MySQL 3.23.2, putei combina COUNT(*) cu DISTINCT pentru a determina numrul de valori
distincte dintr-un rezultat. De exemplu, pentru a numra statele distincte n care s-au nscut preedinii
americani, procedai astfel: mysql> SELECT COUNT(DISTINCT stat) FROM preedinte;
COUNT(DISTINCT stat)! 19 j
Putei mpri numrtorile n valori individuale n coloana de sumar. De exemplu, putei cunoate numrul total
de elevi de la cursul dumneavoastr ca rezultat al rulrii urmtoarei interogri:
mysql> SELECT COUNT(*) FROM elev;
j COUNT(*)
i 31
Dar ci dintre elevi sunt biei si cte sunt fete? O modalitate de a afla aceast informaie este de a cere o
numrare separat pentru fiecare sex: mysql> SELECT COUNT(*) FROM elev WHERE sex='f;
COUNT(*)| 15 mysql> SELECT COUNT(*) FROM elev WHERE sex=1n1;
COUNT (*)! 16:
..................i
Totui, dei aceast metod funcioneaz, este obositoare i nu foarte bine adaptat pentru coloanele care pot
conine numeroase valori distincte. S ne gndim cum putem determina n acest mod numrul preedinilor
nscui n fiecare stat. Va trebui s aflai care'sunt statele reprezentate, pentru a nu omite nici unul (instruciunea
SELECT DIS-
78 Partea l Utilizarea general a sistemului MySQL
TINCT stat FROM preedinte), apoi rulai o interogare SELECT COUNT(*) pentru fiecare stat. Categoric, nu
dorii s facei acest lucru.
Din fericire, MySQL poate numra, folosind o singur interogare, de cte ori apare fiecare valoare distinct ntr-
o coloan. Pentru lista noastr cu elevi, putem numra bieii i fetele astfel:
mysql> SELECT sex, COUNT(*) FROM elev GROUP BY sex;
sex COUNT(*)
FM 15 16

Aceeai form de interogare indic numrul de preedini nscui n fiecare stat: mysql> SELECT stat,
COUNT(*) FROM preedinte GROUP BY stat;
i stat COUNT(*)
i AR 1
i CA 1
i GA 1
;IA 1
L 1
!KY 1
i M 4
i MO 1
i NC 2
INE 1
;NH 1
IN j 1
iNY 4
i OH 7
i PA 1
jsc 1
;TX 2
i VA 8
iVT 2
Cnd numrau valorile n acest mod, clauza GROUP BY este necesar, deoarece indic programului MySQL
modul de grupare a valorilor nainte de a le numra. Dac omitei aceast clauz, vei primi un mesaj de eroare.
Utilizarea funciei COUNT(*) cu GROUP BY pentru numrarea valorilor are un numr de avantaje n raport cu
numrarea individual a apariiilor fiecrei valori distincte din coloan:
Nu trebuie s tii dinainte care sunt valorile prezente n coloana al crei coninut l rezumai.
Avei nevoie de o singur interogare, nu de mai multe interogri.
Obinei toate rezultatele ntr-o singur interogare, deci putei sorta datele de ieire.
Primele dou avantaje sunt importante pentru exprimarea cu mai mare uurin a interogrilor. Cel de-al treilea
avantaj este important deoarece v permite o flexibilitate n afiarea rezultatelor.
Capitolul 1 Introducere n MySQL i SQL
79
Cnd folosii o clauza GROUP BY, rezultatele sunt sortate n coloanele n funcie de care realizai gruparea, dar
putei folosi ORDER BY pentru a sorta ntr-o alt ordine. De exemplu, dac dorii ca numerele de preedini s
fie grupate n funcie de statul de natere, dar s fie i sortate n ordinea descresctoare a celor mai bine
reprezentate state, putei folosi o clauz ORDER BY dup cum urmeaz:
mysql> SELECT stat, COUNT(*) AS numr FROM preedinte -> GROUP BY stat ORDER BY numr DESC;
istat numr
!VA 8
;OH 7
M 4
;NY 4
INC 2
iVT O
;TX n
isc 1
;NH 1
i PA 1
;KY 1
!NJ 1
i IA 1
i MO 1
:CA 1
i NE 1
;GA 1
;IL 1
IAR 1
Cnd coloana dup care dorii s sortai este determinat prin calcul, putei da coloanei un alias i putei face
referire la alias n clauza ORDER BY. Interogarea anterioar demonstreaz acest fapt; coloana COUNT(*) este
denumit numr. O alt modalitate de a face referire la o asemenea coloan este prin poziia sa n datele de ieire.
Interogarea anterioar ar fi putut fi scris si astfel:
SELECT state, COUNT(*) FROM preedinte
GROUP BY stat ORDER BY 2 DESC
Nu cred c desemnarea unei coloane prin poziia acesteia este foarte sugestiv. Dac adugai, eliminai sau re-
ordonai coloanele cu datele de ieire, trebuie s v amintii s verificai clauza ORDER BY si s corectai
numrul coloanei, dac acesta s-a modificat. Aliasurile nu ridic aceast problem.
Dac dorii s folosii GROUP BY cu o coloan care conine valori calculate, trebuie s facei referire la acea
coloan folosind un alias sau poziia coloanei, aa cum se procedeaz n cazul clauzei ORDER BY. Urmtoarea
interogare determin numrul preedinilor care s-au nscut n fiecare lun a anului:
mysql> SELECT MONTH(data_nastere) as Luna,
-> MONTHNAME(datajiastere) AS Nume, COUNT(*) AS numr -> FROM preedinte GROUP BY Nume
ORDER BY Luna;
80
Partea l Utilizarea general a sistemului MySQL
Luna Nume numr
1 Ianuarie A
2 Februarie 4
3 Martie 4
4 Aprilie 4
5 Mai 2
/ Iunie 1
- Iulie 3
B August 4
9 Septembrie 1
10 Octombrie 6
11 Noiembrie 5
12 Decembrie 3
Folosind poziiile coloanelor, interogarea poate fi scris astfel:
SELECT MONTH(data_nastere), MONTHNAME(data_nastere), COUNT(*) FROM preedinte GROUP BY 2
ORDER BY 1;
COUNTQ poate fi combinat cu ORDER BY i LIMIT pentru a gsi, de exemplu, cele mai
bine reprezentate patru state din tabelul preedinte:
mysql> SELECT stat, COUNT(*) AS nuiar FROM preedinte -> GROUP BY stat ORDER BY numr DESC
LIMIT 4;
i stat numr
i VA i 8
OH 7 4 4
i M
JNY
Dac nu dorii s limitai datele de ieire ale interogrii folosind o clauz LIMIT, ci prin cutarea anumitor valori
ale funciei COUNT(), utilizai o clauz HAVING. Interogarea urmtoare v va indica numrul de state
reprezentate prin doi sau mai muli preedini: mysql> SELECT stat, COUNT(*) AS miiar FROM preedinte
-> GROUP BY stat HAVING nunar > 1 ORDER BY numr DESC;
istat numr
i VA 8
;OH 7
;MA 4
NY 4
;NC 2
iVT 2
TX 2
n general, acesta este tipul de interogare care trebuie executat atunci cnd dorii s gsii ntr-o coloan valori
care se repet.
HAVING este similar cu WHERE, dar se aplic dup ce au fost selectate rezultatele interogrii si este folosit
pentru a reduce domeniul rezultatelor trimise efectiv de server clientului.
Exist funcii de sumar altele dect COUNT (). Funciile MIN (), MAX (), SUM () si AVG () sunt utile pentru
determinarea valorii minime, maxime, totale i medii dintr-o coloan. Le putei chiar
Capitolul 1 Introducere n MySQL i SQL
81
folosi pe toate simultan. Urmtoarea interogare prezint diferite caracteristici numerice pentru fiecare chestionar
i test pe care l-ati dat. De asemenea, indic numrul de punctaje incluse n calculul fiecrei valori. (Unii elevi au
fost abseni i, ca atare, nu au fost numrai.) mysql> SELECT
-> eveniment_id,
-> MIN(puncte) AS minim,
-> MAX(puncte) AS maxim,
-> MAX(puncte)-MIN(puncte)+1 AS domeniu,
-> SUM(puncte) AS total,
-> AVG(puncte) AS medie,
-> COUNT(puncte) AS numr,
-> FROM puncte
-> GROUP BY eveniment_id;
eveniment_id minim maxim domeniu total medie numr
1 9 20 12 439 15.1379 29
2 8 19 12 425 14.1667 30
3 60 97 38 2425 78.2258 31
4 7 20 14 379 14.0370 27
5 8 20 13 383 14.1852 27
6 62 100 39 2325 80.1724 29
Aceste informaii pot deveni mai semnificative dac ai ti, desigur, dac valorile respective au fost obinute la
punctaje sau teste. Totui, pentru a obine acele informaii, trebuie s consultm i tabelul eveniment; vom reveni
la aceast interogare n seciunea Regsirea informaiilor din mai multe tabele".
Funciile de sumar sunt distractive, deoarece sunt foarte puternice, dar v putei lsa foarte uor dus de val".
Privii aceast interogare: mysql> SELECT
-> stat AS Stat,
-> AVG((TO_DAYS(data_deces)-TO_DAYS(data_nastere))/365) AS Vrsta
-> FROM preedinte WHERE data_deces IS NOT NULL
-> GROUP BY state ORDER BY Vrsta;
i stat ! vrsta j ; stat i vrsta i
iKY j 56. 20821 9! !TX 71. 476712
j
;VT ; 58. 852055! :MA ! 72.
642009;
; NC ; 60. 141096! ;VA ! 72.
822945;
;OH ! 62. 8661 !PA ' 77.
45 : 158904;
;NH ! 64. 91 7808! !SC i 78.
284932!
;NY i 69. 342466! ;CA ; 81.
336986!
:NJ ! 71. 31 5068; !MO j 88. 6931
51 !
!IA ! 90.
254795!
Interogarea selecteaz preedinii care au decedat, i grupeaz n funcie de data naterii, le calculeaz vrsta la
data decesului, calculeaz vrsta medie (per stat) i apoi sorteaz rezultatele dup vrsta medie. Cu aljte cuvinte,
interogarea determin, pentru preedinii care nu mai sunt n via, vrsta medie la data decesului n funcie de
statul de natere.
82 Partea l Utilizarea general a sistemului MySQL
i ce nseamn asta? nseamn numai c putei scrie interogarea. Evident, nu nseamn c interogarea merit
scris. Nu toate operaiile pe care le putei aplica unei baze de date sunt la fel de semnificative; totui, uneori
oamenii devin extrem de fericii cnd afl ce anume pot face cu baza lor de date. Astfel se poate explica apariia
unui numr tot mai mare de statistici din ce n ce mai ezoterice (i mai lipsite de sens) cu ocazia evenimentelor
sportive televizate din Statele Unite n ultimii ani. Statisticienii sportivi i pot folosi bazele de date pentru a
determina tot ce dorii s tii despre o echip, dar i tot ce nu dorii s tii. Chiar este att de important s tii
care funda din Divizia A (mutatis mutandis pentru realitatea romneasc - N.T.) are la activ cele mai multe
intercepii n careul de 16 metri atunci cnd echipa lui conduce cu mai mult de dou goluri diferen, cnd pn
la sfritul reprizei a doua sunt mai puin de 15 minute i antrenorul nc n-a fcut cele trei schimbri
regulamentare?
Regsirea informaiilor din mai multe tabele
Interogrile pe care le-am scris pn acum au extras date dintr-un singur tabel. Acum ajungem la partea
interesant. Am mai spus c puterea unui SGBD relaional rezid n capacitatea sa de a corela un aspect cu altul,
deoarece acest fapt v permite s combinai informaii din mai multe tabele pentru a gsi rspunsul la ntrebri la
care nu se poate rspunde consultnd un singur tabel. Aceast seciune v prezint modul de scriere a
interogrilor de regsire a informaiilor din mai multe tabele.
Cnd selectai informaii din mai multe tabele, efectuai o operaie denumit unire. Aceasta deoarece producei
un rezultat prin unirea informaiilor dintr-un tabel cu informaiile din cellalt tabel, operaie care are loc prin
coroborarea nregistrrilor din mai multe tabele care conin valori comune.
S parcurgem un exemplu. Anterior, n seciunea Tabele pentru proiectul de eviden a rezultatelor colare", a
fost prezentat, fr nici o explicaie, o interogare pentru regsirea punctajelor de la chestionare sau teste date la
o anumit dat. Acum este momentul s dm explicaia. De fapt, interogarea implic o unire pe trei ci, deci o
vom descrie n dou etape.
n prima etap, construim o interogare pentru selectarea punctajelor obinute la o anumit dat, dup cum se
poate vedea mai jos: mysql> SELECT elev_id, data, puncte, tip
-> FROM eveniment, puncte
-> WHERE data = '1999-09-23'
-> AND eveniment.eveniraent_id = puncte.eveniment_id;
elev_id data puncte tip
1 1999-09-23 15 c
f\ 1999-09-23 12 C
3 1999-09-23 11 C
5 1999-09-23 13 c
6 1999-09-23 18 c

Capitolul 1 Introducere n MySQL i SQL


83
Aceast interogare funcioneaz prin gsirea nregistrrii evenimentului cu data precizat si apoi folosete
identificatorul de eveniment din acea nregistrare pentru a localiza punctaje cu acelai identificator de eveniment.
Pentru fiecare combinaie corespunztoare de nregistrare de eveniment i nregistrare de punctaj, sunt afiate
identificatorul elevului, punctajul, data i tipul de eveniment. Interogarea difer de cele scrise pn acum din
dou puncte de vedere importante:
Clauza FROM denumete mai multe tabele, deoarece datele sunt regsite din mai multe tabele:
FROM eveniment, puncte
Clauza WHERE precizeaz c tabelele eveniment si puncte sunt unite prin stabilirea unei echivalene ntre
valorile coloanei eveniment_id din fiecare tabel:
WHERE ... eveniment.eveniment_id = puncte.eveniment_id
Observai modul n care se face referire la coloane, folosindu-se sintaxa nume_ta-bel.nume_coloana, astfel nct
MySQL s tie care sunt tabelele n chestiune. (Coloana eveniment_id apare n ambele tabele, deci apare o
situaie echivoc dac o folosim fr un nume de tabel pentru a o identifica.)
Celelalte coloane din interogare (data, puncte, tip) pot fi folosite fr un element de calificare de tip nume de
tabel, deoarece apar ntr-un singur tabel i, ca atare, sunt lipsite de echivoc. Totui, eu n general prefer s calific
fiecare coloan dintr-o unire, pentru a preciza mai clar tabelul din care face parte coloana, ntr-o form complet
determinat, interogarea se prezint astfel:
SELECT puncte.elev_id, eveniment.data, puncte.puncte, eveniment.tip
FROM eveniment, puncte
WHERE eveniment.data = "1999-09-23"
AND eveniment.eveniment_id = puncte.eveniment_id De acum ncolo, voi folosi forma complet determinat.
n cea de-a doua etap, vom finaliza interogarea folosind tabelul elev pentru a afia numele elevilor. (Datele de
ieire ale interogrii din prima etap ne prezint cmpul elev_id, dar numele sunt mai semnificative.) Afiarea
numelor este realizat folosind faptul c att tabelul puncte, ct i tabelul elev conin coloana elev_id, ceea ce
permite corelarea nregistrrilor din aceste tabele. Interogarea rezultant se prezint astfel: mysql> SELECT
elev.nune, eveniment.data, puncte.puncte,
-> eveniment.tip FROM eveniment, puncte, elev
-> WHERE eveniment.data = "1999-09-23"
-> AND eveniment.eveniment_id = puncte.eveniment_id
-> AND puncte.eveniment_id = elev.elev_id;
i nume data puncte tip
; Megan 1999-09-23 15 C
; Joseph 1999-09-23 12 C
; Kyle 1999-09-23 11 C
i Abby 1999-09-23 13 C
j Nathan 1999-09-23 18 C

84 Partea l Utilizarea general a sistemului MySQL


Aceast interogare difer de precedenta din urmtoarele puncte de vedere:
Tabelul elev este adugat la clauza FROM deoarece este folosit alturi de tabelele eveniment i puncte.
Coloana elev_id este acum echivoc, deci trebuie determinat sub forma puncte. elev_id sau elev. elev_id,
pentru preciza clar care este tabelul ce urmeaz a fi folosit. (Acest fapt este valabil chiar dac preferri s
scriei uniri care nu precizeaz complet fiecare referin la o coloan.) -
Clauza WHERE are un termen suplimentar, care arat c nregistrrile din tabelul puncte sunt coroborate cu
nregistrrile din tabelul elev, n funcie de identificatorul fiecrui elev:
WHERE ... puncte.elev_id = elev.elev_id *
Interogarea afieaz numele elevului, nu identificatorul su. (Bineneles c le putei afia pe ambele, dac
dorii.) '
Cu aceast interogare, putei introduce orice dat i obinei punctajele de la data respectiv, alturi de numele
eleyilbr si dttipul punctajului. Nu trebuie s tii nimic despre identificatorii de elev sau de eveniment. MySQL
se ocup de determinarea valorilor relevante ale identificatorilor si de utilizarea lor pentru coroborarea automat
a informaiilor din rndurile tabelelor. >
O alt sarcin pe care o incumb proiectul de eviden a rezultatelor colare este totali-zarea absenelor elevilor.
Absenele sunt nregistrate n tabelul absente, n funcie de identificatorul elevului i de dat. Pentru a obtine
numele elevilor (nu doar identificatorii lor) trebuie s unim tabelul absente cu tabelul elev, n funcie de valoarea
din coloana elev_id. Interogarea urmtoare afieaz numrul de identificare a elevului si numele acestuia, alturi
de numrul absenelor: mysql> SELECT elev.elev_id, elev.num,
-> COUNT(absente.data) AS absente
-> FROM elev, absente
-> WHERE elev.elev_id = absente.elev_id
-> GROUP BY elev.elev_id;
elev_id nume absente

Kyle Abby
3 5 10 17 Peter Will
20 Avery 1211
Not: Dei am furnizat un calificator n clauza GROUP BY, nu este absolut necesar pentru aceast interogare.
GROUP BY se refer la coloanele din lista de selecie (din,primele dou linii ale interogrii). Aici exist o
singur coloan denumit elev_id, deci MySQL cunoate coloana la care v referii. Acest fapt este de asemenea
valabil pentru coloanele specificate n clauzele ORDER BY.
Datele de ieire generate de interogare sunt acceptabile dac dorim s tim numai care sunt elevii cu absene.
Dar, dac trimitem aceast list la secretariatul colii, cei de acolo vor spune: Dar ceilali elevi? Vrem o valoare
pentru fiecare elev." Aceasta este;o problem uor diferit, nseamn c dorim s cunoatem numrul absenelor,
chiar i pen-
Capitolul 1 Introducere n MySQL i SQL
85
tru elevii care nu au avut nici o absen. Deoarece ntrebarea este diferit, i interogarea este diferit.
V ' . ' " -. . ' "
"()..'
Pentru a rspunde la ntrebare, putem folosi LEFT JOIN n loc de a asocia identificatorul de elev n clauza
WHERE. LEFT JOIN indic programului MySQL ;s genereze un rnd de date de ieire pentru fiecare rnd
selectat din tabelul denumit primul n cadrul unirii (adic tabelul precizat n stnga cuvintelor cheie LEFT JOIN).
Preciznd mai nti tabelul elev, vom primi date de ieire pentru fiecare elev, chiar i pentru cei care nu sunt
reprezentai n tabelul absente. Interogarea se prezint astfel: mysql> SELECT elev.elev_id, elev.nue,
-> COUNT(absente,date) A absente
-> FROM elev LEFT JOIN absente
-> ON elev.elev_id = absente.elevJLd
-> GROUP BY elevielevid; (
elev_id nume absente
.
WA.V.,.!- :
.:...
1 Megan 0
2 Joseph 0
3 Kyle 1
4 Katie 0
5 Abby 1
6 Nathan 0
7 Liesl 0

Anterior, n seciunea Generarea de sumare* am rulat a interogare care producea o caracterizare numerica a
datelor din tabelul puncte. Datele de ieire ale acelei interogri afiau identificatorul de eveniment, dar nu
includeau data la care a fost obinut punctajul sau tipul acestuia, deoarece atunci nu tiam cum s unim tabelul
puncte cu tabelul eveniment, pentru .a obine datele i tipurile punctajelor. Acum tim. Interogarea urmtoare
este similar celei pe care am executat-o anterior, dar prezint data i tipul punctajelor, nu numai identificatorul
numeric de eveniment:
mysql> SELECT :
, -> eveninent.data,eyeniseat.tip .
-> MIN(puncte.puncte) AS inia, -> MAX(puncte.puncte) AS MxiM,
-> MAX(puncte.puncte)-MIN(puncte.puncte)+1 AS doieniu, -> SQM(puncte.puncte) AS total,
,
-> AVG(puncte.puncte) AS edie,, -> COUNT(puncte.puncte) AS nimar, -> FROM puncte, eveniment
:j,',; .
-> HERE puncte.evenient_id = eveni*ent.eveniHent_14 -> GROUP BY evenUent.data;
86
Partea l Utilizarea general a.sistemului MySQL
data tip minim maxim domeniu total medie numr
1999-09-03 c 9 20 12 439 15.1379 29
1999-09-06 C 8 19 12 425 14.1667 30
1999-09-09 T 60 97 38 2425 78.2258 31
1999-09-16 r* 7 20 14 379 14.0370 27
1999-09-23 c Q 20 13 383 14.1852 27
1999-10-01 62 100 39 2325 80.1724 29
Putei folosi funcii precum COUNT () sau AVG() pentru a genera un sumar pe coloane multiple, chiar dac
aceste coloane provin de la tabele diferite. Interogarea urmtoare determin numrul de punctaje si punctajul
mediu pentru fiecare combinaie ntre data evenimentului i sexul elevului:
mysql> SELECT eveniment.data, elev.sex,
-> COUNT(puncte) AS numr, AVG(puncte) AS medie
-> FROM eveniment, puncte, elev
-> WHERE eveniment.eveninent_id = puncte.elev_id
-> AND puncte.elev_id = elev.elev_id
-> GROUP BY eveniment.data, elev.sex;
data sex numr medie
1999-09-03 F 14 14.6429
1999-09-03 M 15 15.6000
1999-09-06 F 14 14.7143
1999-09-06 M 16 13.6875
1999-09-09 F 15 77.4000
1999-09-09 M 16 79.0000
1999-09-16 F 13 15.3077
1999-09-16 M 14 12.8571
1999-09-23 F 12 14.0833
1999-09-23 M 15 14.2667
1999-10-01 F 14 77.7857
1999-10-01 M 15 82.4000
Putem folosi o interogare similar pentru a efectua una dintre sarcinile aferente proiectului de eviden a
rezultatelor colare: calculul punctajului total al fiecrui elev la sfritul semestrului. Interogarea se prezint
astfel:
SELECT elev.elev_id, elev.nume
SUM(puncte.puncte) AS total, COUNT(puncte.puncte) AS n
FROM eveniment, puncte, elev
WHERE eveniment.eveniment_id = puncte.eveniment_id
AND puncte.elev_id = elev.elev_id
GROUP BY puncte.elev_id
ORDER BY total
Nu exist nici o cerin conform creia o unire trebuie efectuat folosindu-se dou tabele diferite. La nceput
poate prea ciudat, dar putei uni un tabel cu el nsui. De exemplu, putei determina dac au existat preedini
nscui n acelai ora comparnd locul naterii fiecrui preedinte cu locul naterii tuturor celorlali preedini:
Capitolul 1 Introducere n MySQL i SQL
87
mysql> SELECT pl.nume, p1.prenume, pl.oras, pl.stat -> FROM preedinte AS p1, preedinte AS p2 ->
WHERE pl.oras = p2.oras AND pl.stat = p2.stat -> AND (pl.nume != p2.nume OR p1.prenume != p2.prenume)
-> ORDER stat, ora, nume;
nume prenume ora stat
Adams John Quincy John Braintree M
Adams Braintree M
Exist dou aspecte ciudate ale acestei interogri:
Trebuie s facem referire la dou instane ale aceluiai tabel, deci vom crea aliasuri ale tabelului (p1, p2) i le
vom folosi pentru a explicita referirile la coloanele tabelului.
nregistrarea fiecrui preedinte este echivalent cu ea nsi, dar nu dorim s vedem acest lucru n datele de
ieire. Cea de-a doua linie a clauzei WHERE interzice corespondena unei nregistrri cu ea nsi, asigurnd
faptul c nregistrrile comparate aparin unor preedini diferii.
O interogare similar gsete preedinii care s-au nscut n aceeai zi. Datele de natere nu pot fi comparate
direct, deoarece astfel s-ar pierde" preedinii care s-au nscut n ani diferii, n schimb, vom folosi MONTH ()
i DAYOFMONTH() pentru a compara ziua i luna datei de natere:
mysql> SELECT pl.nume, p1.prenume, p1.data_nastere
-> FROM preedinte AS p1, preedinte AS p2
-> WHERE MONTH(p1.data_nastere) = MONTH(p2.data_nastere)
-> AND DAYOFMONTH(p1.data_nastere) =
-> DAYOFMONTH(p2.data_nastere)
-> AND (pl.nume != p2.nume OR p1.prenume != p2.prenume)
-> ORDER BY pl.nume;
nume prenume data_nastere
Harding Polk Warren G. 1865-11-02
James K. 1795-11-02
Folosind funcia DAYOFYEAR () n locul combinaiei ntre funciile MONTH () i DAYOFMONTH () s-ar
obine o interogare mai simpl, dar s-ar produce rezultate incorecte atunci cnd se compar datele din anii biseci
cu datele din anii cu 365 de zile.
Unirile efectuate pn acum au combinat informaii din tabele ntre care exist o oarecare relaie logic
semnificativ, dar numai dumneavoastr cunoatei semnificaia acelei relaii. MySQL nu tie (sau nu-i pas)
dac tabelele unite au sau nu vreo legtur unul cu altul. De exemplu, putei uni tabelul eveniment cu tabelul
preedinte, pentru a afla dac ai dat sau nu chestionare sau teste de ziua de natere a unui preedinte: mysql>
SELECT preedinte.nume, preedinte.prenume,
-> preedinte.data_nastere, eveniment.tip
-> FROM preedinte, eveniment
-> WHERE MONTH(presedinte.data_nastere) =
88 Partea l Utilizarea general a sistemului MySQL
-> MONTH(eveniment.data)
-> ANO DAYOFMONTH(preedinte.data_nastere)
-> OAYOFMONTH(eveniment.data);
nume prenume data_nastere tip
Carter James E 1924-10-01 T
Se pare c ai dat un test de ziua de natere a unui preedinte. i ce dac? Aceasta nseamn c MySQL va fi
foarte bucuros s scoat la iveal rezultate, indiferent dac ele sunt logice sau nu. Numai pentru c folosii un
calculator nu nseamn obligatoriu c rezultatele unei interogri sunt utile sau c merit osteneala. Din fericire
sau din pcate, nu suntem scutii de a ti ce trebuie s facem.
tergerea sau actualizarea nregistrrilor existente
Uneori, dorii s v descotorosii de nregistrri sau dorii s le modificai coninutul. Instruciunile DELETE i
tlPDATE v permit aceste operaii.
Instruciunea DELETE are urmtoarea form:
DELETE FROM tabel_nume WHERE nregistrri care trebuie terse Clauza WHERE indic nregistrrile care
trebuie terse si este opional dar, dac o omitei, vor fi terse toate nregistrrile. Aceasta nseamn c
instruciunea DELETE cea mai simpl este i cea mai periculoas:
DELETE FROM nume_tabel
Aceast interogare terge n totalitate coninutul tabelului. Fii atent la interogarea respectiv!
Pentru a terge anumite nregistrri, folosii clauza WHERE pentru a selecta nregistrrile care v intereseaz.
Aceasta este similar clauzei WHERE dintr-o instruciune SELECT. De exemplu, pentru a terge din tabelul
preedinte pe toi preedinii nscui n statul Ohio, folosii aceast interogare:
mysql> DELETE FROM preedinte WHERE stat="OH";
Query OK, 7 rows affected (0.00 sec)
Un dezavantaj al clauzei WHERE pentru instruciunea DELETE este acela c putei face referire numai la
coloanele tabelului din care tergei nregistrrile.
nainte de a emite o instruciune DELETE, deseori este bine s testai clauza WHERE folosind-o cu o
instruciune SELECT, pentru a v asigura c vei terge nregistrrile pe care dorii s le tergei (si numai acele
nregistrri). S presupunem c dorii s tergei nregistrarea pentru Teddy Roosevelt. Ar fi bun urmtoarea
interogare?
DELETE FROM preedinte WHERE nume="Roosevelt"
Da, n sensul c ar terge nregistrarea pe care o avei n vedere. Nu, n sensul c ar terge i nregistrarea lui
Franklin Roosevelt. Cel mai bine este s verificai n prealabil clauza WHERE, astfel:
mysql> SELECT nume, prenume FROM preedinte -> WHERE nume="Roosevelt";
Capitolul 1 Introducere n MySQL i SQL
89
prenume nume
Roosevelt Theodore
Roosevelt Franklin D.
Din acest exemplu se deduce necesitatea de a fi mai concret: mysql> SELECT nume, prenume FROM
preedinte
-> WHERE nurae=nRoosevelt" AND prenume="Theodore";
prenume nume
Roosevelt Theodore
Acum tim care este clauza WHERE corect pentru selectarea nregistrrii dorite, deci interogarea DELETE
poate fi construit corect: mysql> DELETE FROM preedinte
-> WHERE nume="Roosevelt" AND prenume="Theodore"; Cam mult munc pentru a terge o nregistrare, nu-
i aa? Paza bun trece primejdia rea!
(Aceasta este una din situaiile n care vei dori s reducei la minimum numrul caracterelor introduse de la
tastatur, prin utilizarea tehnicilor de copiere si lipire, respectiv de editare a liniilor de intrare. Vezi seciunea
Sugestii pentru interaciunea cu mysql" pentru mai multe informaii.)
Pentru modificarea nregistrrilor existente, folosii UPDATE, care are urmtoarea form:
UPDATE nume_tabel SET coloane de modificat
WHERE nregistrri de actualizat
Clauza WHERE se folosete ca n cazul instruciunii DELETE i este opional deci, dac nu o specificai, v or fi
actualizate toate nregistrrile din tabel. Interogarea urmtoare transform numele tuturor elevilor dumneavoastr
n George":
mysql> UPDATE elev SET nume="George; Evident, trebuie s fii atent cu nregistrri de acest gen.
De obicei, vei fi mai concret n ceea ce privete nregistrrile pe care le actualizai. S presupunem c ai
adugat recent un membru al Ligii istorice, dar ai completat numai cteva coloane din rubrica sa:
mysql> INSERT membru (nume,prenume)
-> VALUES('lonescu'.'Vasile');
Apoi, v dai seama c ai uitat s menionai data plii cotizaiei. Putei remedia acest neajuns dup cum
urmeaz: mysql> UPDATE membru
-> SET data_expirare='2001-7-20'
-> WHERE nume='lonescu' AND prenume='Vasile'
Putei actualiza mai multe coloane simultan. Instruciunea urmtoare actualizeaz adresa potal i de e-mail a
lui Vasile: mysql> UPDATE membru
-> SET email ='ivasiledyahoo.corn',
-> strada='123 Str. Lunga',oras='Nicieri',
90 Partea l Utilizarea general a sistemului MySQL
-> stat='NY',cod_postal='01003l
-> WHERE nume='lonescu' AND prenume='Vasile';
De asemenea, putei anula" valoarea unei coloane atribuindu-i acesteia valoarea NULL (presupunnd c acea
coloan accept valori NULL). Dac la un anumit moment n viitor Vasile se decide s plteasc acea cotizaie
mare care i permite s devin membru pe via", i putei modifica nregistrarea n mod adecvat atribuind datei
de expirare valoarea NULL (n sensul c nu expir niciodat"): mysql> UPDATE membru
-> SET data_expirare=NULL
-> WHERE nume='lonescu1 AND prenune='Vasile';
n cazul instruciunii UPDATE, ca i pentru DELETE, este bine s testai o clauz WHERE folosind o
instruciune SELECT, pentru a v asigura c alegei nregistrrile corecte pentru actualizare, n cazul n care
criteriile dumneavoastr de selecie sunt prea nguste sau prea largi, vei actualiza prea puine, respectiv prea
multe nregistrri.
Dac ai ncercat interogrile din aceast seciune, vei fi ters i modificat nregistrri din tabelele bazei de date
samp_db. nainte de a trece la seciunea urmtoare, trebuie s anulai aceste modificri. Facei aceasta prin
rencrcarea tabelelor folosind instruciunile de la sfritul seciunii Adugarea de noi nregistrri".
Modificarea structurii tabelelor
V mai amintii cnd am creat tabelul membru al Ligii istorice fr o coloan a identificatorului numeric al
membrilor, ca pretext pentru a folosi instruciunea ALTER TABLE? Este momentul s folosim aceast
instruciune. Cu ajutorul instruciunii ALTER TABLE, putei redenumi tabele, aduga sau terge coloane,
modifica tipuri de coloane i altele. Singurul exemplu pe care l voi prezenta aici este modalitatea de a aduga o
coloan nou. Vezi capitolul 3 pentru mai multe detalii despre posibilitile instruciunii ALTER TABLE.
Considerentul principal la adugarea unei coloane cu identificatorul numeric al membrilor la tabelul membru
este acela c valorile trebuie s fie unice, pentru a se evita confuzia ntre rubrici. Aici este util o coloan
AUTO_INCREMENT, deoarece putem permite programului MySQL s genereze automat numere unice atunci
cnd adugm membri noi. ntr-o instruciune CREATE TABLE, specificaia pentru o asemenea coloan ar arta
astfel:
membru_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY Pentru instruciunea ALTER
TABLE, sintaxa este similar. Rulai aceast interogare pentru a aduga coloana:
mysql> ALTER TABLE membru
-> ADD membru_id INT UNSIGNED NOT NULL AUTO_INCREMENT -> PRIMARY KEY;
Acum, cnd avem o nou coloan pentru memorarea identificatorilor numerici ai membrilor, cum repartizm
numere nregistrrilor existente din tabelul membru? Simplu; MySQL s-a ocupat deja de asta! Cnd adugai o
coloan la un tabel, MySQL iniializeaz valorile coloanelor cu valoarea prestabilit, n cazul unei coloane
AUTO_INCREMENT, aceasta determin generarea unui nou numr din secven pentru fiecare rnd.
Capitolul 1 Introducere n MySQL i SQL
91
Sugestii pentru interaciunea cu mysql
Aceast seciune discut despre modul de a interaciona cu programul client mysql ntr-o manier mai eficient i
cu mai puin text introdus de la tastatur. Este descris un mod mai simplu de conectare la server i metode de
introducere a interogrilor fr a o tasta pe fiecare de la nceput pn la sfrit.
Simplificarea procesului de conexiune
Probabil c trebuie s specificai parametri de conexiune precum numele gazdei, numele de utilizator sau parola
atunci cnd invocai mysql. Pentru simpla rulare a unui program trebuie introdus o cantitate serioas de text,
lucru care devine foarte repede obositor. Exist numeroase metode pentru simplificarea procesului de conectare,
prin reducerea la minimum a textului introdus de la tastatur:
Utilizai un fiier cu opiuni pentru stocarea parametrilor de conectare.
Repetai comenzile beneficiind de caracteristicile interpretorului dumneavoastr de memorare a comenzilor
(istoric).
Definii o scurttur pentru linia de comand mysql folosind un alias sau un script de interpretor.
Utilizarea unui fiier cu opiuni
ncepnd de la versiunea 3.22, MySQL v permite s stocai parametri de conexiune ntr-un fiier cu opiuni.
Apoi, nu mai trebuie s tastai parametri de fiecare dat cnd rulai mysql; acetia sunt folosii ca i cum i-ai fi
introdus n linia de comand. Parametrii sunt de asemenea folosii i de ctre alte programe client MySQL,
precum mysqlimport. Aceasta nseamn c un fiier cu opiuni reduce cantitatea de text introdus atunci cnd
folosii i aceste programe.
Pentru a folosi fiierul cu opiuni n vederea specificrii parametrilor de conexiune, creai un fiier denumit
-/.my.cnf (adic un fiier denumit .my.cnf n catalogul dumneavoastr de baz). Un fiier cu opiuni este un fiier
cu text simplu, deci l putei crea folosind orice editor de texte. Coninutul fiierului se prezint astfel:
[client]
host=gaz(/a_serverului
user=numele_dumneavoastr
password=parola_dumneavoastr
Linia [client] indic nceputul grupului cu opiuni pentru programul client; toate liniile care urmeaz dup
aceasta sunt linii citite de ctre programele client MySQL pentru a obine valorile opiunilor, pn la sfritul
fiierului sau pn la nceputul unui grup de parametri diferit, nlocuii gazda_serverului, numele_dumneavoastra
si parola_dum-neavoastra cu numele gazdei, numele de utilizator i parola pe care le specificai cnd v conectai
la server. Pentru mine, fiierul . my. cnf se prezint astfel
[client]
host=pit-viper.snake.net
user=paul
password=secret
92 Partea l Utilizarea general a sistemului MySQL
Singura linie obligatorie este [client]. Liniile care definesc valorile parametrilor sunt opionale; le putei specifica
numai pe cele dorite. De exemplu, dac numele dumneavoastr de utilizator MySQL este acelai cu numele
UNIX de deschidere a sesiunii de lucru, atunci nu trebuie s includei o linie user.
Dup ce ai creat fiierul .my .cnf, stabilii pentru modul su de acces o valoare restrictiv, pentru a v asigura c
nimeni altcineva nu poate s-1 citeasc:
% chmod 600 .ray,cnf
Sub Windows, coninutul fiierului cu opiuni este acelai, dei numele este diferit (C: \my.cnf), iar
dumneavoastr nu invocai comanda chmod.
Deoarece fiierele cu opiuni au fost adugate la MySQL dect ncepnd cu versiunea 3.22, nu le putei folosi cu
versiunile anterioare, n particular, nu putei folosi un fiier cu opiuni sub Windows la clienii inclui n
distribuia shareware a sistemului MySQL, deoarece aceea se bazeaz pe MySQL 3.21. Fiierele cu opiuni sunt
compatibile cu versiunea Windows nregistrat a sistemului MySQL, sau v putei procura programe client mai
recente, compatibile cu fiierele cu opiuni, din situl Web MySQL.
Despre fiierele cu opiuni se pot obine mai multe informaii n Anexa E, Referin de program MySQL".
Utilizarea istoricului de comenzi al interpretorului
Interpretoare precum csh, tcsh si bash rein comenzile dumneavoastr ntr-o list istoric i v permit sa repetai
comenzi din lista respectiv. Dac folosii un asemenea interpreter, lista dumneavoastr istoric v poate ajuta s
evitai tastarea unor ntregi comenzi. De exemplu, daca ai invocat programul mysql recent, l putei reexecuta
dup cum urmeaz:
% l my
Caracterul ! indic interpretorului s caute n istoricul de comenzi pentru a gsi cea mai recent comand care
ncepe cu my i s o re-execute ca i cum dumneavoastr ai fi rein-trodus-o de la tastatur. De asemenea, unele
interpretoare v permit s v deplasai n sus si n jos n lista istoric folosind tastele cu sgei orientate n sus,
respectiv n jos (sau poate combinaiile de taste Ctrl-P i Ctrl-N). Putei selecta n acest mod comanda dorit i
apoi apsai pe Enter pentru a o executa, tcsh i bash au aceast caracteristic, posibil existent i la alte
interpretoare. Examinai documentaia interpretorului dumneavoastr pentru a afla mai multe detalii despre
utilizarea listei istoric.
Utilizarea aliasurilor i a scripturilor de interpreter
Dac interpretorul dumneavoastr permite atribuirea unui alias, putei configura scurtturi de comenzi care v
permit s invocai o comand lung prin tastarea unui nume scurt. De exemplu, n csh sau tcsh, putei folosi
comanda alias pentru a configura un alias denumit samp_db, cum este acesta:
alias samp_db 'mysql -h pit-viper.snake.net -u -paul -p samp_db' Sintaxa pentru bash este uor diferit:
alias samp_db='mysql -h pit-viper.snake.net -u -paul -p samp_db' Definirea unui alias face aceste dou
comenzi echivalente:
samp_db
mysql -h pit-viper.snake.net -u -paul -p samp_db
Capitolul 1 Introducere n MySQL i SQL 93
Evident, prima comand este mai uor de introdus dect a doua. Pentru ca aliasul s aib efect de fiecare dat
cnd deschidei sesiunea de lucru, plasai comanda alias ntr-unul din fiierele de pornire ale interpretorului
dumneavoastr (de exemplu .cshrc pentru csh sau .bash_profile pentru bash).
Un alt tip de scurttur este crearea unui script de interpreter care execut mysql automat, cu opiunile adecvate,
n UNIX, un fiier script echivalent cu aliasul samp_db prezentat anterior arat astfel:
#! /bin/sh
exec mysql -h pit-viper.snake.net -u -paul -p samp_db
Dac denumesc scriptul samp_db i l transform ntr-un executabil (folosind comanda chmod +x samp_db), pot
tasta samp_db pentru a rula mysql i pentru a m conecta la baza mea de date.
Sub Windows, n aceleai scopuri se poate folosi un fiier batch, avnd extensia .bat si coninnd comenzi
executabile fr intervenia utilizatorului. Denumii fiierul samp_db.bat i inserai n fiier o linie ca aceasta:
mysql -h pit-viper.snake.net -u -paul -p samp_db
Acest fiier batch poate fi rulat fie tastnd samp_db la promptul dintr-o consol DOS, fie executnd dublu clic pe
pictograma sa din Windows.
Dac obinei acces la mai multe baze de date sau v conectai la mai multe gazde, putei defini mai multe
aliasuri sau scripturi, fiecare din acestea invocnd mysql cu opiuni diferite.
Emiterea de interogri cu o cantitate mai mic de text introdus de la tastatur
mysql este un program extrem de util pentru interaciunea cu baza dumneavoastr de date, dar interfaa sa este
ideal pentru interogri scurte, de un rnd. mysql nu este interesat dac o interogare se extinde pe mai multe
rnduri, desigur, dar nu este prea amuzant s tastezi interogri lungi. Introducerea unei interogri, chiar i a uneia
scurte, nu este nici ea prea distractiv, dac descoperi c trebuie s o tastezi din nou datorit unei erori de
sintax.
Exist numeroase tehnici pe care le putei utiliza pentru evitarea unor introduceri i reintroduceri inutile de text:
Folosii caracteristica de editare a liniei de intrare din mysql.
Utilizai copierea i lipirea.
Rulai mysql n mod batch.
Evitai s introducei instruciuni INSERT, prin utilizarea datelor existente pentru crearea de noi nregistrri.
Utilizarea editorului liniilor de intrare din mysql
n mysql este ncorporat biblioteca GNU Readline, care permite editarea liniilor de intrare. Putei manipula linia
pe care o introducei la un moment dat sau putei relua liniile introduse anterior i le putei re-introduce, fie ca
atare, fie dup o modificare ulterioar. Acest lucru este convenabil cnd introducei o linie si observai o greeal
de
94
Partea l Utilizarea general a sistemului MySQL
introducere a textului; putei reveni n interiorul liniei pentru a corecta problema nainte de a apsa pe tasta Enter.
Dac introducei o interogare care conine o greeal, putei relua interogarea i o putei edita pentru a remedia
problema, dup care o retrimitei. (Acest lucru este cel mai uor de fcut dac tastai ntreaga interogare pe o
singur linie.)
Unele dintre secvenele de editare pe care le vei gsi utile sunt prezentate n tabelul 1.4, dar exist multe
comenzi de editare a liniei de intrare n afara celor prezentate n tabel. Putei gsi o versiune electronic a
manualului Readline prin consultarea motorului dumneavoastr preferat de cutare n Internet. Manualul este de
asemenea inclus n distribuia Readline, disponibil n situl Web al proiectului GNU, la adresa http: /
/www.gnu .org/.
Tabelul 1.4 Comenzi mysql de editare a liniei de intrare
Secven de taste
Sgeat sus, Ctrl-P
Sgeat jos, Ctrl-N
Sgeat stnga, Ctrl-B
Sgeat dreapta, Ctrt-F
Esc Ctrl-B
Esc Ctrl-F
Ctrl-A
Ctrl-E
Ctrl-D
Delete
Esc D
Esc Backspace
Ctrt-K
Ctrl-
Semnificaie
Reluarea liniei anterioare Reluarea liniei ulterioare Deplasarea cursorului la stnga (napoi) Deplasarea
cursorului la dreapta (nainte) Deplasare napoi cu un cuvnt Deplasare nainte cu un cuvnt Deplasarea
cursorului la nceputul liniei Deplasarea cursorului la sfritul liniei tergerea caracterului aflat sub cursor
tergerea caracterului din stnga cursorului tergerea cuvntului
tergerea cuvntului din stnga cursorului terge tot, de la cursor la sfritul liniei Anuleaz ultima modificare;
se poate repeta
Exemplul urmtor descrie o utilizare simpl pentru editarea liniei de intrare. S presupunem c ai introdus
aceast interogare n timp ce utilizai mysql:
mysql> SHOW COLUMNS FROM persedinte;
Dac observai c n loc de preedinte" ai scris peredinte", nainte de a apsa pe tasta Enter, apsai tasta
sgeat stnga sau combinaia de taste Ctrl-B de cteva ori pentru a deplasa cursorul la stnga, pn cnd ajunge
la litera s. Apoi apsai de dou ori pe tasta Delete pentru a terge caracterele e r, tastai re pentru a remedia
eroarea i apsai pe tasta Enter pentru a emite interogarea. Dac apsai pe tasta Enter nainte de a sesiza
eroarea, nu este nici o problem. Dup ce mysql i afieaz mesajul de eroare, apsai pe tasta sgeat sus sau pe
combinaia de taste Ctrl-P pentru a relua linia, dup care o editai aa cum am artat mai sus.
Editarea liniilor de intrare nu este disponibil n versiunea Windows a programului mysql, dar v putei procura
distribuia client gratuit cygwin_32 din situl Web MySQL. Programul mysqlc din acea distribuie este similar cu
mysql, dar nelege comenzile de editare a liniei de intrare.
Capitolul 1 Introducere n MySQL i SQL
95
Utilizarea copierii i a lipirii pentru emiterea de interogri
Dac lucrai ntr-un mediu cu ferestre, putei salva textul interogrilor care vi se par utile ntr-un fiier i putei
folosi operaiile de copiere i lipire pentru a emite cu uurin aceste interogri. Pur si simplu respectai
urmtoarea procedur:
1. Invocai mysql ntr-o fereastr Telnet sau ntr-o fereastr de consol DOS.
2. Deschidei fiierul care conine interogrile dumneavoastr ntr-o fereastr document. (De exemplu, eu
folosesc BBEdit sub Mac OS, respectiv vi ntr-o fereastr xterm sub X Window System n UNIX.)
3. Pentru a executa o interogare stocat n fiierul dumneavoastr, selectai-o i copiai-o. Apoi, comutai n
fereastra dumneavoastr Telnet sau n consola DOS i lipii interogarea n MySQL.
Procedura pare cam stngace descris pe hrtie, dar este o modalitate rapid de a introduce interogri rapid i
fr a mai scrie nimic atunci cnd o folosii efectiv.
De asemenea, aceast tehnic v permite s v editai interogrile n fereastra document, precum i s construii
interogri noi prin copierea si lipirea componentelor interogrilor existente. De exemplu, dac selectai frecvent
rnduri dintr-un anumit tabel, dar dorii s vedei datele de ieire sortate n diferite moduri, putei folosi o list cu
diferite clauze ORDER BY n fereastra dumneavoastr document, dup care o copiai i o lipii pe aceea pe care
dorii s o utilizai pentru orice interogare specific.
Putei folosi copierea i lipirea i n cealalt direcie (de la Telnet ctre fiierul dumneavoastr cu interogri).
Cnd introducei linii n mysql, acestea sunt salvate ntr-un fiier denumit .mysqljiistory din catalogul
dumneavoastr de baz. Dac introducei manual o interogare pe care dorii s o salvai pentru a o consulta
ulterior, prsii programul mysql, deschidei . mysql_history ntr-un editor, apoi copiai si lipii interogarea din
fiierul .mysql_history n fiierul care conine interogarea.
Rularea programului mysql n mod batch
Nu este necesar rularea interactiv a programului mysql; acest program poate citi un fiier n mod non-
interactiv (batch). Acest mod este util pentru interogri pe care le rulai periodic, deoarece nu dorii, evident, s
reintroducei de la tastatur o asemenea interogare de fiecare dat cnd o rulai. Este mai uor s inserai o dat
interogarea ntr-un fiier, dup care s cerei programului mysql s execute coninutul fiierului conform
necesitilor.
S presupunem c averi o interogare care gsete pe membrii Ligii istorice interesai de o anumit perioad din
istoria Statelor Unite, cutnd n coloana interese a tabelului membru. De exemplu, pentru a-i gsi pe membrii
interesai n perioada de criz a anilor '30, interogarea trebuie scris astfel (reinei caracterul punct si virgul de
la sfritul instruciunii, pentru ca mysql s poat sesiza locul unde se ncheie aceasta):
SELECT nume, prenume, email, interese FROM membru
WHERE interese LIKE "%criza%"
ORDER BY nume, prenume;
Plasai interogarea ntr-un fiier denumit interese. sql, apoi rulai interogarea furniznd fiierul programului
mysql, astfel:
% mysql samp_db < interese.sql
96 Partea l Utilizarea general a sistemului MySQL
n mod prestabilit, mysql genereaz date de ieire ntr-un format delimitat prin tabula-tori atunci cnd este rulat
n mod grup. Dac dorii s obinei acelai format tabular atunci cnd rulai mysql n mod interactiv, folosii
opiunea -t:
% mysql -t samp_db < interese.sql Dac dorii s salvai datele de ieire, redirecionai-le spre un fiier:
% mysql -t samp_db < interese.sql > fisier_iesire
Pentru a folosi interogarea n scopul de a gsi membri interesai de personalitatea lui Thomas Jefferson, putei
edita fiierul cu interogarea pentru a nlocui criza cu Jefferson, dup care rulai mysql din nou. Aceast metod
funcioneaz atta timp ct nu folosii interogarea foarte frecvent. Dac o folosii foarte frecvent, atunci este
necesar o alt metod. O modalitate de a spori flexibilitatea interogrii este de a o insera ntr-un script de
interpreter care preia un argument din linia de comand a scriptului i o folosete pentru a modifica textul
interogrii. Astfel, interogarea devine parametrizat i v permite s specificai cuvntul cheie care arat
domeniul de interes atunci cnd rulai scriptul. Pentru a vedea modul de funcionare al acestei metode, scriei un
mic script de interpreter, denumit interese.sh:
#1 /bin/sh
if [ $# -ne 1 J; then echo "Rog specificai un cuvnt cheie"; exit; fi
mysql -t samp_db QUERY_INPUT
SELECT nume, prenume, email, interese FROM membru
WHERE interese LIKE "%$1%"
ORDER BY nume, prenume;
QUERY_INPUT
Cea de-a doua linie se asigur c exist un cuvnt cheie n linia de comand; afieaz un scurt mesaj i ncheie
execuia programului n caz contrar, ntreg textul cuprins ntre QUERY_INPUT i linia QUERY_INPUT final
se transform n date de intrare pentru mysql. n cadrul textului interogrii, interpretorul nlocuiete referina la
$1 cu cuvntul cheie din linia de comand. (In scripturile de interpreter, $1, $2... se refer la argumentele
comenzii.) Acest fapt determin interogarea s reflecte cuvntul cheie pe care l specificai n linia de comand
cnd rulai scriptul.
nainte de a putea rula scriptul, trebuie s-1 facei executabil:
% chmod +x interese.sh
Acum, nu mai trebuie s editai scriptul de fiecare dat cnd l rulai. Pur si simplu indicai direct n linia de
comand ce anume cutai:
% interese.sh criza
% interese.sh Jefferson
Crearea de noi nregistrri folosind date existente
Se pot aduga noi nregistrri ntr-un tabel, rnd cu rnd, folosind instruciunea INSERT dar, dup crearea
ctorva nregistrri prin tastarea manual a instruciunilor INSERT, majoritatea dintre noi suntem convini c
trebuie s existe i o metod mai bun de a executa aceast operaie. O alternativ este utilizarea unui fiier care
conine numai valori de date si apoi ncrcarea de nregistrri din acel fiier folosind instruciunea LOAD DATA
sau utilitarul my sql import.
Capitolul 1 Introducere n MySQL i SQL
97
Deseori, creai fiierul de date folosind date care deja exist ntr-un alt format. Informaiile dumneavoastr pot fi
coninut ntr-un program de calcul tabelar sau poate c se afl ntr-o alt baz de date i dorii s le transferai
ctre MySQL. Pentru a nu complica aceast discuie, voi presupune c datele dumneavoastr se afl ntr-o foaie
de calcul tabelar din calculatorul dumneavoastr de birou.
Pentru a transfera datele din foaia de calcul din calculatorul dumneavoastr ntr-un fiier din contul
dumneavoastr UNIX, putei folosi tehnica de copiere i lipire, alturi de Telnet. Iat cum procedai:
1. Deschidei o conexiune Telnet spre contul dumneavoastr UNIX. Sub Mac OS, putei folosi o aplicaie
precum BetterTelnet sau NCSA Telnet. Sub Windows, putei folosi programul Telnet standard.
2. Deschidei foaia de calcul tabelar, selectai blocul de date pe care dorii s-1 transferai i copiai-1.
3. n fereastra Telnet, tastai urmtoarea comand pentru a ncepe capturarea datelor n fisieruldata.txt:
% cat > data.txt
Comanda cat ateapt datele de intrare.
4. Lipii datele pe care le-ai copiat din foaia de calcul n fereastra Telnet. Programul cat crede c introducei
personal informaiile si le scrie ndatoritor n fiierul data.txt.
5. Dup ce toate datele lipite au fost scrise n fiier, apsai pe tasta Enter n cazul n care cursorul ajunge la
sfritul unei linii de date, nu la nceputul unei linii noi. Apoi, apsai pe combinaia de taste Ctrl-D pentru a
indica sfritul fiierului". Programul cat nceteaz s mai atepte date de intrare i nchide fiierul.
n acest moment, avei un fiier data.txt care conine blocul de date pe care 1-ai selectat n foaia dumneavoastr
de calcul tabelar i care este gata de a fi ncrcat n baza dumneavoastr de date cu LOAD DATA sau
mysqlimport.
Copierea i lipirea reprezint o metod rapid si simpl de a transfera date ntr-un fiier UNIX, dar este mai
adecvat pentru seturi mai mici de date. Cantitile mai mari de date pot depi limitele bufferului de copiere al
sistemului dumneavoastr, n asemenea cazuri, se recomand salvarea foii de calcul tabelar n format text simplu
(delimitat prin tabulator!). Apoi, putei transfera fiierul din calculatorul dumneavoastr n contul UNIX folosind
FTP. Transferai fiierul n mod text (nu n mod binar sau imagine), astfel nct caracterele sfrit de rnd s fie
convertite n caractere UNIX de sfrit de rnd. (UNIX folosete caractere salt la linie nou, Mac OS folosete
caractere retur de car, iar Windows folosete perechea de caractere retur de car-salt la linie nou.) Putei indica
instruciunii LOAD DATA sau programului mysqlimport tipul caracterului sfrit de rnd pe care s-1 atepte,
dar n UNIX este mai uor de lucrat cu fiierul dac acesta conine caractere de salt la linie nou.
Dup transferul fiierului, este bine s verificai dac are sau nu rnduri vide la sfrit. Dac are, trebuie s le
tergei, deoarece altfel se vor transforma n nregistrri vide sau deformate atunci cnd ncrcai fiierul n baza
de date.
98 Partea l Utilizarea general a sistemului MySQL
n fiierele salvate n format text simplu dintr-o foaie de calcul tabelar, valorile care conin spaii pot fi delimitate
prin ghilimele. Pentru a elimina ghilimelele atunci cnd ncrcai fiierul n baza dumneavoastr de date, folosii
clauza FIELDS ENCLOSED BY pentru instruciunea LOAD DATA, respectiv opiunea --fields-enclosed-by
pentru mysqlimport. Vezi informaiile despre instruciunea LOAD DATA din Anexa D pentru a obine mai multe
detalii.
De aici, ncotro?
Acum tii destule despre MySQL. Putei configura o baz de date si crea tabele. Putei insera nregistrri n
aceste tabele, le putei regsi n diverse moduri, le putei modifica sau terge. Dar mai avei nc multe de nvat
despre MySQL; manualul din acest capitol a reprezentat numai o mic introducere. Putei vedea acest lucru
examinnd starea bazei noastre de date exemplu. Am creat baza de date i tabelele sale i am populat-o cu unele
date iniiale. Pe parcursul acestui proces am vzut modul de scriere al unora dintre interogrile de care avem
nevoie pentru a rspunde la ntrebri privind informaiile din baza de date. Mai sunt, ns, multe de fcut...
De exemplu, nu dispunem de nici o modalitate interactiv convenabil de a introduce noi nregistrri de punctaje
n cadrul proiectului de eviden a rezultatelor colare, respectiv nregistrri cu noii membri n catalogul Ligii
istorice. Nu avem nici o metod convenabil de a edita nregistrrile existente. i tot nu putem genera
formularele tiprite sau n format electronic pentru catalogul Ligii. Aceste sarcini, precum i altele, vor fi
abordate din nou n capitolele urmtoare, mai ales n capitolele 7, Interfaa API pentru Perl DBI", respectiv 8,
Interfaa API pentru PHP".
Drumul pe care vei merge n continuare printre paginile acestei cri depinde de domeniul dumneavoastr de
interes. Dac dorii s vedei modul n care am finalizat proiectele legate de Liga istoric i de evidena
rezultatelor colare, Partea a Il-a se refer la programarea n MySQL. Dac vei ndeplini funcia de
administrator MySQL pentru situl dumneavoastr, Partea a IlI-a a volumului de fa trateaz despre sarcinile
administrative. Totui, eu v recomand s acumulai mai nti cunotine suplimentare de ordin general despre
utilizarea sistemului MySQL, citind celelalte capitole din Partea I. Aceste capitole discut despre modul de
manipulare a datelor n MySQL, furnizeaz informaii suplimentare despre sintax i despre utilizarea
instruciunilor de interogare i v prezint modaliti de rulare mai rapid a interogrilor. O baz solid de
cunotine legate de aceste subiecte v va fi de folos indiferent de contextul n care folosii MySQL: rulai
programul mysql, v scriei propriile programe sau ndeplinii atribuiile unui adminir trator de baze de date.
CAPITOLUL 2
Lucrul cu date n MySQL i SQL
Practic, tot ceea ce facei n MySQL implic, ntr-un fel sau altul, date, deoarece rostul unui sistem de gestiune a
bazelor de date este, prin definiie, acela de gestiune a datelor. Chiar si o simpl instruciune SELECT 1 implic
o evaluare a unei expresii, cu scopul de a produce o valoare a unei date ntregi.
Fiecare valoare a unei date din MySQL are un tip. De exemplu, 37.4 este un numr, iar "abc" este un ir. Uneori,
tipurile de date sunt explicite, ca atunci cnd emitei o instruciune CREATE TABLE care specific tipul fiecrei
coloane pe care o declarai ca parte a tabelului:
CREATE TABLE tabelul meu
int_col INT, /"
sir_col CHAR(20), /' data col DATE /"
coloana cu valori ntregi */ coloana cu valori ir */ coloana cu valori date */
n alte situaii, tipurile de date sunt implicite, cum este atunci cnd facei referire la valori literale dintr-o
expresie, cnd transferai valori unei funcii sau cnd folosii valoarea retur-nat din acea funcie:
INSERT INTO tabeluljneu (int_col,sir_col,data_col)
VALUES(14,CONCAT("a","b"),19990115)
Aceast instruciune INSERT efectueaz urmtoarele operaii, din care toate implic tipuri de date:
Atribuie valoarea 14 coloanei ntregi1 int_col.
Transfer valorile ir "a" si "b" funciei CONCAT(). Aceast funcie returneaz valoarea ir "ab", care este
repartizat n coloana ir sir_col.
Atribuie valoarea ntreag 19990115 coloanei de tip dat data_col. Atribuirea implic o neconcordan ntre
tipuri, deci MySQL convertete irul 19990115 n data "1999-01-15"; acest fapt arat c MySQL execut
conversia automat a tipului.
Pentru a folosi MySQL n mod eficient, este esenial s nelegei modul de manipulare a datelor n MySQL.
Acest capitol descrie tipurile de date pe care le poate manipula MySQL i discut problemele implicate de lucrul
cu aceste tipuri:
1 Prin coloan ntreag se va nelege coloan care conine valori numere ntregi. S-a preferat n traducere prima
form, din motive de concizie. La fel de va proceda cu expresii gen coloan ir i altele. - N.T.

S-ar putea să vă placă și

  • Mysql 350
    Mysql 350
    Document28 pagini
    Mysql 350
    Lupu Adrian
    Încă nu există evaluări
  • Mysql 250
    Mysql 250
    Document29 pagini
    Mysql 250
    gabrielgabor22
    Încă nu există evaluări
  • Mysql 150
    Mysql 150
    Document30 pagini
    Mysql 150
    Lucian Musteata
    Încă nu există evaluări
  • Mysql 100
    Mysql 100
    Document32 pagini
    Mysql 100
    Виктор Которобай
    Încă nu există evaluări