Documente Academic
Documente Profesional
Documente Cultură
Carte SQL2008 Capitolele 1-4 PDF
Carte SQL2008 Capitolele 1-4 PDF
Editura
2008
2008 Editura InfoMega
e-mail: office@infomega.ro
http://www.infomega.ro
STANCIU, ANDREI
Baze de date : introducere în SQL, Server 2008 / Stanciu Andrei (coord.),
Mihai Florin, Năstase Bucureşti : InfoMega , 2008
Bibliogr.
ISBN 978-973-7853-36-3
I. Mihai, Florin
II. Năstase, Pavel
004.64
Cuprins
CAPITOLUL 1
CONCEPTE ŞI NOŢIUNI DE BAZĂ PRIVIND BAZELE DE DATE
RELAŢIONALE……………………………………………………………… 6
1.1. BAZE DE DATE ŞI SISTEME DE GESTIUNE A BAZELOR DE DATE……… 6
1.2.CONCEPTE DE BAZĂ ALE MODELULUI RELAŢIONAL…………….. 8
1.2.1.Cheia primară……………..……………..……………..………… 9
1.2.2.Cheia externă…………….…………………...………………….10
1.2.3. Restricţii de integritate………………………………………......11
1.2.4.Relaţiile dintre tabele……….……………..……………..………12
1.2.5.Anomalii de actualizare si anomalii de stocare………….......…..12
1.3. NORMALIZAREA BAZELOR DE DATE……………..……………...… 14
1.3.1.Dependenţa funcţională ……………..……………..…………... 15
1.3.2. Dependenţa funcţională completă (totală)……………………... 17
1.3.3.Dependenţa funcţională tranzitivă)……………………............... 18
1.3.4.Formele normale)…………………….......................................... 19
1.3.5.Etapele normalizării)……………………..……………………... 23
1.4. EXERCITII PROPUSE SI REZOLVATE)……………………………. 34
CAPITOLUL 2
SGBD SQL SERVER……………..……………...………………..………… 42
2.1.ARHITECTURA CLIENT-SERVER……………..……………...………. 42
2.2.PREZENTARE SQL SERVER 2008……………..……………...……….. 45
2.3.LIMBAJUL TRANSACT SQL
– PRINCIPALELE TIPURI DE INSTRUCŢIUNI……………..…………. 49
2.4. EXERCIŢII PROPUSE ŞI REZOLVATE……………..……………...… 55
CAPITOLUL 3
DESCRIEREA DATELOR…………..……………...………………..…… 60
3.1.CREAREA TABELELOR ……………..……………...………………….. 61
3.2.INDEXAREA TABELELOR …………..……………...…………………. 65
3.3.IMPLEMENTAREA RESTRICŢIILOR…………..………………………. 67
3.3.1. Restricţii la nivelul tabelelor (check constraints) ………………68
3.3.2. Integritatea referenţială ………………………………………... 68
3.3.3. Proceduri de tip trigger (Declanşatori) ………………………... 69
CAPITOLUL 4
INTEROGAREA DATELOR ………………………………………............. 76
4.1.FUNCŢII PREDEFINITE SQL SERVER………………………………… 76
4.2.OBIECTE DE TIP VIEW…………………………………………………. 94
4.3.PROCEDURI STOCATE………………………………………………… 100
4.3.1.Proceduri de sistem……………………………………………. 101
4.3.2.Declararea variabilelor………………………………………… 102
4.3.3.Parametrizarea procedurilor stocate…………………………… 103
4.3.4.Structuri de control al fluxului………………………………… 105
4.4.FUNCŢII DEFINITE DE UTILIZATOR…………………………………109
4.5.UTILIZAREA CURSOARELOR………………………………………... 117
4.6.EXERCIŢII PROPUSE ŞI REZOLVATE……………………………….. 122
CAPITOLUL 5
FACILITĂŢI PENTRU RAPORTAREA
SI ANALIZA DATELOR…………………………………………………... 128
5.1.ACCESS DATA PROJECTS: REALIZAREA APLICAŢIILOR
CLIENT UTILIZÂND MS OFFICE 2007 …..…………………...……… 128
5.2.REPORTING SERVICES: REALIZAREA RAPOARTELOR………….. 131
5.3.FACILITĂŢI SQL SERVER PENTRU DATAWAREHOUSE…………. 140
5.3.1.Arhitectura unui depozit de date……………………….……… 141
5.3.2.OLAP (On line Analytical Processing) …………………..…... 142
5.3.3.Modelarea multidimensională a datelor……………….……... 143
CAPITOLUL 6
EXPLOATAREA DATELOR IN FORMAT XML………………………. 160
6.1. LIMBAJUL XML - CONCEPTE DE BAZA……………………………. 160
6.2. UTILIZAREA DATELOR ÎN FORMAT XML IN SQL SERVER…….. 167
6.3.CONVERSIA DATELOR XML ÎN STRUCTURI
RELAŢIONALE DE DATE….................................................................... 170
6 Baze de date – Introducere in SQL Server 2008
CAPITOLUL 1
CONCEPTE ŞI NOŢIUNI DE BAZĂ PRIVIND
BAZELE DE DATE RELAŢIONALE
1
C.J.Date, Baze de date Editura E+, 2005
2
Claude Delobel et Michel Adiba, Bases de données et systèmes relationnels, Dunod, Paris, 1992
Capitolul I Concepte şi noţiuni de bază privind 7
bazele de date relaţionale
previziunile de extindere pe termen mediu în privinţa volumului de date din
cadrul organizaţiei;
nu în ultimul rând costurile de licenţiere şi politica de licenţiere a
producătorului;
În prezent, pe piaţă sistemelor de gestiune pentru baze de date relaţionale există o
ofertă bogată şi, ca în orice domeniu, se poate vorbi despre câţiva lideri. Tendinţa
producătorilor, pe lângă extinderea permanentă a capacităţilor de stocare şi
procesare, este de a incorpora în cadrul sistemelor instrumente şi facilităţi
specifice celor mai recente tehnologii (datawarehouse, data mining, facilităţi
pentru multimedia şi tipuri speciale de date).
Sistemele destinate gestiunii bazelor de date relaţionale pot fi clasificate în funcţie
de volumul de date pentru care sunt proiectate şi de facilităţile oferite în
următoarele două categorii:
SGBD pentru volum mediu de date (desktop database)
Microsoft Access Costuri reduse de licenţiere
FoxPro Cerinţe mici în ce priveşte resursele hardware
Paradox Interfaţa accesibilă pentru utilizatorii
FileMaker Pro neexperimentaţi
Soluţii usor de implementat pentru publicarea
Lotus Aproach datelor pe web
3
Compania americană IDG a fost fondată în 1964 şi, în prezent, dispune de filialele în întreaga
lume, ce desfăşoară studii pe piaţă teghnologiilor informatice şi comunicaţiilor.
4
RDBMS – Relational Database Management Systems
Capitolul I Concepte şi noţiuni de bază privind 9
bazele de date relaţionale
În figura următoare este prezentată structura generală a unei tabele, din punct de
vedere al conceptelor asociate.
Conform teoriei relaţionale, o tabelă (relaţie) nu poate să conţintă două sau mai
multe rânduri (tupluri) identice. Fiecare linie a unei tabele trebuie să poată fi
identificată într-o manieră clară, prin intermediul unui singur atribut sau a unui
grup de atribute, ce aparţin tabelei. În primul articol publicat de Codd (1969), se
folosea termenul generic “cheie” pentru a sugera acest lucru. Abia în cel de-al
doilea articol publicat de acesta (Codd, 1970), s-a folosit pentru prima dată
termenul “cheie primară”, termen care astăzi ne este foarte familiar.
Pe lângă caracteristica de unicitate amintită, o cheie primară mai trebuie să
respecte două restricţii:
În cazul cheilor compuse, formate din mai multe atribute, nu se poate elimina
un atribut parte din cheie, fără a distruge caracteristica de unicitate a tuplurilor
unei tabele;
Cheia primară nu admite sub nici o formă valori nule, iar în cazul cheilor
compuse, nici un atribut parte din cheie nu poate avea valori nule. Conform
uneia din regulile pe care trebuie să le respecte bazele de date relaţionale,
formulate de Codd (1985), valoarea nul este diferită de valoarea “zero” din
punct de vedere numeric şi de asemenea diferită de un şir de caractere de
lungime zero. Practic, valoarea nul este independentă de tipul de date şi se
foloseşte atunci când informaţiile care ar trebui stocate lipsesc (nu se cunosc).
O alta definiţie, de dată mai recentă, într-o mai detaliată este cea a lui Mike
Chapple (Chapple M., 2006). Cheia primară a unui tabel relaţional identifică în
mod unic fiecare înregistrare din tabel. Aceasta poate sa fie un atribut sau un grup
de atribute al acelui tabel ce are proprietatea de unicitate sau poate să fie un
atribut cu valorile generate de către sistemul de gestiune al bazelor de date utilizat
10 Baze de date – Introducere in SQL Server 2008
(cum este spre exemplu Autonumber pentru Microsoft ACCESS sau Guid în
Microsoft SQL Server).
Cheia primară se consideră a fi o cheie naturală, dacă atributul sau grupul de
atribute care formează cheia, face parte din mulţimea atributelor ce caracterizează
entitatea identificată de cheia primară. Valorile cheii naturale exprimă legăturile
din lumea reală care există între aceasta şi entitatea identificată. Dacă cheia
primară este reprezentată de un atribut cu valori arbitrare, unice, dar care nu
exprimă nicio legătură din lumea reală cu entitatea identificată, se consideră o
cheie surogat.
O tabelă poate avea mai multe atribute sau mai multe grupuri de atribute, care să
îndeplinească simultan condiţiile pentru a fi cheie primară a tabelei. Acestea se
numesc chei candidate, însă doar cea care este aleasă ca identificator al tabelei
este denumită cheie primară.
În notaţia utilizată în paragrafele următoare, cheia primară va fi scrisă cu caractere
îngroşate.
Termenul cheie externă (foreign key), folosit de Codd în articolul din 1970, se
referă la atributele sau grupurile de atribute care pun în legătură rândurile unei
tabele cu rândurile altei tabele. În cazuri excepţionale, pot exista chei externe care
pun în legătură rândurile unui tabel cu înregistrări ale aceluiaşi tabel, privite dintr-
o anumită perspectivă. Altfel spus cheia externă este un atribut sau un grup de
atribute ale unui tabel definite sub formă de cheie primară în alt tabel (sau chiar în
acelaşi tabel) şi serveşte pentru a defini legăturile dintre tabele.
Pe baza noţiunii de cheie externă, s-a dezvoltat conceptul de restricţie de
integritate referenţială. Între două tabele există o restricţie de integritate
referenţială atunci când, dacă valorile cheii externe nu au valori nule, acestea
trebuie să fie neapărat dintre valorile cheii primare cu care se află în legătură.
Conceptul de integritate referenţială, este unul din conceptele fundamentale, care
asigură coerenţa datelor stocate în baza de date.
Capitolul I Concepte şi noţiuni de bază privind 11
bazele de date relaţionale
Datele stocate într-o bază de date, trebuie să fie coerente, să corespundă realităţii.
În acest sens, restricţiile de integritate definesc setul de constrângeri pe care
trebuie să îl respecte datele, în aşa fel încât să fie considerate coerente.
Succint, restricţiile de integritate ale unei baze de date relaţionale, se pot clasifica astfel:
Restricţii de integritate specifice modelului relaţional. Acestea sunt:
Relaţiile care pot exista între două tabele, pot fi de trei tipuri:
1-1 (unu la unu) – în acest tip de relaţie unei valori a cheii primare dintr-
un tabel îî corespunde cel mult o valoare din câmpul cheie externă al
tabelului cu care se află în legătură.
1-n (unu la mai mulţi) – acest tip de relaţie este cel mai întâlnit. Unei
valori a cheii primare dintr-un tabel îi corespund mai multe valori a cheii
externe din tabelul cu care se află în legătură.
m-n (mai mulţi la mai mulţi) – acest tip de relație nu poate fi exprimată
ca o relaţie simplă între două tabele, ci doar prin intermediul unei tabele de
legătură, care va “împărţi” relaţia m-n în două legături: 1-n și n-1.
Orice bază date relaţională, pentru a nu deveni un coşmar atât pentru cei care o
utilizează, cât şi pentru cei care i-au proiectat structura, trebuie structurată corect
în tabele, iar atributele corect repartizate în tabele. Pentru a fi mai expliciţi,
considerăm următorul tabel (într-o variantă simplificată) referitor la facturile
emise de către o firmă:
cele 100 rânduri este chiar probabil să se întâmple acest lucru), acel rând va
figura ca şi cum ar fi facturat în altă zi decât cea a facturării. O eventuală
statistică a facturărilor pe zile, va fi eronată.
Atribute calculate (derivate din altele) – orice atribut care se stochează şi
care este rezultatul unor calcule aplicate unor atribute care sunt şi ele stocate în
cadrul tabelului. În tabelul luat ca exemplu în figura anterioară se observă că
atributul ValoareFacturata este obţinut prin înmulţirea atributelor
CantitateFacturata şi PretFacturare. Această situaţie poate să genereze multe
situaţii neplăcute:
Risipă de spaţiu – cu aceleaşi efecte care s-au amintit anterior.
Risipă de timp şi/sau erori în date – atât la inserare, cât şi la modificare.
Mai mult, dacă se modifică valorile atributelor din care se obţine atributul
derivat, trebuie modificată şi valoarea acestuia.
Având în vedere toate tipurile de anomalii de actualizare şi cele de stocare a
datelor, este clar că pentru a avea o bază de date coerentă, care să nu manifeste
erorile descrise mai sus, se impun:
definirea corectă a atributelor;
structurarea coerentă a acestora în tabele;
stabilirea corectă legăturilor între tabele;
definirea corectă a unor restricţii de integritate asociate.
Acest proces poate fi, în funcţie de context destul de dificil şi subiectiv. Toate
aceste demersuri nu se fac din mers sau după ureche, ci în urma unui proces
complex de analiză a atributelor şi a relaţiilor care există între ele în realitatea care
se modelează, proces care serveşte proiectării unei baze de date corecte.
Există mai multe metode de proiectare a unei baze de date relaţionale, în lucrarea
de faţă autorii nu îşi propun să trateze ăn detaliu teoria proiectării bazelor de date
relaţionale, ci doar o prezentare succintă a părţilor esenţiale din metoda
normalizării.
Se observă că:
CNP → Nume
O singură valoare din CNP poate fi asociată cu o singură valoare din Nume.
CNP → Prenume
O singură valoare din CNP poate fi asociată cu o singură valoare din Prenume.
Nume CNP
O singură valoare din Nume nu poate fi asociată cu o singură valoare din CNP.
16 Baze de date – Introducere in SQL Server 2008
Prenume CNP
O singură valoare din Prenume nu poate fi asociată cu o singură valoare din CNP.
Nume Prenume
O singură valoare din Nume nu poate fi asociată cu o singură valoare din
Prenume.
Prenume Nume
O singură valoare din Prenume nu poate fi asociată cu o singură valoare din
Nume.
Dependenţele funcţionale pot exista şi în cazul grupurilor de atribute. Este posibil
ca atât determinantul cât şi determinatul să fie formate din grupuri de atribute. În
această situaţie, putem generaliza că dacă X este un atribut sau un grup de
atribute şi Y este la rândul lui un atribut sau un grup de atribute, X determină
funcţional pe Y (X→Y), dacă o singură valoare (combinaţie de valori) din X poate
fi asociată cu o singură valoare (combinaţie de valori) din Y.
Exemple:
CNP→(Nume, Prenume)
O singură valoare din CNP poate fi asociată cu o singură combinaţie de valori din
atributele Nume şi Prenume.
Fie tabela Facturi:
SerieFactura NrFactura DataFactura CUIClient DenumireClient
AA 1111 1/1/2008 RO100 XYZ SA
AA 2222 1/1/2008 RO200 ABC SRL
BB 1111 1/1/2008 RO100 XYZ SA
BB 2222 2/2/2008 RO200 ABC SRL
Considerăm trei atribute sau grupuri de atribute pe care le notăm cu A,B,C. Dacă
între A şi B există dependenţă funcţională (A→B) şi între B şi C există
dependenţă funcţională (B→C), între A şi C există de asemenea dependenţă
funcţională, însă este considerată dependenţă funcţională tranzitivă, deoarece
(A→B→C).
Dependenţele funcţionale tranzitive, prezintă interes în interpretarea 3NF.
Exemplu:
În tabela Facturi:
SerieFactura NrFactura DataFactura CUIClient DenumireClient
AA 1111 1/1/2008 RO100 XYZ SA
AA 2222 1/1/2008 RO200 ABC SRL
BB 1111 1/1/2008 RO100 XYZ SA
BB 2222 2/2/2008 RO200 ABC SRL
1NF – un tabel se află în forma normală unu, dacă are toate atributele atomice şi
nerepetitive.
Un atribut este considerat atomic, dacă nu mai poate fi descompus în alte atribute.
Deşi la prima vedere pare o chestiune simplă, atomicitatea atributelor a fost încă
de la începutul enunţării acestor reguli de către Codd, un subiect de controverse.
Aceasta deoarece, dacă ar fi să se respecte strict, atomicitatea atributelor s-ar
constitui într-o limită a bazelor de date relaţionale în anumite situaţii.
Pentru a explica acest lucru, am luat în considerare două exemple „clasice”, ce se
referă la atributele Data (cu sensul de data calendaristică) şi Adresa, care sunt de
fapt în esenţă două atribute compuse, care ar putea fi descompuse în alte atribute
atomice.
Adresa
Orice adresă este un atribut compus, format cel puţin din următoarele
componente: strada, număr, bloc, scară, etaj, apartament.
Descompunerea adresei în componente, poate fi făcută, numai dacă prezintă
interes pentru domeniul aferent bazei de date.
De exemplu, pentru o agenţie imobiliară este clar că prezintă interes utilizarea
unei adrese descompusă în baza de date ca atribute atomice: strada, număr, bloc,
etc. Una este să cauţi un imobil sau o ofertă de vânzare/cumpărare direct după
20 Baze de date – Introducere in SQL Server 2008
stradă şi alta este să cauţi imobilul printr-o prelucrare asupra unui atribut care pe
lângă alte informaţii conţine şi strada.
Dacă ne situăm însă în cazul unui vânzător de carte, există probabilitatea ca pe
acesta să nu îl intereseze stocarea adreselor cumpărătorilor în varianta mai multe
atribute atomice, ci doar ca un singur atribut Adresa.
Având în vedere că SGBD-urile actuale oferă suport si pentru alte tipuri de date
compuse, sau chiar tipuri de date utilizator, decizia privind descompunerea sau
nedescompunerea unui atribut în componente rămâne la latitudinea proiectanţilor
bazelor de date, în funcţie de cerinţe.
2NF – un tabel se află în forma normală doi, dacă se află în forma normală unu şi
toate atributele sale non cheie se află în dependenţă funcţională completă faţă de
cheia primară.
Exemplul 1:
Considerăm tabela Facturi:
Facturi(SerieFactura, NrFactura, Data, CUIClient, DenumireClient)
Cunoscând faptul că o factură se emite unui singur client, avem:
Tabelul respectă 1NF
Între grupul de atribute care este cheie primară (SerieFactura, NrFactura)
şi celelalte atribute există dependenţă funcţională completă, aşa cum se
remarcă din graful dependenţelor funcţionale următor:
SerieFactura, NrFactura
Data
CUIClient DenumireClient
Exemplul 2:
Considerăm tabelul MateriiPrimeConsumate:
Capitolul I Concepte şi noţiuni de bază privind 21
bazele de date relaţionale
MateriiPrimeConsumate(NrBonConsum, CodMatPrima, Cantitate,
DenMatPrima)
Cunoscând faptul că o materie primă consumată nu poate fi menţionată decât o
singură dată pe acelaşi bon de consum, avem:
Tabelul respectă 1NF;
(NrBonConsum, CodMatPrimă)→Cantitate şi
(NrBonConsum, CodMatPrimă)→DenMatPrima
Dependenţa funcţională (NrBonConsum,
CodMatPrimă)→DenMatPrima nu este una completă, deoarece şi
CodMatPrimă→DenMatPrima, ceea ce înseamnă că o componentă din
grupul de atribute (CodMatPrima) care formează cheia primară determină
funcţional un alt atribut din tabel (DenMatPrima), aşa cum se remarcă şi
din graful dependenţelor funcţionale următor:
NrBonConsum, CodMatPrimă
Cantitate DenMatPrima
În concluzie, tabelul nu respectă 2NF. Soluţia pentru a respecta 2NF este un nou
tabel în care va intra dependenţa funcţională parţială dintre
CodMatPrimă→DenMatPrima şi eliminarea acesteia din tabelul
MateriiPrimeConsumate. CodMateriePrima în tabelul MateriiPrimeConsumate
va fi cheie externă (subliniat cu linie întreruptă), însă va face parte din cheia
primară a tabelului.
NrBonConsum, CodMatPrimă
Cantitate DenMatPrima
3NF – un tabel se află în forma normală trei, dacă se află în forma normală doi şi
nu există dependenţe funcţionale tranzitive între cheia primară şi celelalte atribute.
Exemplul 1:
Considerăm tabela Facturi:
Facturi(SerieFactura, NrFactura, Data, CUIClient, DenumireClient)
Cunoscând faptul că o factură se emite unui singur client, avem:
Tabelul respectă 1NF
Tabelul respectă 2NF – aşa cum s-a stabilit anterior
Pentru a stabili dacă respectă 3NF sunt căutate eventualele dependenţe
funcţionale tranzitive între cheia primară şi celelalte atribute:
SerieFactura, NrFactura
Data
CUIClient DenumireClient
SerieFactura, NrFactura
Data
CUIClient DenumireClient
Obţinerea unui model relaţional al bazei de date, în aşa fel încât nevoia de a-l
reproiecta ulterior să fie cât mai redusă. Este evident că modificarea
fundamentală în timp a regulilor de gestiune care se aplică atributelor culese
24 Baze de date – Introducere in SQL Server 2008
Nr. Atribut
crt.
1 CUI client
2 Denumire client
3 Adresa client
4 Telefon client
5 Număr contract
6 Localitate client
7 Tara client
8 Data început contract
9 Data finalizării contract
10 Denumire client contract
11 CNP angajat supraveghere contract
12 Nume angajat
13 Prenume angajat
14 Data angajării
15 Adresa angajatului
16 Telefonul angajatului
17 Data început supraveghere
18 Data sfârşit supraveghere
19 Cod ofertă
20 Descriere ofertă
21 Tarif bază
22 Tarif negociat
23 Data început valabilitate ofertă
24 Data sfârşit valabilitate ofertă
25 Discount acordat
Capitolul I Concepte şi noţiuni de bază privind 25
bazele de date relaţionale
Reguli de gestiune:
Un contract se încheie cu un singur client;
Derularea unui contract este supravegheată de unul sau mai mulţi angajaţi. Un
angajat poate supraveghea un contract pe o perioadă determinată (între Data
început supraveghere şi Data sfârşit supraveghere); Perioada în care un
angajat supraveghează derularea unui contract nu este aceeaşi cu perioada de
derulare a contractului;
Dacă perioada de derulare a unui contract este mare, nu se poate ca acelaşi
angajat să supravegheze contractul în mai multe perioade diferite de timp;
Fiecare contract se bazează pe o singură ofertă de servicii, în urma căruia se
încheie contractul;
Societatea poate avea în derulare simultan mai multe oferte de servicii;
Serviciile ofertate sunt prezentate sub forma unor descrieri netipizate, în care
sunt prezentate detaliile de execuţie ale acestora;
O ofertă de servicii este valabilă într-o singură perioadă de timp (între Data
început valabilitate ofertă şi Data sfârşit valabilitate ofertă), nefiind posibilă
reactivarea unor oferte mai vechi, pentru alte perioade;
Fiecare ofertă de servicii are un tarif fix (Tarif bază), însă în urma
negocierilor, tariful la care se încheie contractul poate fi diferit (Tarif
negociat), datorită unor factori cum ar fi: durata contractului, fidelizare clienţi,
etc;
Discount acordat se calculează ca fiind diferenţa între Tarif bază şi Tarif
negociat;
Notă. Toate relaţiile de calcul determinate din analiza informaţională sunt
asociate regulilor de gestiune.
a). În forma normală unu (1NF), se construieşte o singură tabelă (numită şi
universală) ce va conţine toate atributele, având în vedere toate aspectele
prezentate deja în paragraful 1.3.4. Forme normale. Aceasta va conţine toate
atributele, mai puţin cele:
Sinonime. Atributele sinonime reprezintă de fapt mai multe apariţii ale
aceluiaşi atribut. Una din restricţiile 1NF este ca atributele să nu se repete.
Cele rezultate din calcule pe baza altor atribute. Trebuie făcută menţiunea
că în cazul unor calcule foarte laborioase şi a unor accesări dese a anumitor
atribute calculate proiectanţii unei baze de date, în urma unei analize atente,
pot face excepţii, în sensul că se pot memora în mod controlat şi asemenea
atribute.
26 Baze de date – Introducere in SQL Server 2008
Aspectele legate de 1NF sunt cu mult mai complexe decât par la prima vedere. În
afară de problema atomicităţii atributelor, expusă în paragraful 1.3.4. mai apare o
problemă la înglobarea tuturor atributelor din dicţionarul datelor într-un singur
tabel: stabilirea unei chei primare pentru acest tabel. Având în vedere că un
singur tabel cu toate atributele conţine foarte multe redundanţe, este foarte greu sa
se stabilească o cheie primară formată dintr-un singur atribut. Chiar şi stabilirea
unei chei primare formată ca grup din mai multe atribute poate deveni o problemă.
Nu trebuie uitat că o cheie primară trebuie să nu conţină valori nule şi să aibă
valori unice, aşa cum s-a prezentat şi în paragraful 1.2.1. Stabilirea unei chei
primare pentru tabela universală din 1NF se poate realiza în câteva moduri:
Găsirea unui singur atribut (aproape imposibil, poate doar dacă baza de date
este foarte simplă) sau a unui grup de atribute care să îndeplinească condiţiile
de a fi declarate cheia primară a tabelului (unicitate şi valori nenule);
Capitolul I Concepte şi noţiuni de bază privind 27
bazele de date relaţionale
În cazuri excepţionale se pot desemna chiar toate atributele (teoria permite
acest lucru) tabelei ca fiind cheie primară, cu condiţia să nu mai existe
redundanţe în liniile tabelei.
În cazul în care, chiar dacă s-ar desemna toate atributele ca fiind cheie primară
a tabelului, tot ar mai exista redundanţe în liniile tabelului, atunci se poate
recurge la o cheie surogat (vezi paragraful 1.2.1 pentru detalii), arbitrară, care
nu are legătură cu realitatea ce se doreşte a fi transpusă în baza de date, însă
care asigură unicitatea rândurilor tabelului. Este o soluţie de compromis, însă
având în vedere că este puţin probabil să se utilizeze o bază de date direct în
1NF, poate fi o soluţie rapidă şi acceptabilă în multe situaţii.
Pentru exemplul luat în considerare (pentru simplificare, am ales varianta cu cheie
primară surogat), avem tabela Contracte în 1NF:
Contracte(IDRand, CUICl, DenumireCl, AdresăCl, TelefonCl, LocalitateCl,
TaraCl, NrContract, DataContract, DataFinContract, CNPAngajat, NumeAng,
PrenumeAng, DataAng, AdresăAng, TelefonAng, DataÎnceput, DataSfârşit,
CodOfertă, DescriereOfertă, TarifBază, TarifNegociat, DataÎnceputValab,
DataSfârşitValab)
b) Pentru a face trecerea tabelei din 1NF în forma normală doi (2NF)
trebuiesc identificate toate dependenţele funcţionale complete dintre atribute
(şi/sau grupuri de atribute). Pentru a nu pierde din dependenţele funcţionale şi
pentru a putea fi observate mai uşor, se poate întocmi o matrice (tabel) a
dependenţelor funcţionale care oferă o viziune de ansamblu asupra acestora.
În tabelul următor sunt prezentate toate dependenţele funcţionale complete (notate
cu cifra 1) dintre atribute:
28 Baze de date – Introducere in SQL Server 2008
Observaţii:
Toate atributele (grupurile de atribute) care determină alte atribute prin
dependenţă funcţională completă se numesc determinanţi şi sunt într-o
primă fază chei candidate (vezi paragraful 1.2.1), din care se vor alege
cheile primare ale tabelelor rezultate.
Pentru atributele care nu se află în dependenţă funcţională completă faţă de
nici un atribut (ca determinaţi) şi nici nu determină funcţional alte atribute
se caută grupuri de atribute care să le determine. Este cazul atributelor
DataInceput şi DataSfarsit. Pentru acestea s-a găsit grupul (CNPAngajat,
NrContract) care le determine prin dependenţă funcţională completă:
(CNPAngajat, NrContract)→DataInceput şi (CNPAngajat,
NrContract)→DataSfârşit.
Notă. Dacă regula de gestiune “Dacă perioada de derulare a unui contract
este mare, nu se poate ca acelaşi angajat să supravegheze contractul în
mai multe perioade diferite de timp” ar fi permis ca acelaşi angajat să
supravegheze de mai multe ori în timp acelaşi contract, dependenţele
funcţionale (CNPAngajat, NrContract)→DataInceput şi (CNPAngajat,
NrContract) →DataSfârşit nu sunt valabile.
Eventuale alte dependenţe, gen (CNPAngajat, NrContract)→NumeAng,
nu sunt dependenţe funcţionale complete, deoarece o componentă din
Capitolul I Concepte şi noţiuni de bază privind 29
bazele de date relaţionale
determinant are o dependenţă funcţională cu un alt atribut CNPAngajat
→NumeAng.
Dacă regulile de gestiune permit, este posibil ca un atribut care nu este nici
determinant şi nici determinat să facă parte chiar el dintr-un grup de
atribute care va fi determinant pentru alte atribute.
În cazul în care pentru un atribut care nu este nici determinant şi nici
determinat nu se poate găsi un determinant format dintr-un grup de atribute
(inclusiv varianta în care atributul ar fi inclus în grup), poate fi luată în
considerare şi utilizarea unei chei surogat, cu valori arbitrare, dar care să
asigure unicitatea rândurilor viitorului tabel.
În cazul în care există dependenţe funcţionale reciproce între determinanţi,
pentru a nu avea tabele identice se renunţă la dependenţele unuia dintre ei.
Este cazul CUICl→DenumireCl şi DenumireCl→CUICl. În continuarea
demersului o să luăm în considerare doar dependenţele funcţionale ale
determinantului CUICl.
Având în vedere toate aspectele prezentate, pentru scrierea 2NF, matricea
dependenţelor funcţionale până în acest moment se prezintă astfel:
30 Baze de date – Introducere in SQL Server 2008
DescriereOferta
DataInceputValab
TarifBaza CodOferta
DataSfarsitValab
DataContra
ct NrContract
TarifNegociat DenumireCl
DataFinContract AdresaCl
CUICl
TelefonCl
LocalitateCl
TaraCl NumeAng
PrenumeAng
CNPAngajat
AdresaAng
NrContract, CNPAng
TelefonAng
DataInceput DataSfarsit
DescriereOferta
DataInceputValab
TarifBaza CodOferta
DataSfarsitValab
DataContra NrContract
ct
TarifNegociat DenumireCl
DataFinContr AdresaCl
act CUICl
TelefonCl
LocalitateCl
TaraCl NumeAng
CNPAngaj PrenumeAng
at
NrContract, AdresaAng
CNPAngajat
TelefonAng
DataInceput
DataSfarsit
Client
CUICl, DenumireCl, AdresaCl, TelefonCl, LocalitateCl, TaraCl
1
Oferta
CodOfertă, DescriereOfertă, TarifBază, DataÎnceputValab, DataSfârşitValab
1
Contract n n
NrContract, DataContract, DataFinContract, TarifNegociat, CUICl, CodOferta
1
Lucrează n
n
CNPAngajat, NrContract, DataÎnceput, DataSfârşit
Angajat
1
CNPAngajat, NumeAng, PrenumeAng, DataAng, AdresăAng, TelefonAng
Nr. Atribut
crt.
1 Cod modul
2 Denumire modul
3 Data începerii modul
4 Data finalizării modul
5 Taxa modul
6 Cod disciplină
7 Denumire disciplină
8 Nr ore
9 CNP cursant
10 Nume cursant
11 Prenume cursant
Capitolul I Concepte şi noţiuni de bază privind 35
bazele de date relaţionale
Nr. Atribut
crt.
12 Iniţiale cursant
13 Adresa cursant
14 Telefon cursant
15 Procent reducere
16 Nr contract
17 Data contract
18 Descriere clauze contract
19 Nume prenume cursant
20 Taxa netă contract
21 Total taxe
Reguli de gestiune:
Un modul de curs poate avea în componenţă mai multe discipline.
O disciplină poate să se găsească cu număr de ore diferit, în componenţa
mai multor module.
Un cursant se poate înscrie la mai multe module (chiar dacă se suprapun
perioadele). Pentru fiecare înscriere, se încheie contract distinct, în care se
menţionează clauzele contractuale, procentul de reducere primit la înscriere
şi taxa netă ce urmează a fi plătită de cursant în urma acordării reducerii.
Taxa netă contract este calculată ca fiind diferenţa dintre Taxa modul şi
reducerea calculată pentru un modul, în funcţie de Procent reducere
acordat unui cursant;
Notă. Toate relaţiile de calcul determinate din analiza informaţională sunt
asociate regulilor de gestiune.
a). În forma normală unu (1NF), se construieşte o singură tabelă (numită şi
universală) ce va conţine toate atributele, având în vedere toate aspectele
prezentate deja în paragraful 1.3.4. Forme normale. Aceasta va conţine toate
atributele, mai puţin cele sinonime şi cele rezultate din calcule pe baza altor
atribute.
Se observă că în lista de atribute prezentată iniţial, atributul Nume prenume
cursant este sinonim cu atributele Nume cursant, Iniţiale cursant şi Prenume
cursant. Având în vedere că Nume cursant, Iniţiale cursant şi Prenume cursant
sunt atomice, am optat pentru eliminarea atributului Nume prenume cursant. Se
observă că atributele Taxa netă contract şi Total taxe sunt calculate şi se elimină.
În urma eliminării acestor trei atribute, dicţionarul simplificat al datelor se
prezintă astfel:
36 Baze de date – Introducere in SQL Server 2008
Nr.
Atribut Descriere
crt.
1 CodModul Cod modul
2 DenModul Denumire modul
3 DataIncepere Data începerii modul
4 DataFinalizare Data finalizării modul
5 TaxaModul Taxa modul
6 CodDisciplina Cod disciplină
7 DenDisciplina Denumire disciplină
8 NrOre Nr ore
9 CNPCursant CNP cursant
10 NumeCursant Nume cursant
11 PrenumeCursant Prenume cursant
12 InitialeCursant Iniţiale cursant
13 AdresaCursant Adresa cursant
14 TelCursant Telefon cursant
15 ProcReducere Procent reducere
16 NrContract Nr contract
17 DataContract Data contract
18 Clauze Descriere clauze contract
Observaţie:
Grupul de atribute (CodModul, CodDisciplină) determină atributul NrOre,
deoarece în regulile de gestiune este menţionat că “o disciplină poate să se
găsească cu număr de ore diferit, în componenţa mai multor module”.
c). Pentru a face trecerea de la 2NF la forma normală trei (3NF), dintre
dependenţele funcţionale complete determinate anterior la 2NF, trebuiesc
identificate care sunt dependenţe funcţionale tranzitive. Aceste dependenţe se
vor elimina din tabelele scrise în 3NF. Cea mai simplă variantă de identificare a
dependenţelor funcţionale tranzitive, este desenarea unui graf al dependenţelor
funcţionale deduse la 2NF din baza matricei dependenţelor funcţionale. În graf se
observă foarte uşor care din dependenţele funcţionale sunt directe (pentru a fi
reţinute) şi care sunt dependenţele funcţionale tranzitive. Acestea din urmă vor
forma alte tabele.
În figura următoare este prezentat graful dependenţelor funcţionale, realizat pe
baza matricei dependenţelor funcţionale prezentate la 2NF (cu linie întreruptă sunt
marcate dependenţele funcţionale tranzitive):
PrenumeCursant InitialeCursant
AdresaCursant
TelCursant
NumeCursant
CNPCursant
Clauze
DenModul NrContract
DataIncepere DataContract
DataFinalizare
TarifModul CodModul
CodDisciplina
CodModul, CodDisciplina
DenDisciplina
NrOre
Capitolul I Concepte şi noţiuni de bază privind 39
bazele de date relaţionale
Disciplina(CodDisciplină, DenDisciplina)
Cursant(CNPCursant, NumeCursant, PrenumeCursant, InitialeCursant,
AdresaCursant, TelCursant)
Contract(NrContract, CodModul, DataIncepere, DataFinalizare, CNPCursant,
ProcReducere, DataContract, Clauze)
Modul(CodModul, DenModul, TaxaModul)
ModulDisciplina(CodModul, CodDisciplina, NrOre)
40 Baze de date – Introducere in SQL Server 2008
Contract n
NrContract, CodModul, DataIncepere, DataFinalizare, CNPCursant, ProcReducere, DataContract,
Clauze
n
Modul
1
CodModul, DenModul, TaxaModul
n ModulDisciplina
CodModul, CodDisciplina, NrOre
n
Disciplina
1 CodDisciplină, DenDisciplina
42 Baze de date – Introducere in SQL Server 2008
CAPITOLUL 2
SGBD SQL SERVER
Orice sistem client server este alcătuit din minimum trei componente principale:
interfaţa cu utilizatorul, aplicaţia (prelucrările sau procesele) şi sistemul de
gestiune a bazelor de date. Arhitectura client/server poate fi implementata sub
forma a trei modele.
Arhitectura pe un nivel (one tier architecture) apare când serverul şi clientul sunt
una şi aceeaşi aplicaţie.
În arhitectura pe două nivele (two layer architecture), datele se găsesc într-un alt
mediu şi sunt accesate prin intermediul primului nivel. Această arhitectură descrie
perfect aplicaţiile client-server.
1
În prezent, compania Sybase dezvoltă propriu SGBD iar Ashton-Tate a fost achiziţionată de
Borland. Ashton-Tate a fost compania care s-a făcut cunsocută în domeniul IT printr-un alt SGBD
46 Baze de date – Introducere in SQL Server 2008
Versiunea SQL Server 7.0 din 1998 (cunoscută sub numele de cod Sphinx) a
reprezentat primul server de date pentru care a fost implementată o interfaţă
grafică complexă de administrare şi, în ediţia 1999 (tot versiunea 7.0, dar cu nume
de cod Plato) au fost implementate tehnologiile OLAP.
Au urmat versiunile SQL Server 2000 (nume de cod Shiloh), 2003 (nume de cod
Liberty) şi 2005 (nume de cod Yukon) care au consolidat poziţia SQL Server în
topul primelor 3 cele mai bine vândute SGBD pentru baze de date relaţionale.
În prezent SQL Server este dezvoltat doar de firma Microsoft, devenind una dintre
cele mai importante aplicaţii dezvoltate de către aceasta.
SQL Server 2008 (nume de cod Katmai) este un produs ajuns la maturitate
compatibil cu cele mai recente tehnologii existente.
Ca şi versiunile precedente, SQL Server 2008 este disponibil în mai multe ediţii
ce diferă prin facilităţile oferite, resursele hardware capabile să le exploateze
(număr de procesoare, memorie RAM, etc.) şi politica de licenţiere (număr de
utilizatori, costuri licenţe, etc.)
Principalele ediţii ale SQL Server 2008 sunt:
Enterprise
Reprezintă soluţia cu cele mai extinse facilităţi. Oferă utilizatorilor toate
instrumentele necesare privind administrarea şi securitatea datelor precum şi un
set complet de instrumente pentru dezvoltarea aplicaţiilor business intelligence.
Standard
Ediţia Standard pune la dispoziţia utilizatorilor toate instrumentele pentru
administrarea bazelor de date şi pentru programare utilizând Transact SQL.
Principalele diferenţe faţă de ediţia Enterprise constau în lipsa unor facilităţi
specifice Datawarehouse, numărul limitat de procesoare pe care le poate exploata
serverul (4 la ediţia Standard, pe când la Enterprise numărul de procesoare este
limitat doar de posibilităţile sistemului de operare) şi numărul de instanţe ale
serverului ce pot fi create (16 în cazul Standard. şi 50 în cazul Enterprise).
Versiunea Standard este disponibilă şi într-o variantă numită SQL Server
Standard for Small Business care este limitată la accesarea serverului de pe
maxim 75 de staţii-client.
Developer
Este o ediţie dedicată dezvoltatorilor de aplicaţii. Această ediţie prezintă toate
facilităţile disponibile în varianta Enterprise dar nu este destinată utilizării ca
server productiv, ci doar pentru teste şi programare.
(Dbase)
Capitolul II SGBD SQL SERVER 47
Workgroup
Varianta Workgroup este destinată firmelor de dimensiuni mai mici. Oferă toate
funcţionalităţile necesare pentru administrarea datelor şi include instrumente
pentru raportare.
Capacitatea de procesare a datelor este limitată pentru maxim 2 procesoare şi 3
GB memorie RAM. Este o soluţie pentru costuri reduse (o licenţă de server cu 5
utilizatori poate fi achiziţionată la circa 750 USD, faţă de varianta Enterprise care
necesită peste 12.000 USD)
Web
Este o soluţie indicată pentru administrarea bazelor de date ce urmează a fi
exploatate în mediul online. Poate fi utilizată atât pentru site-uri cu un trafic redus
cât şi pentru a gestiona baze de date ce deservesc portaluri web cu cerinţe ridicate
din punct de vedere al fluxurilor de date
SQL Server Express
Reprezintă o soluţie oferită gratuit pentru utilizatorii ce doresc să realizeze
aplicaţii client pentru sisteme de mici dimensiuni sau pentru a învăţa. Oferă
funcţionalităţi de bază pentru administrarea datelor.
SQL Server Expres este componenta menită să înlocuiască Microsoft Desktop
Engine din versiunile mai vechi şi este integrată în Microsoft Visual Studio 2008.
Această soluţie poate fi oricând upgradată, dacă se doreşte utilizarea facilităţilor
din alte ediţii.
Compact
Varianta Compact este o soluţie gratuită pentru gestionarea bazelor de date
destinate aplicaţiilor de tip desktop, a aplicaţiilor pentru mobile devices sau de tip
client web pe platforme Windows.
Convenţii în Descriere
sintaxe scrise
MAJUSCULE Cuvintele cheie T-SQL sunt scrise cu
majuscule în cadrul sintaxelor.
italic Parametrii care trebuie să fie furnizaţi de
către utilizator.
bold Nume de proceduri, tabele, coloane, etc.
| (bară Sugerează că în cadrul sintaxelor, dacă avem
verticală) cuvinte separate prin bara verticală, doar
una din posibilităţi trebuie folosită.
[ ] Elemente de sintaxă opţionale.
50 Baze de date – Introducere in SQL Server 2008
Exemplul 2:
SELECT * FROM Facturi.dbo.Produs
Se vor selecta toate câmpurile din tabelul Produs din baza de date Facturi, de pe
serverul curent unde se execută fraza SQL. Tabelul Produs aparţine de schema
dbo. Practic în această variantă de scriere, nu mai are importanţă baza de date de
unde se execută fraza SQL.
Exemplul 3:
SELECT * FROM [s-win-sql-cig\cig].Facturi.dbo.Produs
Se vor selecta toate câmpurile din tabelul Produs din baza de date Facturi, de pe
serverul [s-win-sql-cig\cig]. Practic în această variantă de scriere, nu mai
are importanţă baza de date de unde se execută fraza SQL şi nici serverul. Dacă
sistemul de securitate permite accesarea obiectelor de pe serverul [s-win-sql-
cig\cig], nu mai are importanţă serverul SQL unde se execută fraza SQL.
Exemplul 4:
SELECT * FROM dbo.numefunctie()
Se vor selecta toate coloanele returnate de funcţia numefunctie() care aparţine
de schema dbo. Aşa cum am amintit, la apelarea funcţiilor de finite de utilizator
se scrie obligatoriu şi schema de care aparţin.
Instrucţiunea INSERT
Permite adăugarea de noi înregistrări într-un tabel.
Sintaxă simplificată:
INSERT
{ nume_tabel | nume_view }
{ [ ( lista_coloane ) ]
{ VALUES ( [ ,...n] )}
}
| DEFAULT VALUES
Unde:
nume_tabel– reprezintă numele tabelului în care se vor insera înregistrări;
nume_view - reprezintă numele unui view actualizabil în care se vor insera
înregistrări;
(lista_coloane) – reprezintă lista de câmpuri în care vor fi adăugate
valori. Se vor preciza între paranteze şi se vor separa prin virgulă.
VALUES - este utilizată pentru a introduce o listă de valori specificate
pentru fiecare câmp în parte.
52 Baze de date – Introducere in SQL Server 2008
Instrucţiunea DELETE
Permite ştergerea de înregistrări.
DELETE
[ TOP ( expression ) [ PERCENT ] ]
FROM <tabel>]
[ WHERE { <criterii>] [; ]
Unde:
TOP ( expression ) [ PERCENT ] –specifică un număr de
înregistrări sau un procent din numărul total de înregistrări ce vor fi şterse.
În cadrul instrucţiunilor Insert, Delete şi Update, înregistrările nu pot fi însă
ordonate.
FROM <tabel> - specifică numele tabelului din care se vor şterge
înregistrările.
WHERE <criterii> - permite specificarea uneia sau mai multor condiţii
pentru limitarea numărului de înregistrări ce vor fi şterse. Condiţiile vor fi
separate prin operatorii logici AND/OR. Lipsa clauzei WHERE va conduce
la ştergerea tuturor înregistrărilor.
Instrucţiunea UPDATE
Permite actualizarea înregistrărilor.
UPDATE
[ TOP ( expression ) [ PERCENT ] ] { <tabel|view> }
SET { nume_coloană = { expresie }
[ WHERE { <condiţii> [; ]
Instrucţiunea SELECT
Probabil cea mai utilizată instrucţiune, permite selecţia înregistrărilor din una sau
mai multe tabele, realizarea de calcule precum şi grupări de date.
Sintaxa instrucţiunii este complexă, dar poate fi sintetizată la următoarele clauze
de bază:
Interogări cu subinterogari
Utilizarea subinterogărilor se bazează pe faptul că o instrucţiune SELECT poate fi
utilizată pentru a returna una sau mai multe înregistrări, ce pot fi folosite într-o
altă instrucţiune INSERT, DELETE, UPDATE sau SELECT.
Atunci când subinterogarea returnează mai multe înregistrări, pentru comparaţii,
se pot utiliza cuvintele cheie:
IN (testează apartenenţa unei valori la o mulţime)
ANY ori SOME (compară o valoare cu oricare element al unei mulţimi)
ALL (compară o valoare cu toate elementele unei mulţimi)
EXISTS (verifică dacă o instrucţiune SELECT a returnat un rezultat)
Câteva exemple de utilizare a subinterogărilor sunt prezentate în subcapitolul 2.4
din prezenta lucrare.
Ex. 5: Calculaţi câţi furnizori are firma în fiecare localitate si afişaţi lista ordonata
descrescător pentru localităţile in care exista mai mult de 20 de furnizori.
SELECT LocalitateCL, Count(CUIcL) AS [Total Clienti]
FROM Client
GROUP BY LocalitateCL
HAVING Count(CUIcL)>20
ORDER BY [Total Clienti]
Ex. 6: Calculaţi Valoarea totala a contractelor pe fiecare luna din anul 2008 şi
afişaţi rezultatele doar pentru lunile in care au existat mai mult de 3 contracte.
SELECT Month(DataContract) AS Luna,
Sum(TarifNegociat) As Total
FROM Contract
WHERE DataContract BETWEEN '1/1/2008' AND '12/31/2008'
GROUP BY Month(DataContract)
HAVING Count(TarifNegociat)>3
Ex. 7: Să se obţină lista o listă a contractelor încheiate după 1 ianuarie 2008. Se
va specifica şi numele şi ţările clienţilor contractanţi.
--Soluţia 1 (exprimarea legăturii în clauza FROM)
SELECT NrContract, DataContract, DenumireCl, ŢaraCl
FROM Client INNER JOIN Contract
ON Client.CUICl=Contract.CUICl
WHERE DataContract >= '1/1/2008'
sau
--Soluţia 2 (exprimarea legăturii în clauza WHERE)
SELECT NrContract, DataContract, DenumireCl, ŢaraCl
FROM Client, Contract
WHERE DataContract >= '1/1/2008'
AND Client.CUICl=Contract.CUICl
CAPITOLUL 3
DESCRIEREA DATELOR
Descrierea datelor se referă la operaţiile de creare a bazei de date, definirea
câmpurilor tabelelor, stabilirea cheilor primare, implementarea eventualelor
restricţii şi descrierea legăturilor cheie primară-cheie externă prin intermediul
diagramelor de relaţii
Toate aceste operaţii pot fi realizate prin instrucţiuni Transact SQL sau prin
intermediul interfeţei grafice oferite de Microsoft SQL Server Management
Studio1.
De exemplu, pentru crearea unei baze de date se poate utiliza comanda T-SQL
CREATE DATABASE, iar pentru ştergere DROP DATABASE.
Exemplu:
-- crearea bazei de date
CREATE DATABASE Test1
-- ştergerea bazei de date
DROP DATABASE Test1
Crearea unei baze de date se
poate realiza la fel de simplu
selectând secţiunea Databases
în panoul Object Explorer şi
alegând opţiunea New
Database din meniul
contextual.
Întrucât interfaţa SQL Server Management Studio este extrem de uşor de utilizat
şi prezintă o multitudine de facilităţi pentruu descrierea datelor, în capitolul de
faţă nu se va insista pe comenzile T-SQL, ce pot substitui aceste facilităţi.
1
Aplicaţia SQL Server Management Studio poate fi accesată prin intermediul meniului Start
Programs Microsoft SQL Server SQL Server Management Studio
Capitolul III DESCRIEREA DATELOR 61
Cheia primară se poate stabili selectând câmpul cheie şi, din meniul contextual, se
va alege opţiunea Primary Key.
Pentru câmpurile pentru care nu se doreşte să fie acceptată valoare Null în
momentul introducerii datelor se va preciza acest lucru în coloana Allow Nulls.
După completarea numelor de câmpuri şi a tipurilor de date, fereastra de
proiectare a tabelului se poate închide, precizând un nume pentru tabel în
momentul în care se solicită salvarea acestuia.
Tabelele create se vor regăsi în folderul
Tables al bazei de date. Prin apelarea
meniului contextual pe un tabel selectat
sunt disponibile, printre altele, următoarele
opţiuni:
Design (permite redeschiderea
tabelului în modul de proiectare)
Select Top 1000 rows (va afişa
primele 1000 înregistrări)
Edit Top 200 rows (va deschide
tabelul [n modul de editare/adăugare
afişând primele 200 de înregistrări)
Principale tipuri de date din SQL Server sunt prezentate în tabelul următor:
62 Baze de date – Introducere in SQL Server 2008
Capitolul III DESCRIEREA DATELOR 63
64 Baze de date – Introducere in SQL Server 2008
Atribuirea unei
valori implicite
pentru câmpul
Studii
Atribuirea unei
formule de calcul
pentru câmpul
TVA
Avantaje
Indecşii au rolul de a reduce volumul de date ce trebuie citit pentru ca o interogare
să returneze setul de rezultate solicitat întrucât căutarea pe baza unui index
presupune consultarea unor valori cheie ordonate şi nu parcurgerea tuturor
înregistrărilor din tabele..
Prin crearea de indecşi conform cu cele mai frecvente cereri de interogare se pot
ameliora în mod semnificativ performanţele obţinute la consultarea bazei.
Nu în ultimul rând, câmpurile index pot fi utilizate pentru a impune unicitatea
realizărilor pentru un anumit câmp din baza de date.
Proiectarea superficială a indecşilor sau lipsa acestora vor conduce la performanţe
scăzute în exploatarea bazelor de date. Crearea indecşilor trebuie însă sa pună in
balanţa avantajele conferite de obţinerea mai rapidă a rezultatelor pe de o parte, şi
creşterea spaţiului de stocare necesar, de cealaltă parte.
Indecşii creaţi pe câmpuri ce permit domenii largi de valori şi cei creaţi pe baza
mai multor câmpuri vor solicita spaţiu suplimentar de stocare.
Observaţie: Indecşii pot fi modificaţi sau steri fără a modifica modelul bazei de
date. SQL Server permite optimizarea interogărilor prin selecţia celui mai eficient
index de căutare dintre cei disponibili.
Tipuri de indecşi
Principalele tipuri de indecşi utilizaţi in SQL Server sunt:
Indecşi de tip Cluster ( in acest caz datele din tabel sunt memorate şi sortate
conform valorilor indexului. Intr-un tabel nu poate exista decât un index de tip
cluster. In cazul intr-un tabel nu a fost definit un index de tip cluster, datele din
tabel sunt memorate fără nici un criteriu de ordonare.
Index de tip Non-Cluster: Acest tip de indecşi au o structura separata de
înregistrările tabelului si nu afectează în vreun fel modul de ordonare în care
sunt memorate acestea. Doar valorile din cadrul indexului sunt ordonate, nu si
cele din tabelul asociat. Fiecare valoare a indexului are alocat un indicator ce
permite regăsirea rapidă a înregistrărilor aferente. Un indicator de la o valoare
a indexului către o înregistrare este numit “pointer” sau “row locator”.
Full Text Index reprezintă un tip special de indecşi gestionaţi prin
intermediul serviciului Microsoft Full-Text Engine for SQL Server
(MSFTESQL). Acest tip oferă avantaje în cazul interogărilor complexe asupra
datelor de tip şir de caractere.
Indecşi de tip XML
Capitolul III DESCRIEREA DATELOR 67
Crearea indecşilor
Indecşii pot fi creaţi prin comenzi SQL sau, mai simplu, utilizând interfaţa SQL
Server Management Studio.
In momentul stabilirii cheii primare a unui tabel este creat automat un index de tip
cluster. In momentul in care un câmp este creat cu clauza UNIQUE i se asociază
automat un index de tip non cluster.
Alţi indecşi pentru un tabel se pot adăuga deschizând tabelul în modul de
proiectare şi apelând din meniul Table Designers Indexes/Keys…
2
Fereastra indexes-keys poate fi accesata prim intermediul meniului Table Designer.
68 Baze de date – Introducere in SQL Server 2008
La nivelul tabelelor se pot stabili reguli de validare pentru fiecare câmp în parte
(de exemplu se poate impune apartenenţa valorilor câmpului la un domeniu de
valori), dar şi reguli de validare bazate pe compararea valorilor mai multora dintre
câmpurile ale tabelului.
Pentru a implementa astfel de reguli, se va deschide tabelul în modul de proiectare
şi din meniul Table Designers se va selecta opţiunea Check Constraints.
Figura următoare ilustrează fereastra Check Constraints. Proprietăţile ce trebuie
completate sunt Name (numele restricţiei) si Expression (condiţia ce trebuie
îndeplinită).
Dacă se doreşte realizarea unei legături cheie primară – cheie externă fără a
impune integritatea referenţială, se va modifica proprietatea Enforce foreign key
constraint (în cadrul diagramei respectiva legătura va fi trasată cu linie punctată).
În fereastra de proprietăţi a diagramei se pot specifica pentru fiecare legătură
cheie primară-cheie externă dacă se doreşte ştergerea sau actualizarea în cascadă
(în cadrul secţiunii INSERT AND UPDATE specification)
În general, pentru a evita procesarea unui volum mare de date atunci când o
operaţie de actualizare nu a produs modificări asupra datelor, în cadrul triggerelor
se testează ce rezultate au avut asupra datelor operaţiile care au declanşat
triggerul.
Astfel, cu ajutorul funcţiei UPDATE() se poate determina in interiorul unei
proceduri trigger ce coloane urmează a fi actualizate. (Sintaxa este
UPDATE(nume_câmp) si se poate utiliza in contextul unei structuri de tip IF
pentru a evalua realizările câmpului care au suferit modificări).
O altă modalitate de a determina daca în urma unei comenzi au fost afectate
înregistrări este utilizarea funcţiei @@ROWCOUNT care returnează numărul de
înregistrări ce au fost afectate de o interogare.
Declanşatorii sunt executaţi imediat după operaţia de actualizare, dar înainte ca
aceasta sa fie încheiată in baza de date, utilizându-se tehnica tranzacţionării
operaţiilor.
Conceptul de tranzacţie
Tranzacţionarea este o tehnică prin care este asigurată coerenţa bazei de date în
cursul actualizării acesteia.
O tranzacţie reprezintă un set de operaţii de actualizare care, fie se execută toate,
fie nici una. Operaţiile cuprinse într-o tranzacţie nu pot fi executate parţial: dacă
una dintre ele eşuează atunci toate celelalte sunt anulate.
O tranzacţie poate fi:
Salvată (commited) – când toate operaţiile tranzacţiei au fost încheiate cu
succes iar baza de date este actualizată cu noile modificări.
Derulată înapoi (rollback) – toate operaţiile tranzacţionate sunt anulate iar
baza de date este restaurată la starea dinaintea tranzacţiei.
Într-un mediu multiuser, datele actualizate prin intermediul unei tranzacţii nu sunt
vizibile altor utilizatori decât numai la salvarea tranzacţiei.
Execuţia unei operaţii de modificare/adăugare/ştergere şi a procedurii trigger pe
care o declanşează pot fi considerate o singura tranzacţie.
Dacă declanşatorul generează o eroare se va executa o comandă ROLLBACK
TRANSACTION şi toate operaţiile sunt anulate.
Sintaxe si exemple
Instrucţiunea prin care se poate crea un declanşator este CREATE TRIGGER, iar
instrucţiunea prin care se poate modifica un declanşator este ALTER TRIGGER.
(sintaxa este similară instrucţiunii CREATE TRIGGER).
Instrucţiunea prin care se poate şterge un declanşator este:
DROP TRIGER nume_trigger
Dacă, în loc de FOR se utilizează INSTEAD OF, instrucţiunile SQL din cadrul
triggerului înlocuiesc operaţia de tip INSERT, UPDATE sau DELETE care nu
se mai execută.
Exemplul 1
Fie tabelul ANGAJATI (CodAngajat, Nume, Functie, Salariu, CodDepartament)
Realizaţi un trigger pentru operaţia de ştergere care sa nu permită ştergerea
angajaţilor care au CodDepartament=1.
72 Baze de date – Introducere in SQL Server 2008
Exemplul 1
Realizaţi un trigger care sa nu permită modificarea salariului unui angajat la o
valoare mai mica decât salariul pe care îl are în momentul actualizării.
Capitolul III DESCRIEREA DATELOR 73
IF EXISTS(SELECT *
FROM DELETED, INSERTED
WHERE DELETED.CodAngajat=INSERTED.CodAngajat
AND DELETED.SALARIU>INSERTED.SALARIU)
BEGIN
RAISERROR('NU SE POATE SUB MINIM', 18,2)
ROLLBACK TRANSACTION
END
Observaţii:
Instrucţiunea SELECT operează atât pe tabelul INSERTED, unde sunt memorate
temporar noile valori ale salariilor, cât şi pe tabelul DELETED unde se pot regăsi
valori ce urmează a fi înlocuite. Sunt comparate salariile din DELETED cu cele
din INSERTED pentru acelaşi angajat si, daca există măcar un caz în care noua
valoare a salariului este mai mică, se anulează tranzacţia prin instrucţiunea
ROLLBACK TRANSACTION.
Exemplul 3
Realizaţi un trigger care sa adauge in tabelul Arhiva_Angajaţi toţi angajaţii ce vor
fi şterşi din tabelul Angajaţi. Tabelul Arhiva_Angajaţi are următoarele câmpuri:
CodA, Nume, DataPlecare. DataPlecare se va completa automat cu data la care a
fost şters angajatul
CAPITOLUL 4
INTEROGAREA DATELOR
Exemplul 1
SELECT getdate()
Capitolul IV INTEROGAREA DATELOR 77
Exemplul 2
În acest exemplu vom prezenta modul cum se specifică corect o dată
calendaristică introdusă de utilizator în formatul propriu (dd/mm/yyyy), dar
transformată cu ajutorul funcţiei CONVERT:
Exemplul 3
Utilizarea funcţiei CONVERT pentru transformarea datelor de natura numerică:
SELECT TOP 5 NrContract, TarifNegociat,
CONVERT(decimal(20,1), TarifNegociat) As TarifOZecimala,
CONVERT(numeric(20,2), TarifNegociat) As Tarif2Zecimal2
FROM Contract FROM Contract
Exemplul 4
Utilizarea componentei timp, din data calendaristică:
Funcţia CAST
Are acelaşi rolul ca şi funcţia convert (converteşte rezultatul unei expresii într-
un anumit timp de date) . Sintaxa este mai simplă şi nu prezintă toate facilităţile
funcţiei convert:
CAST(Expresie AS Tip de data)
Funcţia DAY
Returnează ziua dintr-o dată calendaristică.
Sintaxa:
DAY (expresie)
Capitolul IV INTEROGAREA DATELOR 79
Funcţia MONTH
Returnează luna dintr-o dată calendaristică.
Sintaxa:
MONTH(expresie)
Funcţia YEAR
Returnează anul dintr-o dată calendaristică.
Sintaxa:
YEAR(expresie)
Exemplu
SELECT top 5 day(DataContract) as Zi,
month(DataContract) as Luna,
year(DataContract) as An
FROM Contract
Funcţia DATEPART
Extrage dintr-o data calendaristica/ora o anumită informatie calendaristica,
identificata printr-un cod.
Sintaxa:
DATEPART (informaţie_calendaristica, expresie_data/ora)
În tabelul următor sunt prezentate câteva valori uzualepentru parametrul
informatie_calendaristica:
Cod
Rezultat
informatie_calendaristica
year An
month Luna
day Zi
dayofyear Numar zi din an
quarter Trimestru
80 Baze de date – Introducere in SQL Server 2008
Exemplu
Extragerea din data curentă a serverului a mai multor informaţii calendaristice.
Funcţia DATEDIFF
Sintaxa:
DATEDIFF(informaţie_calendaristica, data/ora start, data/ora final)
SELECT
DATEDIFF(DAY, CONVERT(datetime, '15/6/2006', 103),
CONVERT(datetime, '1/1/2009', 103)) as ZILE,
DATEDIFF(MONTH, CONVERT(datetime, '15/6/2006', 103),
CONVERT(datetime, '1/1/2009', 103)) as LUNI,
DATEDIFF(YEAR, CONVERT(datetime, '15/6/2006', 103),
CONVERT(datetime, '1/1/2009', 103)) as ANI,
DATEDIFF(DAYOFYEAR, CONVERT(datetime, '15/6/2006', 103),
CONVERT(datetime, '1/1/2009', 103)) as NRZILE,
Capitolul IV INTEROGAREA DATELOR 81
Funcţia DATEADD
Sintaxa:
DATEADD (informaţie_calendaristica, n, data/ora start)
Calculează o data calendaristică (viitoare sau anterioară), plecând de la o anumită
dată calendaristică (data/ora start) la care se adăuga un n (in format informaţie
calendaristică aşa cum a fost prezentat la funcţia DATEPART). În cazul în care
se doreşte calcularea unei date anterioare faţă de data luată ca bază (data/ora
start), argumentul n se precizează cu minus.
Exemplu
Calcularea datei de peste 1000 zile faţă de data de 1/1/2009 şi a datei de acum
10000 zile faţă de 1/1/2009.
SELECT
DATEADD(DAY, 10000, CONVERT(datetime, '1/1/2009', 103))
as DataViitoare,
DATEADD(DAY, -10000, CONVERT(datetime, '1/1/2009', 103))
as DataAnterioara
82 Baze de date – Introducere in SQL Server 2008
Funcţia LEN
Sintaxa:
LEN(expresie)
Returnează numărul de caractere dintr-o expresie.
Funcţia LOWER
Sintaxa:
LOWER(expresie)
Returnează şirul de caractere din expresie scris cu litere mici.
Funcţia UPPER
Sintaxa:
UPPER(expresie)
Returnează şirul de caractere din expresie scris cu litere mari.
Capitolul IV INTEROGAREA DATELOR 83
Exemplu
Funcţia LEFT
Sintaxa:
LEFT(expresie, n)
Returnează n caractere de la stânga unei expresii şir de caractere
Funcţia RIGHT
Sintaxa:
RIGHT(expresie, n)
Returnează n caractere de la dreapta unei expresii şir de caractere
Funcţia SUBSTRING
Sintaxa:
SUBSTRING (expresie, start, n)
Returnează n caractere dintr-o expresie şir de caractere, începând de la poziţia
start.
Exemplu
RIGHT(RTRIM(NumeAng), 4) as PatruDreapta,
SUBSTRING(NumeAng, 3, 2) as DouaDupaTrei
FROM Angajat
Funcţia POWER
Returnează valoarea unui număr ridicat la o putere.
Sintaxa
POWER(expresie numerică,puterea)
Exemplu:
Funcţia ABS
Funcţia SIGN
Sintaxa: SIGN(expresie numerică)
Returnează una dintre valorile:
-1 dacă expresia este negativă
0 dacă expresia este zero
+1 dacă expresia este pozitivă
Exemplu:
SELECT SIGN(-10) AS EX1, SIGN(0) AS EX2 , SIGN(100) AS EX3
Funcţiile de tip agregat pot fi utilizate in expresii într-o frază SQL în cadrul uneia
dintre următoarele instrucţiuni/clauze:
SELECT
HAVING
COMPUTE
Dacă o funcţie agregat este utilizată în cadrul instrucţiunii SELECT, celelalte
câmpuri preluate din sursa de date în instrucţiunea SELECT se vor regăsi drept
câmpuri de grupare în cadrul instrucţiunii GROUP BY.
Clauza HAVING permite specificarea de condiţii la nivelul grupurilor de
înregistrări .
Instrucţiunea COMPUTE permite calcularea de totaluri generale sau subtotaluri
şi este specificată la sfârşitul instrucţiunii de selecţie (după ORDER BY).
Specificarea opţiunii DISTINCT în cazul funcţiilor AVG, SUM sau COUNT
permite ca valorile identice să fie considerate o singură dată în momentul
efectuării calculelor.
Specificarea simbolului * între parantezele funcţiei COUNT va conduce la
numărarea tuturor valorilor domeniului pe care se aplică funcţia, inclusiv a
valorilor nule.
Exemple:
Se dă tabelul Colaboratori:
Funcţii de clasificare
ROW_NUMBER( ) OVER (< order_by_clause > )
Atribuie un număr de ordine fiecărei înregistrări in funcţie de un criteriu de
ordonare specificat în clauza OVER.
Capitolul IV INTEROGAREA DATELOR 89
Alte funcţii
ISNULL ( expresie , valoare de inlocuit )
90 Baze de date – Introducere in SQL Server 2008
Funcţia ISNULL evaluează dacă o expresie conţine valoarea NULL şi, în cazul în
care condiţia este îndeplinită, înlocuieşte expresia cu valoarea specificată ca al
doilea argument .
ISDATE (expresie )
Funcţia ISDATE verifică dacă o expresie poate fi evaluată ca o dată calendaristică
validă. În cazul în care condiţia este îndeplinită returnează valoarea 1, în caz
contrar 0.
ISNUMERIC(expresie)
Exemplul 1
Utilizarea din SQL:
SELECT NEWID ()
Exemplul 2
Utilizarea în cadrul proprietăţii Default Value or Binding, într-un tabel unde cheia
primară CodModul, este de tip uniqueidentifier:
Capitolul IV INTEROGAREA DATELOR 91
Funcţia CASE
Sintaxa varianta 1:
CASE expresieA
WHEN expresieB1 THEN expresie_Rezultat
[WHEN expresieB2 THEN expresie_Rezultat]
…
[ELSE expresie_Rezultat_F]
END
În această variantă funcţia evaluează expresieA şi în cazul în care rezultatul
acesteia verifică rezultatul evaluării pentru expresieB1 (sau expresieB2, etc.), se
execută expresie_Rezultat. În cazul în care nu se verifică niciuna din expresiile
expresieB1, expresieB2, … se va executa expresie_Rezultat_F.
92 Baze de date – Introducere in SQL Server 2008
Sintaxa varianta 2:
CASE
WHEN expresie_logica1 THEN expresie_Rezultat
[WHEN expresie_logica2] THEN expresie_Rezultat
…
[ELSE expresie_Rezultat_F]
END
Exemplul 2
Să se calculeze o primă anuală acordată fiecărui angajat, ca procent din tariful
negociat al fiecărui contract la care a lucrat, în funcţie de numărul de zile pe care
le-a lucrat. Procentul din tariful negociat este:
5% pentru cei care au lucrat sub 50 zile la un contract;
7% pentru cei care au lucrat între 50 şi 100 zile la un contract;
9% pentru cei care au lucrat între 100 şi 150 zile la un contract;
11% pentru cei care au lucrat între 150 şi 300 zile la un contract;
12% pentru cei care au lucrat peste 300 zile la un contract;
Figura 2
96 Baze de date – Introducere in SQL Server 2008
Figura 3
Figura 4
Nota: accesarea unui View dintr-o fraza SQL se realizează respectând sintaxa
unei fraze SELECT:
SELECT lista_atribute
FROM NumeView
…….
Exemplul 1
Definirea unui View pentru calcularea numărului de angajaţi care a lucrat la
fiecare contract.
Exemplul 3
Crearea unui View indexat pentru afişarea contractelor din 2008:
Exemplul 2
Definirea unui View distribuit pentru afişarea contractelor încheiate, din două baze
de date diferite (CarteBDA şi CarteBDA_server), care sunt stocate pe servere
diferite ([10.1.3.3\CIGTOTAL] şi [FM-PC]) aflate în locaţii geografice diferite.
FROM [FM-PC].CarteBDA_server.dbo.Contract
ORDER BY DataContract
Notă: pentru a putea executa o frază SQL care foloseşte date de pe mai multe
servere se execută în prealabil procedura sistem (o singura dată pentru fiecare
server): sp_addlinkedserver nume_server
sau
EXEC ListaContracte @Data1=’1/1/2007’, @Data2=, ‘1/1/2008’
In exemplul precedent, nespecificarea valorii pentru unul dintre cei doi parametri
va genera o eroare şi imposibilitatea de a executa procedura. Pentru a
preîntâmpina astfel de situaţii, parametrilor de intrare li se pot asocia valori
implicite, care vor fi utilizate automat atunci când nu se precizează o altă valoare.
Aceste valori se specifică imediat după declararea fiecărui parametru.
Pentru a atribui valoarea implicită ‘1/1/2000’ parametrului @Data1 şi ‘1/1/2009’
parametrului @Data2 se va modifica procedura astfel:
EXECUTE AflaMaximPeClient
@ValMax=@Variabila OUTPUT, @Client='RO1001'
Observaţie:
Orice procedură stocată care se execută cu succes va returna valoarea zero.
Procedurile stocate care provoacă la execuţie o eroare vor returna un cod
negativ (de la -1 la -14)
IF expresie_logica
Bloc_insctructiuni_SQL_1
[ELSE
Bloc_instructiuni_SQL_2]
Instrucţiunea WAITFOR
Sintaxa:
WAITFOR DELAY ‘timp_aşteptare’ | TIME ‘ora_execuţie’
Stabileşte un timp de întârziere (timp_aşteptare) până la momentul lansării în
execuţie a unei fraze SQL sau stabileşte ora (ora_execuţie) la care se va lansa în
execuţie o frază SQL. Este utilă mai ales la programarea unor operaţii în perioade
timp în care nu se lucrează (de exemplu o operaţie complexă care nu presupune
intervenţia unui utilizator şi se poate executa noaptea).
Exemplul 1
Afişarea peste un minut a tuturor contractelor:
WAITFOR DELAY '00:01'
SELECT * FROM Contract
Exemplul 2
Afişarea tuturor angajaţilor la ora 22:48
WAITFOR TIME '22:48'
SELECT * FROM Angajat
Exemplul 3
Se doreşte majorarea treptată cu câte 10% a tarifelor de bază pentru fiecare ofertă,
până când media generală a tarifelor de bază depăşeşte media generală a tarifelor
negociate din contracte.
În acest sens, s-a definit codul SQL următor:
Observaţii:
Prin intermediul instrucţiunii RETURNS se precizează tipul de date al valorii
returnate de funcţie.
Prin intermediul instrucţiunii RETURN se specifică efectiv valoare de returnat
rezultată în urma calculelor din comenzile SQL precizate în corpul funcţiei
(între BEGIN şi END). În corpul funcţiei, între BEGIN şi END pot fi incluse
structuri repetitive, declaraţii de variabile, etc. Valoarea returnată nu poate fi
de tip tabel, motiv pentru care nu pot fi utilizate în clauza FROM a unei
instrucţiuni SELECT, însă pot fi utilizate în SELECT, WHERE, GROUP BY,
HAVING şi ORDER BY.
Numele complet al unei funcţii este dat de următorul specificator:
NumeBazaDate.NumeProprietarFunctie.NumeFuncţie
La apelarea unei funcţii definite de utilizator dintr-o frază SQL, trebuie precizat în
mod obligatoriu proprietarul funcţiei (de exemplu dbo). Numele bazei de date se
precizează doar dacă funcţia executată provine din altă bază decât cea unde se
face apelul către ea. În cazul în care funcţia trebuie executată de alt utilizator decât
proprietarul, acesta trebuie să aibă dreptul de EXECUTE asupra acesteia.
Informaţii despre o funcţie se pot obţine folosind următoarea procedură de sistem:
sp_help funcţie
Capitolul IV INTEROGAREA DATELOR 111
Exemplul 1
Se dau de la două dintre tabelele din modelul proiectat în primul capitiol al cărţii.
CLIENTI (CUICl, DenumireCL, AdresaCL, LocalitateCl, TaraCL )
CONTRACTE(NrContract, DataContract, DataFinContract, TarifNegociat , CodClient)
Se doreşte realizarea unei funcţii pentru calculul unui discount ce se aplica la
valoarea contractelor (tariful negociat) după următoarele criterii:
Pentru contractele de la clienţii din afara României cu valoare sub 1000 se
aplica 5 % la valoare contract
Pentru contractele de la clienţii din afara României cu valoare peste 1000 se
aplica 7% la valoare contract
Pentru contractele de la clienţii din România se aplica 10% la valoare contract
CREATE FUNCTION DISCOUNT(@VALC AS MONEY,
@TARA AS VARCHAR(50))
RETURNS money
AS
BEGIN
RETURN
CASE
WHEN @TARA<>'Romania' AND @VALC<1000 THEN @VALC*0.05
WHEN @TARA<>'Romania' AND @VALC>=1000 THEN @VALC*0.07
ELSE @VALC*0.1
END
END
Ulterior putem utiliza funcţia în cadrul unui View după cum se poate observa în
figura următoare:
Exemplul 2
Se doreşte să se realizeze o funcţie pentru a calcula pentru fiecare dintre clienţii cu
care nu mai sunt contracte în derulare în prezent câte săptămâni au trecut de la
finalizarea ultimului contract.
Pentru clienţii la care încă se mai lucrează la ultimul contract (nu s-a ajuns la data
de finalizare) funcţia va returna valoarea 0.
CREATE FUNCTION CalculSaptamani (@CodC as char(30))
RETURNS int
AS
BEGIN
DECLARE @UltimaData as datetime
SET @UltimaData = (SELECT max(DataFinContract)
FROM CONTRACT
WHERE CUICl=@CodC)
RETURN
CASE
WHEN @UltimaData>=GETDATE() THEN 0
ELSE Datediff(week, @UltimaData, getdate())
END
END
Exemplul 3
Se doreşte alocarea unor coduri contractelor pentru realizarea unor clasificări şi
verificări ulterioare. Codurile vor fi alcătuite din: primele 3 caractere din
denumirea ţării din care provine clientul, urmate de caracterul de pe poziţia a doua
din numele clientului, apoi, ultimele doua cifre din anul în care s-a semnat
contractul şi numărul zilei din an în care s-a finalizat contractul.
Capitolul IV INTEROGAREA DATELOR 113
RETURN @COD1+@COD2+@COD3+@COD4
END
Utilizarea funcţiei pentru a afişa lista codurilor aferente contractelor este
exemplificată în interogarea următoare:
Exemplu
Realizaţi o funcţie prin intermediul căreia să se determine care sunt primii 10
clienţi cu cele mai multe contracte. Funcţia va returna codurile clienţilor şi
numărul total de contracte.
INSTRUCŢIUNI SQL
RETURN
END
Exemplu
Realizaţi o funcţie prin intermediul căreia să se determine care sunt primii 10
clienţi cu cele mai multe contracte. Funcţia va returna codurile clienţilor şi
numărul total de contracte.
RETURN
END
Putem utiliza funcţia în cadrul unei proceduri stocate ce afişează lista contractelor
cu clienţii importanţi, contractate de la începutul anului 2008 astfel:
SELECT NrContract, DataContract, TarifNegociat,
DenumireCl, AdresaCl
FROM CONTRACT INNER JOIN CLIENT ON
Contracte.CodClient=Clienti.Codclient
WHERE CLIENTI.CodClient IN (SELECT CodClient FROM
dbo.CLIENTI_IMPORTANTI() )
AND DataContract>'1/1/2008'
Exemplu
Se doreşte realizarea unei funcţii care să returneze lista contractelor finalizate într-
o anumită perioadă şi, pentru fiecare dintre acestea, 50% din valoarea contractata
(tariful negociat).
116 Baze de date – Introducere in SQL Server 2008
RETURN
END
FETCH
[ [ NEXT | PRIOR | FIRST | LAST
| ABSOLUTE { n | @nvar }
| RELATIVE { n | @nvar } ]
FROM
]
Nume_cursor
[ INTO @variable_name [ ,...n ] ]
ABSOLUTE { n | @nvar}
dacă n este un număr pozitiv se returnează înregistrarea cu numărul n,
calculată în raport cu începutul cursorului.
dacă n este un număr negativ se returnează înregistrarea cu numărul n,
calculată în raport cu sfârşitul cursorului.
f. Variabila @@FETCH_STATUS
Determina daca mai exista înregistrări de accesat in cursor. Valori posibile:
0 – instrucţiunea FETCH pentru accesarea unei înregistrări s-a executat cu
succes.
-1 – instrucţiunea FETCH pentru accesarea unei înregistrări a eşuat.
-2 – instrucţiunea FETCH pentru accesarea unei înregistrări nu a returnat
niciun rezultat.
Exemplu
Sa se definească o procedură stocată care să folosească un cursor pentru
următoarele operaţii:
parcurgerea unui set de înregistrări virtuale, secvenţial, înainte, cu media
tarifelor negociate ale fiecărei oferte folosite în contracte.
daca media tarifelor negociate a unei oferte din cursor este mai mare decât
o valoarea transmisă printr-un parametru procedurii stocate se va majora cu
10% tariful de bază al ofertei (în tabelul Oferta).
FROM Contract
GROUP BY CodOferta
Apelul procedurii stocate cu parametrul 4000 (se vor lua în considerare din cursor
doar mediile tarifelor de bază mai mari de 4000):
2. Realizaţi un View pentru a calcula totalul încasărilor din anul 2007 pe fiecare
client. Pentru clienţii la care totalul încasărilor depăşeşte 40000 se va calcula un
BONUS de 2% din total încasări.
Capitolul IV INTEROGAREA DATELOR 123
Figura 6 View
RETURN
END
Exemplu de utilizare:
SELECT * FROM ListaPeAn(2006)
Exemplu de utilizare:
EXEC Clasament 6000
Capitolul IV INTEROGAREA DATELOR 125
OPEN CRS
CLOSE CRS
DEALLOCATE CRS