Professional Documents
Culture Documents
1.1 Uvod
SQL jezik inovirala je tvrtka IBM, polazeći od osnovnih operacija relacijskih baza podataka,
kako ih je definirao Codd . SQL je neproceduralni jezik IV generacije. Pod time se
podrazumijeva, da nije potrebno definirati korake ( proceduru) izvođenja, nego se definira
«što želimo kao rezultat i način kako će rezulatat biti prikazan». Naredbe jezika dijele se u
dvije skupine:
Ime
Prezime
DatumRodjenja
StudijID
PostaID
Dakle, prikazane su sve kolone i svi retci tablice, pri čemu je poredak redaka slučajan,
najčešće onim redom kako su retci upisivani u tablicu.
Često nam nisu potrebne sve kolone, pogotovu kod tablica s većim brojem kolona. Kolone
koje želimo prikazati pobrojimo poslije ključne riječi SELECT, pa komanda kojom ćemo
prikazati samo Ime i Prezime studenta izgleda:
Ime Prezime
Ivo Ivic
Ana Matic
Tomislav Butorovic
Ana Marija Tomic
Marko Markovic
Helena Topic
Hrvoje Antic
Ante Zelic
Često želimo prikaz samo nekih redaka tablice i to onih koji zadovoljavaju određeni uvjet.
Prikažimo Ime i Prezime studenata koji su upisani na studij «Matematike – Informatike».
Pregledom tablice Studiji:
StudijID Studij
1 Matematika - Informatika
2 Tehnicka kultura - Informatika
3 Matematika
4 Matematika - Fizika
5 Biologija - Kemija
nalazimo, da studij Matematike – Informatike ima oznaku StudijID=1. Tako će upit za prikaz
imena i prezimena studenata Matematieke – Informatike biti:
FROM Studenti
WHERE StudijID=1
Ime Prezime
Ivo Ivic
Ana Matic
Tomislav Butorovic
FROM Studenti
WHERE StudijID=1
ORDER BY Prezime
Ime Prezime
Tomislav Butorovic
Ivo Ivic
Ana Matic
Dakle, SQL – upitna komanda nad jednom tablicom ima opći oblik:
FROM Tablica
[ WHERE uvjet ]
Kako Sustav za upravljanje relacijskom bazom podataka ( RDBMS ) izvodi ovaj upit (tablica
nema definiranih indeksa ):
Kako nema definiranih indeksa ( ili kada je tablica s malim brojem redaka) izvodi
potpuno skeniranje tablice, dakle kreće od prvog do posljednjeg retka
- Ime varchar(50)
- Prezime varchar(50)
Pročita prvi redak tablice Studenti i ako je vrijednost kolone StudijID=1, upiše vrijednosti
Ime i Prezime u radnu tablicu. U slučaju da StudijID nije 1, ide na slijedeći redak.
Nedostatak gornjih upita je taj, što brojčane oznake StudijID nisu dovoljno opisne, tj. iako
vidimo oznaku studija, ne znamo o kojem se studiju radi, naravno, ne želimo li stalno tražiti
naziv studija u tablici Studiji. Na sreću, SQL upitni jezik provodi i operaciju prirodnog
spajanja dviju ili više tablica:
ORDER BY Prezime
Rezultat ovog upita je relacija, prikazana kao Kartezijev produkt tablica Studenti i Studiji.
Dakle, svaki redak tablice Studenti je udružen sa svakim retkom tablice Studiji. Kako Studenti
sadrži 8 redaka, a Studiji 5, to rezultantana tablica sadrži 40 redaka. Uočavamo da neki retci
ne sadrže istinite podatke: student Hrvoje Antić je upisan na studij 2 – Tehnicka kultura –
Informatika ( lijeva kolona StudijID u tablici ), pa povezivanje sa studijima 1, 3, 4 i 5 ne odgovara
istini. Zato u pravilu, operaciju prirodnog spajanja ograničavamo na retke koji sadrže istinite podatke,
dakle:
WHERE Studenti.StudijID=Studiji.StudijID
ORDER BY Prezime
Rezultat upita je virtualna tablica, pod čime se misli da ne postoji njen fizički zapis na
mediju, npr. disku, nego se dinamički izgrađuje pri izvođenju upita.
Uobičajeni naziv za ovakav oblik spajanja tablica je «spajanje jednakosti» ( eng. «equi –
join»).
Izvedimo sličan upit, kojim ćemo prikazati ime, prezime, poštanski broj i naziv pošte
studenta:
Marko Markovic
Razlog leži u nedefiniranim poštanskim brojevima ( prigodom prijave, studenti nisu prijavili
adresu, jer su bili u fazi preseljenja ). No, mi želimo prikazati sve studente, čak i ako nije
definiran poštanski broj. Naravno, ako pošta nije poznata, neće biti ispisana.
FROM Studenti
ORDER BY Prezime
Ime Prezime PostaID PostaID Posta
Hrvoje Antic 23000 23000 Zadar
Tomislav Butorovic 21000 21000 Split
Ivo Ivic 21000 21000 Split
Marko Markovic NULL NULL NULL
Ana Matic 22000 22000 Sibenik
Ana Marija Tomic NULL NULL NULL
Helena Topic 20000 20000 Dubrovnik
Ante Zelic 53000 53000 Gospic
Engleski termin ovog oblik spajanja je LEFT OUTER JOIN, što možemo prevesti kao
«spajanje slijeva», a prikazuje sve retke u tablici s lijeve strane ključne riječi (Studenti). Svaki
redak tablice Studenti će pokušati spojiti s tablicom Poste preko identičnih vrijednosti kolona
PostaID i prikazati naziv pošte, kad god je spajanje uspješno, odnosno NULL vrijednost kad
spajanje nije moguće.
Kako Sustav za upravljanje relacijskom bazom podataka ( RDBMS ) izvodi ovaj upit (tablice
nemaju definirane indekse ):
Kako nema definiranih indeksa ( ili kada je tablica s malim brojem redaka) izvodi
potpuno skeniranje tablice, dakle kreće od prvog do posljednjeg retka tablice Studenti
- Ime varchar(50)
- Prezime varchar(50)
- PostaID int ( iz tablice Studenti)
- PostaID int ( iz tablice Poste)
- Posta varchar(50)
FROM Studenti
ORDER BY Studiji.StudijID
Ovim upitom prikazuju se sve moguće studijske grupe, te studenti onih studijskih grupa koje
imaju upisane studente. Studiske grupe bez studenata, isto tako su navedene, ali naravno bez
pridruženih studenata.
1.2.4 Unutrašnje ( Inner Join ) spajanje
U nekim prilikama, ipak želimo prikaz samo onih redaka koji se mogu spojiti s
odgovarajućim recima druge tablice. Recimo, kada trebamo uputiti pisma na adrese studenata,
studenti bez adrese trebaju biti ispušteni iz prikaza:
FROM Studenti
ORDER BY Prezime
Isti rezulata se dobije i primjenom «Equi-join» spajanjem, no ipak «INNER JOIN» zapis
potpunog spajanja ima prednost, jer u komandi jasno razlikuje klauzulu restrikcije WHERE
od spajanja INNER JOIN.
Dakle, sintaksa potpune upitne komande koja izvršava projekciju, potpuno i nepotpuno
spajanje, restrikciju i određivanje poretka je:
FROM Tablica1
[ WHERE uvjet ]
Često trebamo neke izračunate podatke, čija se vrijednost temelji na baznim podacima,
upisanim u tablici. Prikažimo ime i prezime studenata u jednoj koloni, spajanjem kolona ime i
prezime, te ukupni broj slova imena i prezimena ( razmak nije uključen). Retke je potrebno
poredati po dužini teksta, tako da student s najdužim imenom i prezimenom bude na vrhu
poretka:
FROM Studenti
Sintaksa Opis
LEFT( Tekstualni izraz, n ) Izdvaja n pozicija s lijeva iz tekstualnog izraza
( obično tekstualna kolona tablice)
RIGHT( Tekstualni izraz, Izdvaja n pozicija s desna iz tekstualnog izraza
n) ( obično tekstualna kolona tablice)
SUBSTRING( Tekstualni Izdvaja D znakova iz tekstualnog izraza, počev od
izraz, S, D) pozicije S izraza
LEN( Tekstualni izraz ) Daje dužinu ( broj slova ) tekstualnog izraza
Primjeri:
FROM Studenti
Inicijal Prezime
I. Ivic
A. Matic
T. Butorovic
A. Tomic
M. Markovic
H. Topic
H. Antic
A. Zelic
FROM Studenti
2 zadnja slova
prezimena Prezime
ic Ivic
ic Matic
ic Butorovic
ic Tomic
ic Markovic
ic Topic
ic Antic
ic Zelic
c) Prikazati 3 slova imena studenta, počev od 3. slova
FROM Studenti
3 slova počev od
3. Pozicije Ime
o Ivo
a Ana
mis Tomislav
aM Ana Marija
rko Marko
len Helena
voj Hrvoje
te Ante
SELECT *
FROM Studenti
WHERE Ime='Ivo'
e) Prikazati sve studente čije ime sadrži slovo i na bilo kojoj poziciji.
SELECT *
FROM Studenti
f) Prikazati sve studente kojima naziv pošte sadrži slovi i na bilo kojoj poziciji.
FROM Studenti
g) Prikazati sve studente kojima naziv pošte sadrži slovi i na bilo kojoj poziciji.
FROM Studenti
h) Prikazati ime, prezime i dužinu imena svim studentima, čije je ime duže od 5 slova.
Poredati po dužini imena.
SELECT Ime, Prezime, LEN(Ime)
FROM Studenti
ORDER BY LEN(Ime)
Duzina
Ime Prezime Imena
Helena Topic 6
Hrvoje Antic 6
Tomislav Butorovic 8
Ana Marija Tomic 10
g) Prikazati ime i prezime studenta u jednoj koloni, te svaku pojavu malog slova a, zamijeniti
velikim slovom A.
FROM Studenti
Ime Prezime
Ivo Ivic
AnA MAtic
TomislAv Butorovic
AnA MArijA Tomic
MArko MArkovic
HelenA Topic
Hrvoje Antic
Ante Zelic
a) Zanima li nas koliko imamo ukupno studenata u tablici Studenti, izvest ćemo upit:
SELECT count(*)
FROM Studenti
(No column name)
8
Dakle, count(*), pri čemu * da nas zanima broj redaka, bez obzira na definiranu vrijednost
kolona, će izbrojati ukupni broj redaka tablice.
b) Ispišimo sada ukupni broj studenta, te broj studenata koji imaju definiranu adresu
(PostaID):
FROM Studenti
BrojStudenata ImaDefiniranuPostu
8 6
c) Ispišimo broj studenata na svakoj studijskoj grupi. Grupe na kojima nema upisanih
studenata nije potrebno prikazati, te poredati prema broju studenata na grupi, počev od
najbrojnije grupe:
FROM Studenti
GROUP BY StudijID
StudijID count(*)
1 3
2 3
3 2
Kako programski sustav za upravljanje relacijskom bazom podataka( RDBMS) izvodi ovaj
upit ( Pretpostavka je da tablica nije indeksirana):
RDBMS prevede definiranu komandu SQL upita u niz poziva primitivnih procedure
Count1 int
Krene od prvog retka tablice Studenti i upiše vrijednost StudijID ( 1 ) u radnu tablicu, te
brojačkoj koloni Count dodijeli vrijednost 1.
Prelazi na slijedeći redak i ponovno pronalazi StudijID=1. Kako oznaka studija postoji u
radnoj tablici, uveča brojač pojava Count za 1, te on sada iznosi 2.
Ove korake ponavlja sve do posljednjeg redka tablice, te svaki put kada naiđe na
veijednost StudijID, koja ne postoji u tablici, stvori redak. Ako oznaka studija postoji u
radnoj tablici, uvečava joj brojač za 1.
d) Gore dobiveni rezultat je ispravan, ali nije razumljiv, jer oznake studija nisu deskriptivne.
Zato bismo radije čitali rezultat uz puni naziv studijske grupe, pa zato moramo spojiti tablicu
Studiji, gdje se opisi nalaze:
FROM Studenti S
GROUP BY Studij
Studij BrojStudenata
Matematika - Informatika 3
Tehnicka kultura - Informatika 3
Matematika 2
e) Zahtijeva li se prikaz samo onih studijskih grupa, na kojima je opisano više od 2 studenta,
upit će biti:
FROM Studenti S
GROUP BY Studij
Studij BrojStudenata
Matematika - Informatika 3
Tehnicka kultura - Informatika 3
f) Želimo li pak, ispisati sve studijske grupe, te ukupan broj studenata upisan na svaku
studijsku grupu, uključujući i grupe na kojima nema upisanih studenata, upit će biti:
FROM Studiji ST
GROUP BY Studij
Studij BrojStudenata
Biologija - Kemija 0
Matematika 2
Matematika - Fizika 0
Matematika - Informatika 3
Tehnicka kultura - Informatika 3
FROM Studenti S
ORDER BY Prezime
h) Isto tako, možemo ispisati sve studente, čija je prosječna ocjena veća ili jednaka 3.5:
FROM Studenti S
LEFT OUTER JOIN StudentiOcjene SO ON S.StudentID=SO.StudentID
ORDER BY Prezime
i) Konačno, ispišimo sve studente s adresom 21000 ( Split ) koji imaju prosječnu ocjenu 3.5
ili veću, te ukupan zbroj ocjena i prosječnu ocjenu svakog studenta, a rezltate poredajmo po
abecednom redu prezimena:
AVG(Ocjena*1.0) As ProsječnaOcjena
FROM Studenti S
WHERE PostaID=21000
ORDER BY Prezime
a) Ispišimo sve studente Studijske čije ime ili prezime započinje slovom a :
FROM Studenti
Ime Prezime
Ana Matic
Ana Marija Tomic
Hrvoje Antic
Ante Zelic
Uvjet će biti zadovoljen ako Ime ili prezime započinje slovom A, pa su ova dva uvjeta
povezana logičkim operatorom OR.
FROM Studenti
Ime Prezime
Ante Zelic
Uvjet je zadovoljen samo u slučaju kada ime započinje slovom A, a prezime slovom Z, pa su
ova dva uvjeta vezana logičkim operatorom AND.
FROM Studenti
Ime Prezime
Hrvoje Antic
Bilo koji od logičkih izraza može biti negiran, odnosno, rezultirat će istinom kada ne-negirani
uvjet daje laž.
d) Potrebno je izlistati sve studente, kojima ima ili prezime započinje slovom A, a da im
je PostaID=22000:
FROM Studenti
Gornji upit nije dao očekivani rezultat, jer vidimo da samo jedan od tri studenta prebiva na
PostaID=22000. Problem je uzrokovan logičkim povezivanjem elementarnih uvjeta. Naime,
kao što kod računskih operacija množenje ima veći prioritet od zbrajanja, tako logički
operator AND ima veći prioritet od OR operatora.
Zato gornji uvjet zadovoljava svaki redak, čim ime započinje slovo A.
Redoslijed razvijanja pojedinih elementarnih uvjeta možemo odrediti upotrebo zagrada, pa je
ispraljeni upit :
FROM Studenti
FROM Studenti
WHERE StudijID IN ( 1, 3, 5 )
FROM Studenti
a) Prikažimo sve studente koji studiraju na istoj studijskog grupi kao student čije je prezime
Ivić.
Upit 1:
SELECT StudijID
FROM Studenti
WHERE Prezime='Ivic'
Upit 2:
FROM Studenti
WHERE StudijID=1
FROM Studenti
FROM Studenti
WHERE Prezime='Ivic')
b ) Komplementarno gornjem upitu, možemo ispisati sve studente koji nisu upisani na isti
studij kao student Ivić:
FROM Studenti
FROM Studenti
WHERE Prezime='Ivic')
Uočimo, upotrebu ključne riječi NOT, kojom se označava da uvjet zadovoljavaju svi studenti,
čija je vrijednost StudijID različita od 1, tj. nemaju StudijID isti kao student Ivić.
c) Ispišimo sve studente, koji studiraju na studijskim grupama, na kojima je upisano više od 2
studenta.
FROM Studenti
FROM Studenti
GROUP BY StudijID
HAVING count(*) > 2)
SELECT LEFT(Ime, 1)
FROM Studenti
ORDER BY 1
Inicijal
A
A
A
H
H
I
M
T
U slučaju velikog broja redaka u tablici, ovakav prikaz bi bio potpuno nepregledan, pa želimo
vidjeti samo jedinstvene pojave svakog slova, jer nas saznanje da imamo jednog ili više
studenata čije ime započinje s A zadovoljava:
ORDER BY 1
Inicijal
A
H
I
M
T
Ključna riječ DISTINCT označava da se retci s istom vrijednošću svih kolona, prokažu samo
jednom.
Stvori privremenu radnu tablicu s kolonama kako je navedeno u SELECT klauzuli, dakle
u našem primjeru, s jednom kolonom.
Izvodi upit pretražujući tablicu, provjeravajući zadovoljenje uvjeta ako postoji, poziva
funkciju LEFT, koja vraća prvo slovo imena.
Upisuje vrijednosti projeciranih kolona onih redaka koji zadovoljavaju uvjet u radnu
tablicu
Pretraži radnu tablicu ispisujući svaki put samo prvu pojavu retka, preskačući retke koji
imaju iste vrijednosti u svim kolonama, kao već ispisani redak.
Pri upisu retka u tablicu, vrijednosti nekih kolona mogu biti nepoznate, te ih moramo ostaviti
nedefiniranim. Naravno, neke kolone moraju imati obavezno unijete vrijednosti, pa se pri
kreiranju tablice zahtijeva obavezan unos vrijednosti. U našem primjeru tablice Studenti, ime,
prezime i studijska grupa moraju biti unijete, a PostaID, te datum rođenja mogu ostati
nedefinirane. Nedefinirana vrijednost naziva se Null vrijednost.
FROM Studenti
Uočimo da se Null vrijednost testira ključnom rječju IS Null i da test = Null, gdje je znak
jednakosti zamijenio ključnu riječ IS, ne mora dati očekivani rezultat. Naime, o postavkama
baze podataka ovisi rezultat test = Null, no to prelazi okvire ovih skripta.
b) Prikažimo sve studente koji imaju definiranu vrijednost PostaID, dakle PostaID IS
NOT Null :
FROM Studenti
U prethodnom poglavlju smo izvodili upite nad već definiranim tablicama u koje su
prethodno unijeti podaci. U ovom poglavlju ćemo definirati i izvoditi komande kojima se
stvaraju, mijenjaju i uništavaju objekti relacijske baze. Različiti sustavi za upravljanje
relacijskim bazama ( RDBMS ) pružaju mogućnost definiranja nekih specifičnih objekata, no
svi sigurno podržavaju mogućnost kreiranja, mijenjanja i uništavanja tablica, pogleda ( views)
i indeksa.
Isto tako, valja napomenuti da je mnogo prokladniji način stvaranja objekata korištenjem
grafičkog korisničkog sučelja. Lakše je klikom miša odabrati željenu akciju ili tip podatka,
nego pamtiti sintaksu komandi, te ćemo najvjerojatnije objekte baze kreirati koristeći grafički
interfejs i pokazivačku jedinicu ( miš ) na razvojnom računalu. U fazi implementacije baze na
ciljnom računalu ili većem broju ciljnih računala, bilo bi veoma neprikladno ponavljati niz
već odrađenih «klikova». Srećom, danas korišteni sustavi relacijskih baza mogu generirati
komande za stvaranje bazbih objekata. Mi moramo komande razumjeti i biti u stanju zadati ih
ručno.
Tablica sadrži kolone i retke. Kolone se moraju definirati prigodom stvaranja tablice, a retci
se stvaraju unosom vrijednosti u tablicu. Tablica predstavlja fizičku implementaciju entiteta, a
kolone atributa. Tablica je određena korisničkim imenom kreatora i imenom tablice. Isti
korisnik mora svakoj tablici odabrati jedinstveno ime. Različiti korisnici mogu koristiti ista
imena za svoje tablice. Kako jedan sustav za upravljanje relacijskim bazama može u isto
vrijeme upravljati s više baza na istom stroju, kažimo da je tablica određena preko tri
komponente:
Baza.Korisnik.Tablica
Atributi Opis
Ime Slobodno unijeti tekst, maksimalne dužine 30 znakova,
obavezan unos
Prezime Slobodno unijeti tekst, maksimalne dužine 30 znakova,
obavezan unos
DatumRodjenja Datum, unos nije obavezan
StudijID Cio broj, s vrijednostima od 1 do 255, obavezan unos. Opis
brojčane oznake pogledati u tablici Studiji
PostaID Cio broj, s vrijednostima od 10000 ( Zagreb) do 99999, unos
nije obavezan. Opis brojčanih vrijednosti pogledati u tablici
Poste
Kod kreiranja tablice je veoma važno odabrati odgovarajući tip podatka svake kolone.
Na taj način onemogućavamo unos nesuvislih ili nemogućih podataka, barem u onoj mjeri
koliko je to moguće. Pojasnimo primjerom: ako bi kolona DatumRodjenja bila tekstualnog
tipa, onda bi bo moguć unos datuma 30.02.2002, no znamo da veljača ne može imati 30 dana.
Zato je važno da kolona DatumRodjenja bude datumskog tipa, pri čemu baza neće dopustiti
unos nemogućeg datuma. Dakle, pravilnim izborom tipa podatka kolone sprečavamo
nemoguće unose, no neispravni unosi još su uvijek moguću: npr. osobi rođenoj 2. siječnja
1980, još je uvijk moguće nepažnjom unijeti datum rođenja 1. veljače 1980.
DatumRodjenja datetimeNull,
Tablicu Studenti, stvorenu gornjom komandom mogli smo kreirati i preko grafičkog
korisničkog sučelja.
Želimo li ponovno stvoriti tablicu s istim imenom, postojeću moramo najprije uništiti, jer nisu
moguće dvije tablice s istim imenom.
Pri kreiranju tablice Studenti, propustili smo kreirati kolonu PostaID. Vrlo je čest slučaj da se
tijekom eksploatacije baze podataka moraju dodati neke kolone, kao posljedica naknadog
proširenja zahtjeva. Uništavanje, radi ponovnog kreiranja tablice nije moguće jer su podaci
već upisani, a to bi značilo njihov gubitak. Dapače, tablicu će koristiti postojeća aplikacija, pa
ona ne smije biti nedostupna. Zato su nam na raspolaganju komande za dodavanje novih
kolona, te za promjenu postojećih. Iz praktičnih razloga, nastojimo nikada ne uništiti
postojeće kolone, jer neki segment aplikacije koji se poziva na stara imena kolona, neće raditi.
Kolone možemo dodavati bez bojazni po greške postojećih aplikacija, naravno ako se
pridržavamo i nekih drugih «praktičnih pravila» o kojima će biti riječi u slijedećem poglavlju.
Kolonu nije moguće dodadi uz zabranu Null vrijednosti ( NOT NULL ), ako nije definirana
predefinirana ( default) vrijednost.
Navedimo i komandu za uništavanje kolone, iako je dobro izbjegavati takvu praksu, iz ranije
opisanih razloga:
Pri izmjenama tipa podataka iz tipa većeg opseg vrijednosti u manji opseg, moramo
osigurati da već upisane vrijednosti ne prelaze novi, manji opseg.
Mijenjamo li maksimalno dopušteni broj znakova u kolonama varijabilne širine, može doći do
gubitka dijela unosa koji ne stane u novu, manju dimenziju. Neke RDBMS će prijaviti grešku:
U praksi ćemo vrlo često trebati ispise iz tablice Studenti povezane s tablicama Studiji i Poste,
jer nas u pravilu zanima naziv studija i pošte. Da bi olakšali pretraživanje i izbjegli složenost
često korištenih upita, stvorit ćemo pogled ( view) Vstudenti, koji će povezivati potrebne
tablice. Isto tako, javlja se potreba da neke kolone ne budu dostupne stanovitoj grupi
korisnika, dok ih neka druga skupina može čitati. U našem primjeru, zadržat ćemo kolonu
DatumRodjenja skrivenom u pogledu Vstudenti.
AS
FROM Studenti S
Sada je ispis imena, prezimena, naziva studija, poštanskog broja i naziva pošte, krajnje
jednostavan:
SELECT *
FROM Vstudenti
RDBMS pogled tretira kao virtualnu tablicu, dakle ne čita je s medija ( diska ) nego dinamički
izgrađuje za vrijeme izvođenja upita, baš kao da smo zadali upit:
FROM Studenti S
SELECT *
FROM VStudenti
Pogled koji više ne trebamo, ili ga želimo ponovno kreirati, možemo uništiti komandom:
Cilj ovog poglavlja su naredbe SQL jezika za stvaranje objekata relacijske baze, pa tako i
indeksa. Analizom upita, planiranjem indeksa, te ostalih potankosti vezanih uz indekse se
bavimo u posebnom poglavlju, a ovdje samo kratko pojasnimo pojam i značaj indeksa.
Pretpostavimo da želimo pronaći u telefonskom imeniku splitskog područja sve osobe čije je
prezime Ivić. Zadatak ćemo brzo obaviti, jer je imenik poredan po abecednom redu prezimena
pretplatnika. No, ako bi zadatak bio pronaći sve osobe koje žive u Teslinoj ulici, potrošili bi
mnogo više vremena. Jednostavno, morali bi krenuti od prvog pretplatnika, na prvoj stranici
imenika, te svakom pretplatniku pregledati ulicu. Postupak provjere ulice bi provodili jednom
po jednom, svim pretplatnicima, sve do posljednjeg na zadnjoj stranici imenika. Razlog za
potpuno čitanje imenika leži u činjenici da je imenik sortiran po abecedi prezimena, ali ne i po
ulicama. Dakle, imenik je indeksiran po prezimenu. Kada bi željeli isti imenik sortiran i po
ulicama, to bi radi uštede papira mogli napraviti na ovaj način: dodati stranice s abecednim
popisom ulica, te kod svake ulice nabrojati sve stranice i retke u kojima ćemo pronaći
pretplatnike s adresom u Teslinoj ulici. To bi vjerojatno značilo, da bi brzo pronašli Teslinu
ulicu i onda bismo za svakog pretplatnika morali pronaći stranicu, te ponovno za slijedećeg
pretplatnika skoknuti na stranicu indeksa ulica, pročitati na kojoj se stranici nalazi slijedeći
pretplatnik i tako redom. Dakle, indeksiranjem se značajno ubrzava pretraživanje.
Shvatimo naredbu za kreiranje indeksa kao sortiranje podataka u određenom poretku (slučaj
abecednog poretka po prezimenima), odnosno, kao dodavanje stranica s abecednim poretkom
ulica i pokazivačima stranica i redaka na kojima su pretplatnici date ulice.
Naravno, mi želimo indeksirati tablicu studenti, po prezimenu, kako bismo u tablici s mnogo
redaka brzo pronašli traženo prezime ( naredbom je stvoren indeks koji odgovara indeksiranju
ulica u gornjem tekstu).
Postupak stvaranja indeksa u velikim tablicama, s nekoliko stotina tisuća i miliona redaka,
može potrajati nekoliko minuta.
- stvaranje
Definicija objekta
- uništavanje
Cjeloviti informacijski sustav izgrađuje niz ekranskih formi – prozora preko kojih
upisujemno, mijenjamo ili brišemo podatke u tablicama relacijske baze, služeći se
programskim objektima za spajanje na bazu i rad sa skupovima podataka. No, pored toga, u
svim fazama života baze podataka, postavlaju se nepredviđeni upiti, a isto tako se obavljaju
ad hock izmjene podataka, pa stoga treba obratiti potrebnu pažnju i steći potrebnu sigurnost i
samopouzdanje u korištenju naredbi za manipulaciju podacima.
Upišimo novog studenta u tablicu Studenti, čije je ime Marko, prezime Marić, rođen je
07.08.1980. i upisan je na studijsku grupu 1. Poštanski broj njegove adrese za sada nije
poznat.
Primjetimo da nakon ključne riječi INSERT INTO slijedi ime tablice, te lista kolona u koje će
biti upisani podaci, dok ključnu riječ VALUES slijedi lista vrijednosti. Lista kolona i lista
vrijednosti moraju se podudarati po broju i tipu podataka. Sustav će javiti grešku ako:
upisujemo vrijednost čiji tip ne odgovara ili se ne može pretvoriti u tip kolone, npr. ako
bismo u cjelobrojnu kolonu StudijID pokušali upisati tekst 'Marko'.
(Syntax error converting the varchar value 'Marko' to a column of data type
smallint.)
Kada naredba za upisivanje retka obuhvaća listu svih kolona definiranih u tablici, nije
neophodno navoditi listu kolona, već samo listu vrijednosti, pri čemu poredak vrijednosti
mora odgovarati fizičkom poretku kolona u tablici:
Ovakvu naredbu možemo koristiti ad hock, dakle upotrijebimo i izbrišemo, ali nipošto u
programima ili skriptama koje se koriste trajno. Naime, tijekom vremena prpizići će potreba
za dodavanjem jedne ili više kolona u tablicu, što je uobičajena praksa kako primjena baze
napreduje, a onda broj kolona tablice i navedenih vrijednosti se neće podudariti. Stoga je
praktičana neophodnost da se uvijek navodi lista kolona u koje se upisuju vrijednosti.
Naknadno dodane kolone moraju dopuštati Null vrijednost ili imati definiranu pretpostavljenu
( default ) vrijednost.
Stvorimo li tablicu Studenti2, s kolonama Ime, Prezime i StudijID, tada u nju možemo upisati
dio ili sve retke iz tablice Studenti, naredbom:
FROM Studenti
WHERE StudijID=1
UPDATE Studenti
SET DatumRodjenja='1980/06/21'
UPDATE Studenti
SET DatumRodjenja='1980/06/21'
Svim studentima koji nemaju definiran poštanski broj, ( PostaID IS NULL), potrebno je
upisati broj čija druga znamenka slijeva odgovara broju StudijID, a prva znamenka je 2.
Kako se radi o zahtjevnoj naredbi, najprije ćemo provjeriti naše razmišljanje izvođenjem
SELECT upita, jer jasno je, pogrešno promijenjene podatke nije lako popraviti:
Kako smo zaista dobropostavili uvjet, to vidimo da su obuhvaćeni samo studenti kojima nije
definirana PostaID ( NULL ), te da je prva znamenka slijeva poštanskog broja 2 i konačno
StudijID i driga znamenka poštanskog broja se uvijek podudaraju.
SET PostaiD=P.PostaID
Jasno je, da će nakon izvedene naredbe PostaID dobiti ranijom komandom izlistane
vrijednosti.
Možemo brisati pojedinačne retke, grupu redaka koji zadovoljavaju određeni kriterij, ili pak
sve retke u tablici.
Općenito, sigurno ćemo izbrisati samo jedan redak, ako se u WHERE klauzuli testira
vrijednost primarnog ključa, jer on na jedinstven način identificira svaki redak.
Primarni ključ tablice Studenti je StudentID, čije vrijednosti automatski generira sustav
relacijske baze ( Autonumber ).
Brišemo, dakle trajno uklanjamo iz tablice, studenta Hrvoja Antića, čijije StudentID ( u mojoj
tablici ) 7 naredbom:
WHERE StudentID=7
Kako smo upotrijebili primarni ključ kao uvjet, to smo sigurni da je izbrisan najviše jedan
redak.
Vrlo jednostavno, kako se i da pretpostaviti, ispuštanjem uvjeta bit će izbrisani svi retci
tablice.
Skrenimo pažnju, da je nakon izvedene komande, tablica potpuno prazna. Prije izvođenja
ovakvih komandi, moramo biti sigurni što želimo.