Baze podataka 2 - FESB
Baze podataka 2 - FESB
Baze podataka 2 - FESB
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>Baze</strong> <strong>podataka</strong> 2<br />
<br />
<br />
<br />
Uvod<br />
Logiko modeliranje pomou dijagrama E-V (entiteti - veze)<br />
Primjer:<br />
ili E-R (Entity – Relationship)<br />
Entitet STUDENT sa atributima: ime, prezime, datum roenja, JMBG,<br />
mjesto roenja, itd.<br />
Entiteti UPISNI LIST i PREDMET.<br />
STUDENT i UPISNI LIST su meusobno u vezi (odnosu, relaciji);<br />
takoer i UPISNI LIST i PREDMET,
E-V dijagram je osnova<br />
i uvod za prikaz<br />
<strong>podataka</strong> u relacijskom<br />
modelu<br />
Objašnjenje:<br />
0,1 ili više studenata predaje<br />
upisni list<br />
1 upisni list pripada pojedinom<br />
studentu<br />
0,1 ili više predmeta je upisano<br />
na jednom upisnom listu<br />
0,1 ili više upisnih listova sadrži<br />
jedan te isti predmet<br />
<br />
<br />
Veza STUDENT – UPISNI LIST je 1 : M<br />
Veza UPISNI LIST – PREDMET je M : N<br />
Relacijski model <strong>podataka</strong> se gradi iz modela E-V<br />
pomou transformacijskih pravila:<br />
- entitet se prikazuje tablicom<br />
- dva entiteta sa vezom 1:M povezana su stranim<br />
kljuem<br />
- za dva entiteta sa vezom M:N formira se novi<br />
entitet<br />
<br />
- veza 1:1 meu dva entiteta može se realizirati ili<br />
da ostanu dvije tablice meusobno povezani<br />
stranim kljuem, ili da se formira jedna<br />
tablica sa svim artibutima.
Relacijski model je<br />
organiziran tako da je<br />
izmeu tablice UPISNI<br />
LIST i tablice PREDMET<br />
dodana tablica UPISUJE.<br />
SQL (Structured Query<br />
Language – strukturni<br />
jezik za pretraživanje) je<br />
standardiziran po ISO i<br />
ANSI standardima.<br />
Svi SUBP nastoje što je<br />
više mogue slijediti<br />
original standard SQL-a,<br />
ali ga i obogauju raznim<br />
dodatnim opcijama.<br />
<br />
<br />
Osnovni objekti u SQL-u su:<br />
- baza <strong>podataka</strong> (Database)<br />
- tablica (Table) - relacija<br />
- stupac (Column) - atribut<br />
- pogled ili virtualna tablica (View)<br />
- pravilo integriteta (Constraint)<br />
- indeks (Indeks)<br />
- pohranjena procedura (Store Procedure)<br />
- okida (Trigger)<br />
<br />
Imena objekata u SQL-u formiraju se iz slova, znaka ‘_’ i<br />
znamenki. Prvi znak (od max 18) mora biti slovo.<br />
SQL je ‘neosjetljiv’ na razliku izmeu velikih i malih slova.<br />
SELECT ime, prezime FROM student<br />
select ime, prezime from student
Struktura scheme baze <strong>podataka</strong>:<br />
CREATE – kreiranje (izrada) nove strukture, npr.<br />
tablice (pogleda, indeksa, procedure, baze …)<br />
ALTER – promjena ve postojee strukture<br />
DROP - brisanje ve postojee strukture.<br />
Primjer:<br />
CREATE TABLE mjesto<br />
(mjesto_id int IDENTITY CONSTRAINT<br />
PK_MJESTO PRIMARY KEY,<br />
ime_mjesta varchar(30) NOT NULL,<br />
post_br int NULL)<br />
DROP TABLE mjesto<br />
<br />
ALTER TABLE mjesto ADD drzava varchar(50)<br />
ALTER TABLE mjesto ALTER COLUMN ime_mjesta varchar (50)<br />
<br />
<br />
Rad sa podacima:<br />
INSERT – upis <strong>podataka</strong> u tablicu (novi zapis)<br />
UPDATE – promjena postojeih <strong>podataka</strong> (u<br />
postojeem zapisu)<br />
DELETE – brisanje postojeeg zapisa<br />
SELECT – upit nad postojeim podacima<br />
Primjer:<br />
INSERT INTO mjesto (ime_mjesta, post_br, drzava)<br />
VALUES (‘Mrduša donja’, ‘99999’, ‘Neznase’)<br />
UPDATE mjesto SET drzava = ‘Hrvatska’<br />
WHERE post_br = ‘99999’<br />
DELETE FROM mjesto WHERE post_br IS NULL<br />
SELECT * FROM mjesto WHERE drzava != ‘Hrvatska’
Tipovi <strong>podataka</strong>:<br />
- znakovni ( char(), varchar(), text, … )<br />
- binarni ( bit )<br />
- numeriki ( int, smallint, decimal, float, double, … )<br />
- datum-vrijeme ( datetime, smalldatetime )<br />
<br />
<br />
Selekcija <strong>podataka</strong><br />
<br />
Selekcija – dobavljanje <strong>podataka</strong> vrši se SQL izrazom oblika:<br />
SELECT [ALL | DISTINCT] imena_kolona FROM<br />
imena_tablica|logike_veze WHERE uvjetni_izraz<br />
imena_kolona<br />
- zvjezdica (*), predstavlja sve kolone po redoslijedu navedenom kod<br />
formiranja tablice (CREATE TABLE).<br />
- ako lista imena_kolona sadrži više kolona, nazivi kolona se meusobno<br />
odvajaju zarezom.<br />
imena_tablica |logike veze<br />
- nazivi tablica iz kojih se dobavljaju podaci<br />
- logike veze opisuju operacije prirodnog spajanja meu<br />
tablicama ( inner join – unutarnja veza,<br />
outer join – vanjska veza,<br />
left join – lijeva veza ,<br />
right join - desna veza)<br />
uvjetni_izraz<br />
logiki izraz koji definira uvjet po kojem se vrši pretraživanje
$"!%"&<br />
<br />
!"!# "<br />
'!# !<br />
"!()!# *<br />
"!# *<br />
SELECT STUDENT.ime_studenta,<br />
STUDENT.prezime_studenta,<br />
MJESTO.naziv_mjesta<br />
FROM MJESTO INNER JOIN STUDENT ON<br />
MJESTO.mjesto_ID = STUDENT.mjesto_preb<br />
<br />
<br />
Uvjetni izrazi<br />
Oblik uvjetnog izraza ima oblik:<br />
Naziv_kolone Predikat Vrijednost<br />
Predikati usporedbe<br />
= jednako razliito od<br />
> vee od !> nije vee<br />
< manje od !< nije manje<br />
>= vee ili jednako<br />
Sortiranje izlaznih rezultata<br />
<br />
Koristi se izraz ORDER BY, kao dio select instrukcije:<br />
SELECT [ALL | DISTINCT] nazivi_kolona<br />
FROM nazivi_tablica|logike veze<br />
WHERE uvjetni izraz<br />
ORDER BY kolone_sortiranja<br />
Sintaksa:<br />
ORDER BY naziv_kolone tip_sortiranja, naziv_kolone tip_sortiranja,...<br />
Agregatne funkcije<br />
Generiraju zbirne(skupne) vrijednosti nad pojedinim kolonama tablice,<br />
koriste se u SELECT izrazu.<br />
SUM – zbroj AVG- prosjek MIN-minimum<br />
MAX-maximum COUNT- pobrojavanje<br />
Agregatne funkcije SUM i AVG mogu se koristiti samo za numerike<br />
tipove <strong>podataka</strong>.<br />
<br />
<br />
Grupni upiti<br />
<br />
Odreuje grupe po kojima se dijele izlazni rezultati:<br />
SELECT [ALL | DISTINCT] nazivi kolona, agregatne kolone<br />
FROM nazivi_tablica| join veze<br />
[WHERE uvjetni izraz]<br />
[GROUP BY nazivi kolona]<br />
[HAVING uvjetni izraz]<br />
[ORDER BY sort_izraz]<br />
HAVING uvjetni izraz<br />
Ogranienje izlaznih rezultata po<br />
zadanom uvjetu nakon izvršenja<br />
GROUP BY operacije.<br />
,*"!!%345616!5/78+9!"&<br />
45616!"("!:! " "!<br />
!)(("!" ;" "!<br />
("!"<br />
5/78+9!"*! "<br />
. ("!" ".<br />
SELECT STUDENT.student_id, ime, prezime, COUNT(sem)<br />
FROM STUDENT INNER JOIN UPISNI_LIST<br />
ON STUDENT.student_id = UPISNI_LIST.student_id<br />
GROUP BY STUDENT.student_id, ime, prezime<br />
HAVING SK_GOD > ’2004/05’
Ugnježdeni upiti - podupiti<br />
<br />
Podupit (Subquery) je SELECT izraz ukljuen u glavni SELECT, INSERT,<br />
UPDATE ili DELETE upit.<br />
Pri tome podupit i glavni upit mogu djelovati ne istu tablicu ili na razliite<br />
tablice. Mnogi SQL izrazi koji ukljuuju podupite mogu se realizirati<br />
i stvaranjem upita sa povezivanjem (join).<br />
SELECT [ALL | DISTINCT] nazivi kolona, agregatne kolone<br />
FROM nazivi_tablica| join veze<br />
[WHERE naziv_kolone predikat (subquery)]<br />
Postoje tri osnovna oblika oblika podupita (subqueries):<br />
-podupiti liste na koje se primijenjuje IN predikat - vraa niz rezultata (listu),<br />
koju glavni upit koristi u svom uvjetnom izrazu preko predikata liste<br />
(IN ili NOT IN).<br />
- podupiti sa predikatom usporedbe - rezultat podupita može se u glavni<br />
upit ukljuiti preko jednog od predikata usporedbe (=,,
Podupiti sa predikatom usporedbe<br />
<br />
Podupit mora vratiti samo jednu vrijednost; ukoliko podupit vraa više od<br />
jedne vrijednosti javlja se greška u izvršavanju glavnog upita.<br />
Primjer: Prikazati sve studente<br />
koji su roeni u istom mjestu kao<br />
i student ‘x y’.<br />
SELECT student_id, ime, prezime<br />
FROM STUDENT<br />
WHERE mjesto_id =<br />
(SELECT mjesto_id<br />
FROM STUDENT<br />
WHERE ime = ’X’<br />
AND prezime = ’Y’)<br />
ORDER BY prezime, ime<br />
Primjer: Prikazati sve upisne listove<br />
za studenta ‘x y’ osim posljednjega.<br />
SELECT sk_god, sem<br />
FROM UPISNI_LIST<br />
WHERE student_id =<br />
(SELECT student_id<br />
FROM STUDENT<br />
WHERE ime = ’X’<br />
AND prezime = ’Y’)<br />
AND sem <<br />
(SELECT MAX(sem)<br />
FROM UPISNI_LIST<br />
WHERE student_id =<br />
( SELECT student_id<br />
FROM STUDENT<br />
WHERE ime = ’X’<br />
AND prezime = ’Y’))<br />
<br />
<br />
Podupiti sa predikatom postojanja<br />
<br />
Operator EXISTS ispituje postojanje <strong>podataka</strong> uz navedene uvjete. Podupit<br />
sa predikatom postojanja ne vraa nikakve podatke, ve daje samo rezultat<br />
TRUE ili FALSE.<br />
Primjer: Prikazati sve studente koji nemaju niti jedan upisni list.<br />
SELECT student_id, ime, prezime<br />
FROM STUDENT<br />
WHERE NOT EXISTS (SELECT *<br />
FROM UPISNI_LIST<br />
WHERE STUDENT.student_id = UPISNI_LIST.student_id)<br />
Primjer: Prikazati sva mjesta u kojima je roen neki student.<br />
SELECT *<br />
FROM MJESTO<br />
WHERE EXISTS (SELECT *<br />
FROM STUDENT<br />
WHERE MJESTO.mjesto_id = STUDENT.mjesto_id)
UNIJA<br />
<br />
Operator unije (UNION) definira relacijsku operaciju unije, tj. povezuje<br />
rezultate više upita u jedinstveni skup rezultata.<br />
Sintaksa:<br />
Upit_1 UNION [ALL] Upit_2...ORDER BY sort<br />
Pri formiranju unije mora vrijediti:<br />
- upiti iji se rezultati uniraju moraju imati jednaki broj izlaznih kolona<br />
- odgovarajue izlazne kolone u upitima koji se povezuju unijom moraju<br />
biti istog tipa <strong>podataka</strong>.<br />
UNION operator uklanja duplicirane redove rezultata obaju upita.<br />
Ukoliko se želi prikaz svih redova, bez eliminacije duplikata, potrebno je<br />
navesti opciju ALL.<br />
<br />
<br />
<br />
Primjer: Veza outer join sa strane 2.<br />
SELECT STUDENT.ime_studenta,<br />
STUDENT.prezime_studenta, MJESTO.naziv_mjesta<br />
FROM MJESTO INNER JOIN STUDENT ON<br />
MJESTO.mjesto_ID = STUDENT.mjesto_preb<br />
UNION<br />
SELECT STUDENT.ime_studenta,<br />
STUDENT.prezime_studenta, MJESTO.naziv_mjesta<br />
FROM MJESTO left JOIN STUDENT ON MJESTO.mjesto_ID<br />
= STUDENT.mjesto_preb<br />
UNION<br />
SELECT STUDENT.ime_studenta,<br />
STUDENT.prezime_studenta, MJESTO.naziv_mjesta<br />
FROM MJESTO right JOIN STUDENT ON<br />
MJESTO.mjesto_ID = STUDENT.mjesto_preb;<br />
Pitanje: Ako se umjesto UNION stavi<br />
UNION ALL što se dobije (i zašto)?
?8@6<br />
FUNKCIJE<br />
SQL ukljuuje veliki broj funkcija koje omoguavaju<br />
izvršavanje operacija kojima se vrši preoblikovanje izlaznih<br />
rezultata ili formiranje novih kolona izlaznog rezultata iji<br />
sadržaj se dobija operacijama nad postojeim kolonama u<br />
tablicama. To su:<br />
- Sistemske funkcije, koje vraaju podatke iz sistemskih tablica<br />
- Funkcije znakovnih <strong>podataka</strong> koji djeluju nad podacima tipa char,<br />
varchar, binary<br />
- Matematike funkcije koje djeluju na numeriki tip <strong>podataka</strong><br />
- Funkcije vezane za datum i vrijeme<br />
- Funkcije konverzije, kojima se jedan tip <strong>podataka</strong> pretvara u drugi.<br />
Opi oblik primjene funkcija može se prikazati sintaksom oblika:<br />
SELECT naziv_kolone = funkcija(parametri)<br />
<br />
<br />
Funkcije znakovnog tipa <strong>podataka</strong><br />
?8@6(!<br />
Koriste se u SQL izrazima gdje je potrebno izvršavanje odreenih<br />
operacija nad kolonama (atributima) koje sadržavaju znakovni<br />
(tekstualni) tip podatka: char, varchar, text.<br />
Povezivanje znakova (concatenation)<br />
Operator povezivanja znakova (nizova) je plus (+). Dva ili više nizova<br />
povezuju se u jedinstveni znakovni niz. npr.: SELECT ('abc'+ 'def')<br />
Primjer: Prikazati popis studenata u<br />
obliku liste sa dvije kolone. Prva<br />
kolona sadržava prezime i ime<br />
studenta, a druga kolona mjesto, ulicu<br />
i državu preb. studenta.<br />
Upit:<br />
SELECT prezime_studenta, ime_studenta,<br />
naziv_mjesta, ulica, drzava<br />
FROM MJESTO INNER JOIN STUDENT<br />
ON MJESTO.mjesto_ID =<br />
STUDENT.mjesto_preb<br />
Rezultat upita:
Upit sa spajanjem atrubuta:<br />
SELECT prezime_studenta + ‘ ‘ + ime_studenta,<br />
naziv_mjesta + ‘, ‘ + ulica + ‘, ‘+ drzava<br />
FROM MJESTO INNER JOIN STUDENT<br />
ON MJESTO.mjesto_ID =<br />
STUDENT.mjesto_preb<br />
Rezultat upita:<br />
?8@6(!<br />
Sadržaj tablice MJESTO:<br />
Upit sa spajanjem atrubuta i ISNULL funkcijom:<br />
SELECT prezime_studenta + ‘ ‘ + ime_studenta,<br />
naziv_mjesta + ‘, ‘ + ulica + ‘, ‘+ ISNULL(drzava, ‘ ‘)<br />
FROM MJESTO INNER JOIN STUDENT<br />
ON MJESTO.mjesto_ID =<br />
STUDENT.mjesto_preb<br />
Rezultat upita:<br />
Sadržaj tablice STUDENT:<br />
<br />
<br />
?8@6(!<br />
LEFT<br />
Vraa dio znakovnog niza sa lijeve strane, poevši od prvog znaka u<br />
duljini n znakova (prvih n znakova slijeva).<br />
Rezultat funkcije je znakovnog tipa <strong>podataka</strong>.<br />
Sintaksa: LEFT(niz_znakova, n) # ;" # A;"!<br />
RIGHT<br />
Vraa dio znakovnog niza u duljini n znakova s desne strane (prvih n<br />
znakova sdesna).<br />
Rezultat funkcije je znakovnog tipa <strong>podataka</strong>.<br />
Sintaksa: RIGHT(niz_znakova, n) n – broj znakova – cjelobrojni podatak<br />
SUBSTRING<br />
Vraa dio znakovnog niza sa lijeve strane, poevši od zadanog znaka<br />
(start) u duljini n znakova.<br />
Rezultat funkcije je znakovnog tipa <strong>podataka</strong>.<br />
Sintaksa: SUBSTRING(niz_znakova, start,n)<br />
start – pozicija poetnog znaka u nizu – cjelobrojni podatak<br />
n – broj znakova – cjelobrojni podatak
?8@6(!<br />
LEN<br />
Vraa duljinu znakovnog niza izraženu u broju karaktera, ukljuujui i<br />
razmake.<br />
Rezultat funkcije je cjelobrojni podatak (integer).<br />
Sintaksa: LEN(niz_znakova)<br />
Primjer: Prikazati sve studente kojima prezime poinje sa slovom B.<br />
SELECT STUDENT=PREZIME+''+IME FROM STUDENT WHERE LEFT(PREZIME,1)=’B’<br />
Primjer: Prikazati sve studente kojima prezime završava sa i.<br />
SELECT STUDENT=PREZIME+''+IME FROM STUDENT WHERE RIGHT(PREZIME,2)=’i’<br />
Primjer: Pronai najveu duljinu prezimena za studente prikazane u tablici.<br />
SELECT max(LEN(PREZIME)) FROM STUDENT<br />
Napomena:<br />
SUBSTRING(niz_znakova,1,n) = LEFT(niz_znakova,n)<br />
SUBSTRING(niz_znakova,LEN(niz_znakova)-n+1,n)<br />
=RIGHT(niz_znakova,n)<br />
<br />
<br />
?8@6(!<br />
CHARINDEX<br />
Vraa podatak o položaju traženog niza znakova unutar nekog niza koji<br />
se pretražuje.<br />
Funkcija se primijenjuje kada se unutar jednog niza znakova traži pojava<br />
drugog niza, a povratni podatak je cijeli broj (integer), koji daje redni broj<br />
znaka u pretraživanom nizu, gdje poinje traženi niz. Ukoliko se traženi<br />
niz ne nalazi unutar pretraživanog funkcija vraa 0.<br />
Sintaksa: CHARINDEX(traženi_niz, pretraživani_niz)<br />
Primjer:<br />
Podatke o imenu i prezimenu studenata izdvojiti u novu tablicu naziva<br />
STUDENT2, na nain da su podaci o imenu i prezimenu objedinjeni.<br />
SELECT PREZ_I_IME = PREZIME + ''+IME<br />
INTO STUDENT2<br />
FROM STUDENT<br />
Iz ovako dobijene tablice STUDENT2 potrebno je dobiti podatke o<br />
studentima, gdje su prezime i ime prikazani u odvojenim kolonama<br />
SELECT PREZIME = LEFT(PREZ_I_IME, CHARINDEX('',PREZ_I_IME)-1),<br />
IME = RIGHT(PREZ_I_IME, LEN(PREZ_I_IME) -<br />
CHARINDEX('',PREZ_I_IME))<br />
FROM STUDENT2
?8@6(!<br />
Detaljna analiza upita koji iz jednog polja u kome je uneseno i prezime i ime<br />
izdvaja posebno prezime a posebno ime (pod pretpostavkom da je su<br />
razdvojeni praznim znakom tj. blank-om):<br />
SELECT PREZ_I_IME,<br />
LEN(PREZ_I_IME) AS 'duljina',<br />
CHARINDEX('',PREZ_I_IME) AS 'mjesto blank-a',<br />
LEN(PREZ_I_IME)- CHARINDEX('',PREZ_I_IME) AS 'duljina zdesna do blank-a',<br />
PREZIME = LEFT(PREZ_I_IME, CHARINDEX('',PREZ_I_IME)-1),<br />
IME = RIGHT(PREZ_I_IME, LEN(PREZ_I_IME) - CHARINDEX('',PREZ_I_IME))<br />
FROM<br />
STUDENT2<br />
<br />
<br />
650 - <strong>Baze</strong> <strong>podataka</strong> 2<br />
Sistemske funkcije<br />
&<br />
$"!!!**"!% !!% !* !%!*:<br />
"*!" (!!* !%H8*"H<br />
!! "#$%&'$())<br />
))*))+$&$<br />
,-'.$-'!"$/01!<br />
"!!<br />
"#0'(<br />
<br />
<br />
650 - <strong>Baze</strong> <strong>podataka</strong> 2<br />
Sistemske funkcije<br />
Složeni oblik<br />
Funkcije konverzije<br />
Koriste se za pretvaranje <strong>podataka</strong> iz jednog tipa u drugi.<br />
Prilikom primjene operacija nad podacima esti<br />
su sluajevi vršenja pojedinih operacija ili<br />
usporedbe <strong>podataka</strong> razliitog tipa.<br />
U ovakvim sluajevima SQL mehanizam<br />
ponekad sam automatski vrši pretvorbu tipa<br />
<strong>podataka</strong>.<br />
Npr. Ukoliko se usporeuju podaci tipa int i smallint,<br />
prilikom usporedbe SQL sam vrši tzv. implictitnu<br />
konverziju, te niži format podatka (smallint) automatski<br />
pretvara u viši (int) za potrebe vršenja operacije.<br />
Openito u sluajevima ako se dva po tipu<br />
razliita podatka primjenjuju u operaciji,<br />
prioritet tipa <strong>podataka</strong> odreuje koji tip <strong>podataka</strong><br />
se pretvara u drugi.<br />
Podatak sa tipom nižeg prioriteta se pretvara u<br />
tip podatka višeg prioriteta.<br />
POGLED (VIEW)<br />
$(7864<br />
Pogledi su virtualne tablice, koje se formiraju kao posebna<br />
organizacijska jedinica u bazi <strong>podataka</strong>.<br />
Osnovne tablice postoje kao stvarne, fizike tablice u bazi<br />
<strong>podataka</strong>. One imaju svoju definiciju koja je pohranjena u<br />
sistemskom katalogu baze <strong>podataka</strong>, svoje podatke koji<br />
su pohranjeni na disku i svoje indekse.<br />
Pogled (view), kao virtualna tablica, nema svoje indekse,<br />
niti datoteke s podacima, ali mu korisnik pristupa kao i<br />
svakoj drugoj tablici.<br />
Kreiranje pogleda - Pogled se definira naredbom<br />
CREATE VIEW ime AS<br />
SELECT ...select query<br />
[WITH CHECK]<br />
<br />
<br />
$(7864<br />
U sklopu definicije pogleda mogue je navesti bilo koji select query,<br />
obini ili grupni uz postojea pravila u okviru SQL-a.<br />
Atributi pogleda imaju iste nazive kao i atributi tablica nad kojima je<br />
pogled definiran.<br />
Primjer:<br />
CREATE VIEW V_UPISNI_LIST AS<br />
SELECT IME, PREZIME, MAT_BR,<br />
UPISANI_SEM, SK_GOD,<br />
OBR_PROG_IME, APSOLVENT<br />
FROM STUDENT INNER JOIN UPISNI_LIST<br />
ON STUDENT.STUDENT_ID=UPISNI_LIST.STUDENT_ID<br />
INNER JOIN OBR_PROG<br />
ON UPISNI_LIST.OBR_PROG_ID= OBR_PROG.OBR_PROG_ID<br />
Ovaj pogled formiran je nad tablicama STUDENT, UPISNI_LIST i<br />
OBR_PROG, sa izlaznim atributima IME, PREZIME, MAT_BR,<br />
UPISANI_SEM, SK_GOD, OBR_PROG_IME i APSOLVENT.
$(7864<br />
>"!*!: ;!A ""<br />
$(!""<br />
<br />
<br />
$(7864<br />
Pogledu je mogue pristupati kao i svakoj drugoj tablici:<br />
SELECT *<br />
FROM V_UPISNI_LIST<br />
WHERE IME=’Goran’ AND PREZIME=’Ban’<br />
ORDER BY SK_GOD, UPISANI_SEM<br />
SELECT distinct IME, PREZIME<br />
FROM V_UPISNI_LIST<br />
WHERE UPISANI_SEM=1 AND SK_GOD=’2002/03’<br />
ORDER BY PREZIME, IME
Preimenovanje atributa pogleda<br />
$(7864<br />
Prilikom uobiajenog definiranja pogleda, njegovi atributi imaju iste<br />
nazive kao i atributi tablica nad kojima je pogled definiran.<br />
Ako postoji potreba za promjenom naziva pojedinih atributa, to se<br />
može ostvariti na tri naina:<br />
Uobiajeno pravilo promjene naziva atributa u SELECT<br />
upitima tipa novi_naziv = atribut.<br />
Primjer:<br />
CREATE VIEW V_STUDENTI AS<br />
SELECT IME, PREZIME, SK_GOD, UPISANI_SEMESTAR = UPISANI_SEM<br />
FROM STUDENT INNER JOIN UPISNI_LIST<br />
ON STUDENT.STUDENT_ID =UPISNI_LIST.STUDENT_ID<br />
<br />
<br />
$(7864<br />
Korištenjem izraza AS u obliku: atribut AS novi_naziv.<br />
Primjer:<br />
CREATE VIEW V_STUDENTI AS<br />
SELECT IME, PREZIME, SK_GOD, SEM AS UPISANI_SEM<br />
FROM STUDENT INNER JOIN UPISNI_LIST<br />
ON STUDENT.STUDENT_ID =UPISNI_LIST.STUDENT_ID<br />
Navoenjem novih naziva atributa u definiciji pogleda u<br />
obliku<br />
CREATE VIEW naziv_pogleda (nazivi atributa) AS<br />
Primjer:<br />
CREATE VIEW V_STUDENTI (IME, PREZIME, SK_GOD, UPISANI_SEM) AS<br />
SELECT IME, PREZIME, SK_GOD, SEM<br />
FROM STUDENT INNER JOIN UPISNI_LIST<br />
ON STUDENT.STUDENT_ID =UPISNI_LIST.STUDENT_ID
Ažuriranje, unos i brisanje <strong>podataka</strong> u pogledu<br />
$(7864<br />
Za razliku od stvarnih tablica, mogunosti promjene <strong>podataka</strong><br />
u pogledu podliježu znatnim ogranienjima.<br />
Mijenjanje, unos i brisanje <strong>podataka</strong> u pogledu nije<br />
dozvoljeno:<br />
- ako je pogled formiran dohvaanjem <strong>podataka</strong> iz više<br />
od jedne tablice<br />
- ako je pogled formiran grupnim upitom (group by)<br />
- ako je bilo koji atribut pogleda stvoren pomou<br />
agregatne funkcije<br />
- ako se pri formiranju pogleda koristi opcija DISTINCT<br />
- ako je pogled formiran kao UNION query<br />
- ako je pogled formiran pomou složenog upita sa<br />
podupitom.<br />
<br />
<br />
$(7864<br />
Promjene <strong>podataka</strong> u pogledu su vrlo ograniena.<br />
Dodatna ogranienja mogu se aktivirati korištenjem izraza WITH<br />
CHECK u definiciji pogleda. Pomou ove opcije provjerava se da li se<br />
unosom ili promjenom <strong>podataka</strong> narušava struktura pogleda, tj. da li<br />
promjena ili unos <strong>podataka</strong> zadovoljava uvjet naveden u upitu.<br />
Ako se opcija WITH CHECK ne navede u pogled je mogue unijeti<br />
podatke koji narušavaju strukturu pogleda<br />
Primjer:<br />
CREATE VIEW V1_STUDENT AS<br />
SELECT IME, PREZIME, ROD_DAT<br />
FROM STUDENT<br />
WHERE ROD_DAT>’01.01.1980’<br />
je pogled koji prikazuje sve studente koji su roeni nakon 1. sijenja<br />
1980. Ovakav pogled može se ažurirati i brisati, budui zadovoljava<br />
sva gore navedena pravila.<br />
Primjer:<br />
INSERT V1_STUDENT VALUES ( ‘Z’,’D’,’01.05.1979’)<br />
je isto kao<br />
INSERT STUDENT(IME,PREZIME,ROD_DAT) VALUES ( ‘Z’,’D’,’01.05.1979’)
Primjer:<br />
CREATE VIEW V1_STUDENT AS<br />
SELECT IME, PREZIME, ROD_DAT<br />
FROM STUDENT<br />
WHERE ROD_DAT>’01.01.1980’ WITH CHECK<br />
$(7864<br />
Uvoenjem opcije provjere (WITH CHECK) naredba:<br />
INSERT V1_STUDENT VALUES ( ‘Z’,’D’,’01.05.1979’)<br />
nee dati rezultat jer novi podatak koji se unosi ne zadovoljava uvjet<br />
ROD_DAT>’01.01.1980’.<br />
Uklanjanje pogleda<br />
Pogled se uklanja iz baze <strong>podataka</strong> naredbom:<br />
DROP VIEW naziv_pogleda<br />
Primjer:<br />
DROP VIEW V1_STUDENT<br />
<br />
<br />
,* !."!*!:("<br />
OSNOVE VIŠEKORISNIKOG RADA<br />
Zbog veeg broja korisnika koji pristupaju bazama <strong>podataka</strong>,<br />
administrator baze ima zadatak ograniiti prava pristupa i<br />
korištenja <strong>podataka</strong>.<br />
Osnovni razlozi ogranienja prava pristupa podacima u bazi<br />
su:<br />
- mogunosti neovlaštenog pristupa podacima<br />
- nestruno rukovanje podacima<br />
- mogue zlouporabe.<br />
DBA - Database administrator (Administrator baze <strong>podataka</strong>),<br />
kao kljuna osoba u održavanju baze <strong>podataka</strong> je korisnik<br />
najvišeg prioriteta, koji ima sva prava pristupa.
,* !."!*!:("<br />
Ovisno o zadacima koje obavljaju pojedini korisnici, DBA<br />
formira nove korisnike u bazi:<br />
ADD USER ime_korisnika: šifra<br />
ime_korisnika (login) – korisniko ime koje mora biti<br />
jedinstveno u bazi <strong>podataka</strong>, tj. nije dozvoljeno da postoje<br />
dva razliita korinika sa istim imenom.<br />
šifra (password) – sigurnosna (tajna) šifra, kojom svaki<br />
korisnik potvruje svoj identitet.<br />
Korisnik se dodaje na nivou baze <strong>podataka</strong>.<br />
Svakom korisniku se mogu dodatno dodijeliti ili ograniiti<br />
prava na korisštenje djelova baze <strong>podataka</strong>.<br />
<br />
<br />
Dodjeljivanje privilegija (prava)<br />
,* !."!*!:("<br />
Prava pristupa pojedinim korisnicima dodjeljuju se naredbom:<br />
GRANT nazivi_prava ON naziv_objekta TO ime_korisnika<br />
nazivi_prava – lista prava pristupa podacima<br />
SELECT – pravo itanja <strong>podataka</strong><br />
UPDATE – pravo promjene (ažuriranja) <strong>podataka</strong><br />
DELETE – pravo brisanja <strong>podataka</strong><br />
INSERT - pravo unosa <strong>podataka</strong><br />
naziv_objekta – ime objekta (tablice ili pogleda) u bazi na koji se prava<br />
odnose<br />
ime_korisnika – naziv korisnika kojem se prava dodjeljuju.<br />
=<br />
>) )?6<br />
>"!*!> * ":!!"% ;!A!-=06+-<br />
>) ?<br />
>"!*!> * ":!!;"!*;!A!-=06+-
,* !."!*!:("<br />
Sužavanje pojedinih prava na dijelove tablica i pogleda<br />
Prava promjene i unosa <strong>podataka</strong> mogue je suziti na<br />
pojedine atribute (kolone) u tablici:<br />
INSERT (lista_atributa) – pravo unosa <strong>podataka</strong> u samo odreene<br />
kolone<br />
UPDATE (lista_atributa) – pravo promjene <strong>podataka</strong> u navedenim<br />
kolonama tablice<br />
Primjer:<br />
GRANT SELECT, UPDATE(Datum, MjestoId) ON STUDENT TO K3<br />
Korisniku K3 dodjeljuje se pravo itanja i pravo promjene datuma i<br />
mjesta roenja u tablici STUDENT.<br />
<br />
<br />
Kaskadno dodjeljivanje privilegija<br />
,* !."!*!:("<br />
Administrator baze <strong>podataka</strong> može pojedinim korisnicima,<br />
uz dodjeljivanje prava dati mogunost proslijeivanja tih<br />
prava drugim korisnicima:<br />
GRANT nazivi_prava ON naziv_objekta TO ime_korisnika<br />
WITH GRANT OPTION<br />
Dodjeljivanjem prava uz opciju WITH GRANT OPTION,<br />
korisniku se daje mogunost da po potrebi ta prava<br />
proslijedi drugima.<br />
Primjer:<br />
DBA: GRANT SELECT, UPDATE ON STUDENT TO K1<br />
WITH GRANT OPTION<br />
K1: GRANT SELECT ON STUDENT TO K2<br />
Korisnik K1 proslijeuje svoje pravo itanja <strong>podataka</strong> korisniku K2.
Opoziv (uklanjanje prava)<br />
,* !."!*!:("<br />
Prava koja su dodijeljena korisnicima mogu se ukloniti sa:<br />
REVOKE nazivi_prava ON naziv_objekta FROM ime_korisnika<br />
Primjer:<br />
REVOKE UPDATE ON STUDENT FROM K1<br />
Prilikom uklanjanja prava mogue je korištenje dodatnih<br />
opcija CASCADE ili RESTRICT.<br />
Primjer:<br />
REVOKE UPDATE ON STUDENT FROM K1 CASCADE<br />
Pravo promjene <strong>podataka</strong> u tablici STUDENT oduzima se korisniku K1,<br />
ali i svima onima kojima je korisnik K1 to pravo proslijedio.<br />
Primjer:<br />
REVOKE UPDATE ON STUDENT FROM K1 RESTRICT<br />
Pravo promjene <strong>podataka</strong> u tablici STUDENT oduzima se korisniku K1<br />
samo u sluaju da on to pravo nije nikome proslijedio. Ako je K1<br />
proslijedio pravo UPDATE prikazuju se podaci o korisnicima koji su to<br />
pravo naslijedili.<br />
<br />
<br />
,* !."!*!:("<br />
Poništavanje prava naslijeivanja<br />
Pravo daljnjeg dodijeljivanja privilegija, koje se daje sa<br />
opcijom WITH GRANT OPTION mogue je poništiti<br />
naredbom:<br />
REVOKE GRANT OPTION FOR nazivi_prava ON naziv_objekta<br />
FROM ime_korisnika<br />
Primjer:<br />
REVOKE GRANT OPTION FOR UPDATE ON STUDENT FROM K1<br />
Korisniku K1 se oduzima pravo da dijeli UPDATE privilegiju drugima,<br />
a ujedno se brišu sva UPDATE prava koje je K1 prethodno dodijelio.<br />
Pri tome UPDATE pravo samog korisnika K1 ostaje sauvano.
Grupiranje korisnika<br />
,* !."!*!:("<br />
Radi lakšeg i bržeg dodijeljivanja prava korisnicima koji<br />
rade na istim poslovima i imaju sline potrebe za pristup<br />
pojedinim podacima, korisnici se povezuju u grupe:<br />
CREATE GROUP naziv_grupe FOR USERS (lista_korisnika)<br />
Primjer:<br />
CREATE GROUP KORISNICI FOR USERS (K1, K2, K3)<br />
Dodjeljivanjem prava grupi, prava se dodijeljuju svim korisnicima koji<br />
su lanovi te grupe.<br />
GRANT SELECT, UPDATE ON STUDENT TO KORISNICI<br />
Grupa korisnika može se naknadno mijenjati dodavanjem<br />
novih ili iskljuenjem nekog od postojeih lanova te grupe:<br />
ALTER GROUP naziv_grupe ADD|DROP USERS (lista_korisnika)<br />
Primjer:<br />
ALTER GROUP KORISNICI ADD USERS (K6)<br />
ALTER GROUP KORISNICI DROP USERS (K2,K3)<br />
<br />
<br />
SKUPNE SQL INSTRUKCIJE (BATCHES)<br />
!*"A!<br />
Skup, slijed (batch – eng. skupina, grupa, gomila, …)<br />
SQL instrukcija predstavlja više SQL instrukcija koje klijent<br />
postavlja na bazu <strong>podataka</strong>.<br />
Ove SQL instrukcije baza <strong>podataka</strong> prihvaa kao jedinstveni<br />
skup naredbi i izvršavaju se slijedom jedna za drugom po<br />
redoslijedu kako su navedene.<br />
=<br />
7!.*"!66?-!"!&<br />
66?-N !<br />
8+61-*7/=6H;" HD<br />
8+61-*7/=6H;" HD<br />
66?-N
!*"A!<br />
SQL kompajler prihvaa niz instrukcija i kompajlira ih jednom<br />
kao cjelinu.<br />
Zbog ove injenice u primjeni slijeda instrukcija postoje<br />
izvjesna ogranienja:<br />
U sklopu slijeda instrukcija ne mogu se primjenjivati<br />
instrukcije kojima se stvaraju procedure, okidai, pravila i<br />
pogledi (CREATE PROCEDURE, CREATE TRIGGER,<br />
CREATE RULE, CREATE VIEW).<br />
Primjena CHECK ogranienja u sklopu formiranja tablice<br />
postaje aktivna tek nakon završetka svih instrukcija u slijedu.<br />
Nije mogue u istom slijedu izbrisati objekt iz baze, a potom<br />
stvoriti novi istog naziva.<br />
Nije mogue postojeim tablicama dodavati nove kolone i<br />
pristupati novostvorenim kolonama u istom slijedu instrukcija.<br />
<br />
<br />
Varijable<br />
!*"A!<br />
U SQL sustavima varijable su korisniki definirane jedinice u<br />
kojima se pohranjuju odreene vrijednosti.<br />
Pri tome se razlikuju lokalne i globalne varijable:<br />
Lokalne varijable deklariraju se od strane korisnika i koriste<br />
na nain identian kao u svim višim programskim jezicima.<br />
Globalne varijable predefinirane su od strane SQL sustava i<br />
njima rukuju interni mehanizmi baze <strong>podataka</strong>.<br />
Lokalne varijable deklariraju se i koriste u sklopu slijeda<br />
SQL instrukcija ili SQL procedura (stored procedures),<br />
korištenjem kljune rijei DECLARE u obliku:<br />
DECLARE @naziv tip_podatka, @naziv2 tip_podatka2, ….
!*"A!<br />
DECLARE @naziv tip_podatka, @naziv2 tip_podatka2, ….<br />
naziv: ime varijable. @ predstavlja oznaku za lokalnu<br />
varijablu.<br />
Korištenje lokalne varijable mogue je samo u sklopu slijeda<br />
instrukcija ili procedure gdje je ta varijable definirana.<br />
Vrijednost varijabli pridijeljuje se u sklopu select izraza:<br />
SELECT @varijabla = SQL izraz<br />
SELECT izraz kojim se pridijeljuje vrijednost varijable uobiajeno vraa<br />
samo jednu vrijednost (jedan red izlaznog rezultata).<br />
Ako SELECT izraz vraa više vrijednosti, varijabli se pridijeljuje<br />
posljednja vrijednost.<br />
Ako SELECT izraz ne vraa nikakav rezultat, varijabla zadržava svoju<br />
prethodnu vrijednost.<br />
<br />
<br />
!*"A!<br />
Primjer:<br />
Slijedom SQL instrukcija prikazati podatke za studenta sa zadanim<br />
JMBG, u formi opisa: ime, prezime i godina studija na kojoj se trenutno<br />
nalazi.<br />
DECLARE @sIme varchar(30), @sPrezime varchar(30),@iSem tinyint<br />
SELECT @sPrezime=PREZIME, @sIme=IME, @iSem=MAX(SEM)<br />
FROM STUDENT INNER JOIN UPISNI_LIST<br />
ON STUDENT. STUDENT_ID = UPISNI_LIST.STUDENT_ID<br />
WHERE JMBG = '2605980385031'<br />
GROUP BY PREZIME, IME<br />
SELECT Opis=@sPrezime+''+@sIme+'student '<br />
+CONVERT(VARCHAR(5),@iSem/2+@iSem%2)+'. godine'<br />
@&%<br />
$"!*) "%!"' %;"!!;J)"<br />
*'$A<br />
!!@ !!*"<br />
"%$*0"<br />
'$
!*"A!<br />
<br />
<br />
!*"A!<br />
Globalne varijable se koriste bez deklariranja, imaju<br />
oznaku @@, njima upravlja sam sustav baze <strong>podataka</strong>, a<br />
koriste se uglavnom za uvid u sistemske aktivnosti ili<br />
informacije o aktivnostima korisnika u bazi.<br />
Neke od naješe korištenih globalnih varijabli su:<br />
@@ERROR – Sistemska varijabla koja sadržava brojani<br />
podatak o greški. Ova varijabla se esto koristi za kontrolu<br />
uspješnog obavljanja pojedinih SQL instrukcija.<br />
Ukoliko je SQL instrukcija uspješno obavljena vrijednost<br />
varijable je 0.<br />
Kod izvršavanja svake SQL instrukcije vrijednost ove<br />
varijable se resetira, pa je provjeru greške potrebno obaviti<br />
neposredno nakon instrukcije kojoj se ispituje valjanost.
!*"A!<br />
@@IDENTITY – Sadržava podatak o posljednjoj generiranoj<br />
IDENTITY vrijednosti.<br />
Vrijednost varijable se mijenja nakon svake INSERT ili<br />
SELECT INTO instrukcije.<br />
Ako se unos <strong>podataka</strong> obavlja u tablici koja ne sadrži<br />
IDENTITY kolone ili sistem ne može generirati novu<br />
vrijednost za IDENTITY kolonu vrijednost @@IDENTITY se<br />
postavlja na null.<br />
Ako se pri obavljanju unosa <strong>podataka</strong> dogodi greška,<br />
vrijednost @@IDENTITY globalne varijable ne može se<br />
vratiti na prethodno stanje.<br />
@@ROWCOUNT – Sadržava podatak o broju redova na<br />
koje djeluje posljednji SQL izraz.<br />
Svaki izraz koji ne djeluje izravno na podatke (npr. IF izraz)<br />
postavlja vrijednost ove varijable u 0.<br />
<br />
<br />
>""("%*(<br />
Kontrola programskog toka (slijeda instrukcija) u SQLu<br />
provodi se primjenom slijedeih izraza:<br />
Izraz<br />
BEGIN...END<br />
BREAK<br />
CONTINUE<br />
GOTO label<br />
IF...ELSE<br />
RETURN<br />
WHILE<br />
Opis<br />
Definira blok instrukcija<br />
Izlaz iz WHILE petlje<br />
Nastavak obrade WHILE petlje<br />
Nastavlja izvršavanje instrukcija od izraza koji je<br />
oznaen sa label<br />
Definira uvjetno izvršavanje instrukcija<br />
Bezuvjetni izlaz iz bloka instrukcija<br />
Ponavlja niz instrukcija dok je postavljeni uvjet<br />
istinit (TRUE)
""("%*(<br />
BEGIN…END<br />
Definira blok instrukcija koje se izvršavaju zajedno.<br />
Naješe se primijenjuje u uvjetnim strukturama tipa IF…ELSE, gdje je<br />
u zavisnosti od uvjeta potrebno izvršavanje veeg broja instrukcija.<br />
Sintaksa:<br />
BEGIN<br />
SQL izrazi<br />
END<br />
BEGIN i END izraz moraju se koristiti zajedno (u paru). Jedan bez<br />
drugoga ne mogu biti upotrebljeni u SQL izrazima.<br />
<br />
<br />
IF…ELSE<br />
>""("%*(<br />
Postavlja uvjet na izvršavanje SQL izraza.<br />
SQL izraz koji slijedi nakon IF instrukcije i njezinog uvjeta izvršava se<br />
samo ako je uvjet zadovoljen (TRUE).<br />
Opcionalni ELSE izraz definira SQL instrukciju koja se izvršava ako uvjet<br />
nije zadovoljen.<br />
Sintaksa: IF uvjetni_izraz<br />
SQL izraz<br />
[ELSE uvjetni_izraz2<br />
SQL izraz]<br />
uvjetni_izraz – izraz Boolovog tipa koji vraa istinu (TRUE) ili neistinu<br />
(FALSE). Ako ovaj izraz sadržava SELECT upit onda taj upit mora biti<br />
naveden u zagradama.<br />
SQL izraz – jedna ili više SQL instrukcija koje se izvršavaju u zavisnosti<br />
od toga da li je uvjetni_izraz zadovoljen.<br />
IF i ELSE uvjet pokree izvršavanje samo jedne SQL instrukcije.<br />
Ukoliko je potrebno u zavisnosti u uvjetnom izrazu pokrenuti više SQL<br />
instrukcija, te instrukcije treba definirati kao blok BEGIN…END.
Primjer:<br />
>""("%*(<br />
Definirati slijed SQL instrukcija kojima se prikazuju podaci o studentu<br />
(ime, prezime i jmbg), ako je zadano ime i prezime studenta.<br />
Pri tome je potrebno imati na umu slijedee mogunosti:<br />
- student zadanog prezimena i imena ne postoji u tablici<br />
- postoji više studenata sa istim imenom i prezimenom.<br />
U ovim specijalnim sluajevima slijed SQL instrukcija treba vratiti<br />
odgovarajue obavijesti.<br />
Ako traženi student postoji ispisati njegovo ime, prezime i jmbg.<br />
<br />
<br />
>""("%*(
""("%*(<br />
<br />
<br />
>""("%*(
""("%*(<br />
Zadatatak je mogue riješiti i drugim putem (korištenjem globalne<br />
varijable @@ROWCOUNT.<br />
<br />
<br />
RETURN<br />
>""("%*(<br />
Predstavlja bezuvjetni kraj slijeda instrukcija (batch) ili procedure. Svi<br />
izrazi koji slijede nakon RETURN ne izvršavaju se.<br />
WHILE<br />
Postavlja uvjet na temelju kojeg se izvršava SQL instrukcija ili više njih<br />
(blok SQL instrukcija) obuhvaenih sa BEGIN…END.<br />
Sintaksa:<br />
WHILE uvjetni_izraz<br />
{sql_izraz | blok SQL instrukcija}<br />
[BREAK]<br />
{sql_izraz | blok SQL instrukcija}<br />
[CONTINUE]<br />
SQL instrukcija ili blok instrukcija obuhvaenih sa BEGIN…END<br />
izvršavaju se dok je uvjetni izraz u WHILE dijelu istinit.<br />
Izvršavanje SQL instrukcija obuhvaenih WHILE petljom može se<br />
kontrolirati unutar petlje primjenom instrukcija prekida (BREAK) i<br />
nastavka izvršavanja (CONTINUE).
""("%*(<br />
Primjer:<br />
U tablici prozvoda izvršiti poveanje cijene proizvoda sve dok se ne<br />
postigne prosjena cijena što bliže 30,00. Pri tome najviša cijena<br />
proizvoda ne smije prijei 50,00.<br />
WHILE (SELECT MAX(cijena) FROM proizvod) < 50<br />
BEGIN<br />
UPDATE proizvod SET cijena = cijena * 2<br />
IF (SELECT AVG(cijena) FROM proizvod) >= 30<br />
BREAK<br />
ELSE<br />
CONTINUE<br />
END<br />
<br />
<br />
Primjer:<br />
>""("%*(<br />
Zadana je tablica ISPIT_GRUPA, koja sadržava podatke o ispitnim<br />
grupama.<br />
U tablici bi za svaku ispitnu grupu trebalo pisati broj ispitne grupe (1-10) i<br />
datum održavanja ispita u ispitnoj grupi.<br />
Napisati instrukcije koje na temelju zadanog datuma ispitnog roka,<br />
unose podatke za ispitne grupe, po sljedeem pravilu:<br />
Poetak ispitnog roka uvijek je u ponedjeljak.<br />
U svakom roku održavaju se ispiti iz 10 ispitnih grupa, pri emu je svaka<br />
ispitna grupa slijedei dan, uz izuzetak subote i nedjelje.
""("%*(<br />
O "<br />
<br />
<br />
TRANSAKCIJE (TRANSACTIONS)<br />
-"*A!<br />
Osnovna namjena suvremenih DBMS sustava za rukovanje<br />
bazama <strong>podataka</strong> je omoguavanje istovremenog rada<br />
veoj grupi korisnika nad istom bazom <strong>podataka</strong>.<br />
Pri tome jedni unose podatke, drugi ih ažuriraju, a trei<br />
samo pretražuju.<br />
Kod takvog rada, esti su sluajevi da više korisnika dohvaa istu grupu<br />
<strong>podataka</strong>. Pri tome korisnik ima dojam da samo on pristupa podacima,<br />
neovisno od ostalih korisnika.<br />
Transakcija je skup SQL instrukcija koje se izvršavaju<br />
zajedno.<br />
Transakcija poinje oznakom BEGIN TRAN, a završava<br />
pozitivnim ishodom (izvršenjem transakcije) – COMMIT<br />
TRAN, ili negativnim ishodom (poništenjem transakcije) -<br />
ROLLBACK TRAN.
Primjer:<br />
head (STUDENT)={student_id, ime, prezime}<br />
student_id =PK(STUDENT), IDENTITY<br />
head(UPISNI_LIST)={ulist_id, student_id, sem,sk_god}<br />
ulist_id=PK(UPISNI_LIST), IDENTITY<br />
-"*A!<br />
<br />
<br />
-"*A!<br />
Sve instrukcije obuhvaene transakcijom izvršavaju se po<br />
principu sve ili ništa.<br />
To znai da se, u sluaju prekida transakcije zbog greške u<br />
nekoj od instrukcija, poništavaju sve akcije koje su<br />
transakcijom obuhvaene.<br />
Prilikom pokretanja transakcije sve akcije koje su njom<br />
obuhvaene, odvijaju se u posebnom dijelu baze, koji se<br />
naziva transakcijski log (transaction log).<br />
U sluaju uspješnog završetka transakcije, rezultati tj.<br />
podaci koji proizlaze iz transakcije, zapisuju se fiziki na<br />
disk u bazu <strong>podataka</strong>.<br />
To znai da su rezultati koje je transakcija dala, vidljivi tek<br />
nakon što se stvarno fiziki zapišu u bazu na disku.
-"*A!<br />
Sve instrukcije obuhvaene transakcijom izvršavaju se po<br />
principu sve ili ništa.<br />
To znai da se, u sluaju prekida transakcije zbog greške u<br />
nekoj od instrukcija, poništavaju sve akcije koje su<br />
transakcijom obuhvaene.<br />
Prilikom pokretanja transakcije sve akcije koje su njom<br />
obuhvaene, odvijaju se u posebnom dijelu baze, koji se<br />
naziva transakcijski log (transaction log).<br />
U sluaju uspješnog završetka transakcije, rezultati tj.<br />
podaci koji proizlaze iz transakcije, zapisuju se fiziki na<br />
disk u bazu <strong>podataka</strong>.<br />
To znai da su rezultati koje je transakcija dala, vidljivi tek<br />
nakon što se stvarno fiziki zapišu u bazu na disku.<br />
<br />
<br />
Sve instrukcije obuhvaene<br />
transakcijom izvršavaju se<br />
po principu sve ili ništa.<br />
-"*A!<br />
Primjer:<br />
Slanje dnevnog prometa iz<br />
trgovine Trgovina x u centralnu<br />
bazu <strong>podataka</strong> IS-a.<br />
0. Preduvjet:<br />
0.1. kasa je zakljuena<br />
0.2. dnevni promet je<br />
obraunat<br />
1. Slanje dnevnog prometa<br />
1.1. Provjera je li promet ve poslan (provjera oznake ‘nije poslan’)<br />
1.2. itanje <strong>podataka</strong> iz tablica baze <strong>podataka</strong> Trgovina x<br />
1.3. Prijava na centralnu bazu <strong>podataka</strong><br />
1.4. Upis proitanih <strong>podataka</strong> u centralnu bazu <strong>podataka</strong><br />
1.5. Odjava sa centralne baze <strong>podataka</strong><br />
1.6. Upis oznake ‘poslano’ za poslani dnevni promet u Trgovini x.<br />
<br />
"*A!
Problem zavisnosti o nepotvrenoj promjeni<br />
(kako bi to izgledalo kada ne bi postojali transakcijski log-ovi)<br />
Promotrimo primjer meuzavisnosti dvaju transakcija na slici:<br />
-"*A!<br />
Transakcija T1 u prvom koraku (trenutak t1) ažurira podatke P1. Kada<br />
bi ovi podaci bili odmah fiziki promijenjeni u tablici, tu promijenu mogli<br />
bi vidjeti i drugi korisnici.<br />
U trenutku t2 nastupa transakcija T2, koja ita izmjenjene podatke P1.<br />
Transakcija T1 izvršava se dalje i završava ROLLBACK-om, što znai<br />
da se sve akcije te transakcije poništavaju.<br />
Stoga podaci P1 ostaju u stanju prije promjene.<br />
U ovom sluaju transakcija T2 bi proitala krive podatke!<br />
<br />
<br />
Uloga transakcijskog log-a kod sistemskih prekida<br />
-"*A!<br />
Raunala na kojima se nalaze baze <strong>podataka</strong> podložna su<br />
sistemskim prekidima (tzv. soft crash).<br />
Jedan od estih tipova sistemskih prekida je gubitak<br />
napajanja. Nestanak struje se može dogoditi<br />
- u trenutku izvršavanja neke transakcije,<br />
- u trenutku kad se rezultati neke transakcije<br />
zapisuju u bazu <strong>podataka</strong> na disk.<br />
Kako znati gdje je sustav “stao”, tj. što je od tekuih<br />
operacija izvršeno a što nije?
-"*A!<br />
Stanje izvršavanja svih<br />
transakcija bilježi se u<br />
transakcijskom log-u (Slika).<br />
Nakon odreenog perioda<br />
sustav uvodi kontrolne toke<br />
(checkpoint).<br />
$'"/"/+6<br />
$'"/"/+<br />
U trenutku kada nastupa checkpoint, pokree se fiziki<br />
zapis <strong>podataka</strong> u tablicu na disku za sve transakcije<br />
koje su obavljene u log-u, a iji sadržaj nije još zapisan<br />
u bazu.<br />
<br />
Sve transakcije koje su u<br />
tijeku u trenutku uzimanja<br />
checkpointa, pamte se u<br />
posebnoj checkpoint<br />
datoteci. U sluaju prekida u<br />
sustavu, nakon ponovnog<br />
pokretanja, sustav ulazi u<br />
režim oporavka (recovery).<br />
Oporavak poinje pregledom checkpoint datoteke i<br />
ustanovljavanjem koje su transakcije bile u tijeku.<br />
Nakon toga slijedi prijelaz u transakcijski log, gdje poinje<br />
pregled onih transakcija koje su zabilježene u checkpoint<br />
datoteci, kao i svih kasnijih.<br />
Transakcije koje su obavljene u transakcijskom logu, a njihov<br />
rezultat nije zapisan u tablice, pokreu se ponovo (REDO), a<br />
one koje u trenutku prekida nisu bile dovršene uklanjaju se<br />
(UNDO).
Primjer:<br />
Promatra se stanje izvršavanja<br />
transakcija u vremenskom periodu<br />
prema slici.<br />
Nastupanjem kontrolne toke<br />
(checkpoint), rezultati svih završenih<br />
transakcija (a to je u ovom sluaju<br />
samo T1) zapisuju se fiziki u tablice<br />
baze <strong>podataka</strong>.<br />
U checkpoint datoteku pohranjuju se<br />
podaci o transakcijama koje su u<br />
trenutku uzimanja kontrolne toke<br />
bile u izvršavanju (T2).<br />
$'"/"/+B1<br />
-"*A!<br />
Pretpostavka je da sistemski prekid nastupa u trenutku Tf.<br />
Transakcije T2 i T4 još uvijek nisu završene, dok je transakcija T3 izvršena u<br />
transakcijskom logu, ali je neizvjesno da li je njezin sadržaj zapisan u bazu.<br />
Kod postupka oporavka, sustav provjerava checkpoint datoteku i utvruje da je u<br />
trenutku posljednje kontrole log-a u tijeku bila transakcija T2. Zatim prelazi u<br />
transakcijski log, te kontrolira stanje transakcije T2 i onih koje su zapoete<br />
poslije T2 (T3 i T4). Budui transakcije T2 i T4 nisu završene u transakcijskom<br />
logu, one se poništavaju, a transakcija T3 se ponavlja.<br />
<br />
<br />
Zakljuavanje <strong>podataka</strong> u bazi<br />
-"*A!<br />
Svaka transakcija obavlja se u relativnoj izolaciji u odnosu na<br />
druge transakcije, tj. vrijedi pravilo da nitko drugi ne može<br />
pristupiti podacima koje jedan korisnik mijenja ili briše.<br />
Meutim, podatke koje jedan korisnik ita mogu itati i drugi korisnici, jer<br />
samo itanje <strong>podataka</strong> ne donosi nikakve promjene na podacima.<br />
Ovakav sustav zaštite pristupa podacima realizira se<br />
zakljuavanjem onih dijelova baze <strong>podataka</strong> nad kojima se<br />
provode pojedine operacije, tj. postavljanjem lokota (lock).<br />
Sustavi baza <strong>podataka</strong> prepoznaju dvije vrste lokota:<br />
- djeljivi lokot (shared), koji se postavlja na podacima<br />
koji se samo išitavaju (select), i<br />
- ekskluzivni lokot (exclusive), koji se postavlja na<br />
podacima koji se obrauju.<br />
Lokot nad odreenim podacima postavlja SUBP automatski u<br />
zavisnosti o tipu akcije koja se nad podacima provodi.
-"*A!<br />
S – shared lokot<br />
X – exclusive lokot<br />
Kada neka transakcija T2 zahtijeva pristup podacima za obradu, ona<br />
ujedno traži lokot nad tim podacima.<br />
Ukoliko iste podatke obrauje neka druga transakcija T1, ona ve drži<br />
lokot nad tim podacima.<br />
Ishod ovakvog stanja zavisi od tipa obrade nad podacima koje<br />
pojedine transakcije vrše.<br />
Slika prikazuje meusobne veze meu lokotima, u redovima su<br />
prikazani lokoti koje drži transakcija T1, a po stupcima lokoti koje<br />
zahtjeva transakcija T2.<br />
Iz toga je vidljivo da dvije transakcije mogu pristupiti istim podacima<br />
(D u tablici) jedino ako obje transakcije iskljuivo itaju podatke.<br />
<br />
<br />
Problem gubitka ažuriranih<br />
informacija<br />
-"*A!<br />
Meudjelovanje dvaju transakcija i<br />
nužnost primjene lokota može se<br />
uoiti na slijedeem primjeru dvaju<br />
transakcija:<br />
Primjer pokazuje meudjelovanje dvaju transakcija.<br />
T1 mijenja podatke P1, a T2 traži pristup istim podacima dok T1 još nije<br />
završen.<br />
Transakcija T1 primila je podatke P1 u obradu, i izvršila ažuriranje<br />
<strong>podataka</strong> P1.<br />
U trenutku t2, pristup istim podacima traži T2, ali T1 još uvijek traje, što<br />
znai da promjena <strong>podataka</strong> P1 još nije zapisana u odgovarajuu tablicu.<br />
Stoga T2 ita prethodno stanje <strong>podataka</strong> P1 bez promjena koje je<br />
izvršila transakcija T1.<br />
Tek u trenutku t4 završava T1 i rezultati transakcije se zapisuju u tablicu.<br />
U trenutku t5 završava transakcija T2 koja svoje “rezultate” zapisuje<br />
fiziki u tablicu, te poništava promjene koje je izvršila transakcija T1.
Rješenje problema je u primjeni lokota (lock)<br />
-"*A!<br />
U trenutku t1 transakcija T1 dohvaa podatke P1 i na njima postavlja<br />
djeljivi lokot. U trenutku t2 istim podacima pristupa transakcija T2 i<br />
postavlja svoj djeljivi lokot. Transakcija T1 u trenutku t3 treba izvršiti<br />
promjenu na podacima, te traži pretvaranje svog djeljivog lokota u<br />
ekskluzivni (X-lock). Taj lokot ne dobija budui transakcija T2 nad istim<br />
podacima drži S-lock. Transakcija T2 takoer traži X-lock, ali bez<br />
uspjeha jer postoji S-lock od strane transakcije T1. Ne dolazi do<br />
gubitka informacija, ali obje transakcije prelaze u stanje ekanja.<br />
Ova pojava se naziva deadlock.<br />
<br />
<br />
-"*A!<br />
Deadlock:<br />
Dvije transakcije svojim zahtjevima blokiraju jedna drugu, te<br />
onemoguavaju pristup podacima.<br />
Sustavi baza <strong>podataka</strong> imaju ugraene mehanizme za detekciju<br />
deadlock-a.<br />
Uobiajeni nain razrješavanja ovakve situacije je prekid jedne od<br />
transakcija, što drugoj omoguava normalan nastavak i izvršavanje do<br />
kraja.
Razumljivo, deadlock nije zadovoljavajue rješenje meudjelovanja<br />
transakcija. Umjesto toga interni mehanizmi baze <strong>podataka</strong> vrše<br />
prilagoavanje lokota strukturi same transakcije.<br />
-"*A!<br />
Djelovanje lokota razrješava ovakve situacije, jer omoguava da se<br />
promjene na podacima odvijaju u relativnoj izolaciji, pa u navedenom<br />
sluaju, transakcija T2 može pristupiti podacima P1, tek nakon što T1<br />
izvrši promjenu, a u tom sluaju transakcija T2, ita stvarne podatke,<br />
dakle nakon njihove promjene.<br />
<br />
<br />
Nivoi zakljuavanja<br />
-"*A!<br />
Sustav može postaviti lokot ili na stranicu memorije (page)<br />
ili na cijelu tablicu.<br />
Kad god je to mogue, postavlja se lokot na stranicu.<br />
Razlog je u injenici da takvo postavljanje lokota ini<br />
podatke dostupnijim korisnicima.<br />
Tako istovremeno više korisnika može pristupiti podacima<br />
iz iste tablice, ali sa razliitih stranica, a i dohvat <strong>podataka</strong><br />
je brži.
SQL Stored Procedures<br />
"$"A"*<br />
U razvoju i obradi baze <strong>podataka</strong>, esta je potreba<br />
korištenja slijeda instrukcija kojima se više SQL<br />
instrukcija izvršavaju u nizu, kao jedinstvena cjelina.<br />
Veina SQL platformi nudi mogunost pohrane bloka<br />
SQL instrukcija u posebnom obliku nazvanom<br />
procedure (stored procedures).<br />
Ovakve strukture u mnogome olakšavaju i ubrzavaju<br />
rad sa bazama i poveavaju efikasnost.<br />
<br />
<br />
"$"A"*<br />
Po svom nainu djelovanja i primjeni SQL procedure ne<br />
razlikuju se bitno od uobiajenih procedura koje se koriste u<br />
višim programskim jezicima.<br />
Prihvaaju ulazne parametre (argumente)<br />
Vraaju rezultat obrade u obliku izlaznih parametara<br />
Vraaju rezultat obrade u obliku skupa rezultata<br />
Sadržavaju niz SQL programskih instrukcija kojima se<br />
vrše operacije nad podacima u bazi<br />
Omoguavaju pozivanje ostalih procedura<br />
Vraaju podatak o statusu izvršavanja procedure
"$"A"*<br />
<br />
<br />
"$"A"*<br />
Prednosti korištenja SQL procedura oituju se u slijedeem:<br />
Modularno programiranje<br />
Procedure se formiraju jednom, te se mogu pozivati nebrojeno<br />
puta, kad god postoji potreba za obradom koju vrši procedura.<br />
Sve eventualne izmjene u proceduri mogu se kreirati<br />
nezavisno od klijentske aplikacije.<br />
Sigurnosni aspekt<br />
Pravo izvršavanja SQL procedura može se dodijeliti nezavisno<br />
od prava izvršavanja pojedinih izraza koji su obuhvaeni<br />
procedurom.
"$"A"*<br />
Prednosti korištenja SQL procedura oituju se u slijedeem:<br />
Brzina izvršavanja<br />
SQL procedure razlikuju se od uobiajenog slijeda SQL<br />
instrukcija, budui se koriste u pre-kompajliranom i<br />
optimiziranom obliku.<br />
- Prvo se definira (napiše) procedura.<br />
- Prilikom prvog poziva i izvršenja sve SQL instrukcije koje<br />
su obuhvaene procedurom se kompajliraju i<br />
optimiziraju.<br />
- Procedura se pohranjuje u sistemski katalog baze<br />
<strong>podataka</strong>, u intrenom obliku tj. u obliku spremnom za<br />
izvršavanje.<br />
- Stoga se pri ponovnim pozivanjima i korištenju procedure<br />
koristi izvršni oblik, bez ponovnog kompaliranja i<br />
optimiranja.<br />
<br />
<br />
Prednosti korištenja SQL procedura oituju se u slijedeem:<br />
"$"A"*<br />
Smanjenje mrežnog prometa<br />
Pri korištenju baze <strong>podataka</strong> u client-server strukturi,<br />
umjesto slanja veeg broja SQL instrukcija, šalje se samo<br />
zahtjev za izvršavanje procedure u obliku jedne instrukcije.<br />
SQL procedura stvara se izrazom CREATE PROCEDURE.<br />
Pravo stvaranja procedura ima onaj tko je stvorio bazu<br />
(DB Administrator), a on ta prava može dodijeliti ostalim<br />
korisnicima.<br />
Procedure predstavljaju posebne objekte u bazi, te u jednoj<br />
bazi ne mogu postojati dvije procedure istog naziva.<br />
Prilikom stvaranja procedure potrebno je definirati:<br />
- Ulazne i izlazne parametre,<br />
- SQL instrukcije kojima se izvršavaju operacije u bazi,<br />
- Povratnu vrijednost (status value), kojom se definira status procedure.
"$"A"*<br />
CREATE PROCEDURE naziv_procedure<br />
{@parametar tip_podatka} [= default] [OUTPUT]<br />
{@parametar tip_podatka} [= default] [OUTPUT]<br />
[WITH {RECOMPILE | ENCRYPTION | RECOMPILE,<br />
ENCRYPTION}]<br />
AS<br />
SQL_izrazi [...n]<br />
naziv_procedure - ime SQL procedure<br />
@parametar tip_podatka [= default] [OUTPUT] – definicija<br />
parametara (argumenata) procedure.<br />
Može se definirati od 1 do najviše 255 parametara.<br />
Prvi znak u parametru mora biti znak @ (simbol varijable).<br />
Oznaka tip_podatka predstavlja tip podatka pojedinog<br />
parametra.<br />
<br />
<br />
- još o parametrima procedure -<br />
"$"A"*<br />
Oznaka default predstavlja inicijalnu vrijednost parametra pri<br />
pozivu (izvršavanju) procedure.<br />
Prilikom pozivanja procedure potrebno je navesti<br />
vrijednost za svaki definirani parametar. Ukoliko se<br />
za odreeni parametar navede default vrijednost,<br />
tada se pri izvršavanju procedure, za taj parametar<br />
ne mora navesti vrijednost, ve se vrijednost<br />
parametra postavlja na default vrijednost.<br />
Klauzula OUTPUT u definiciji parametra oznaava da se<br />
radi o izlaznom parametru koji vraa informaciju iz<br />
procedure.
- još o definiranju procedure -<br />
WITH {RECOMPILE | ENCRYPTION | RECOMPILE,<br />
ENCRYPTION} – opcije<br />
"$"A"*<br />
RECOMPILE – naznauje da se pri izvršavanju procedure<br />
ne koristi prekompajlirana i optimirana struktura procedure<br />
iz sistemskog kataloga baze, ve se procedura pri svakom<br />
izvršavanju iznova kompajlira.<br />
ENCRYPTION – oznaava sigurnosno kodiranje SQL<br />
procedure, iji sadržaj nakon kompajliranja i izvršavanja,<br />
postaje kodiran za sve korisnike.<br />
<br />
<br />
Primjer:<br />
Procedura bez ulaznih parametara.<br />
Deklarirati proceduru koja prikazuje podatke o svim studentima<br />
upisanim u 1.semestar školske godine 2004/05.<br />
"$"A"*<br />
CREATE PROCEDURE statistika<br />
AS<br />
SELECT PREZIME, IME, STAN=ISNULL( ADRESA,'') + ', '+<br />
IME_MJESTA, OBR_PROG_IME<br />
FROM STUDENT INNER JOIN MJESTO<br />
ON STUDENT.MJESTO_STAN=MJESTO.MJESTO_ID<br />
INNER JOIN UPISNI_LIST<br />
ON STUDENT.STUDENT_ID=UPISNI_LIST.STUDENT_ID<br />
INNER JOIN OBR_PROG<br />
ON UPISNI_LIST.OBR_PROG_ID=OBR_PROG.OBR_PROG_ID<br />
WHERE SK_GOD=’2004/05’<br />
AND SEM=1
"$"A"*<br />
Primjer:<br />
Procedura sa ulaznim parametrima.<br />
Deklarirati proceduru koja prikazuje podatke o svim studentima, gdje su<br />
semestar i školska godina ulazni parametri.<br />
CREATE PROCEDURE statistika2<br />
@iSem tinyint,<br />
@sSkgod varchar(10)<br />
AS<br />
SELECT PREZIME, IME, STAN= ISNULL(ADRESA,'') + ', '+<br />
IME_MJESTA, OBR_PROG_IME<br />
FROM STUDENT INNER JOIN MJESTO<br />
ON STUDENT.MJESTO_STAN=MJESTO.MJESTO_ID<br />
INNER JOIN UPISNI_LIST<br />
ON STUDENT.STUDENT_ID=UPISNI_LIST.STUDENT_ID<br />
INNER JOIN OBR_PROG<br />
ON UPISNI_LIST.OBR_PROG_ID=OBR_PROG.OBR_PROG_ID<br />
WHERE SK_GOD=@sSkgod AND SEM=@iSem<br />
<br />
<br />
"$"A"*<br />
Primjer:<br />
Procedura sa izlaznim parametrima.<br />
Deklarirati proceduru koja za zadano mjesto vraa broj studenata koji u<br />
njemu stanuju.<br />
CREATE PROCEDURE stanovanje<br />
@iBroj int OUTPUT,<br />
@sImeMjesta varchar(10)<br />
AS<br />
SELECT @iBroj =count(*)<br />
FROM STUDENT INNER JOIN MJESTO<br />
ON STUDENT.MJESTO_STAN=MJESTO.MJESTO_ID<br />
WHERE IME_MJESTA=@sImeMjesta
Izvršavanje procedure pokree se izrazom oblika:<br />
EXEC naziv_procedure parametri<br />
Pri emu se parametri navode kao lista vrijednosti<br />
meusobno odvojenih zarezom, ili u obliku:<br />
@parametar=vrijednost.<br />
"$"A"*<br />
Ukoliko se parametri (argumenti) procedure navode u obliku<br />
@parametar=vrijednost, može ih se navesti u bilo kojem<br />
redoslijedu, budui se u ovakvom obliku tono navodi kojem<br />
parametru se pridijeljuje koja vrijednost.<br />
Ukoliko se parametri navode samo kao vrijednosti, moraju<br />
se navesti u onom redoslijedu u kojem su navedeni kod<br />
stvaranja procedure.<br />
<br />
<br />
&<br />
8". "A" P*!*!Q&<br />
>"!" "A" ?16/-6 # *%"!<br />
"$"A"*<br />
6!!"D!%!)"! # !. <br />
8". "A" !.
Primjer: EXEC statistika2 1, '2004/05'<br />
"$"A"*<br />
ili<br />
EXEC statistika2 @iSem=1,@sSkgod='2004/05'<br />
EXEC statistika2 @iSem=1, @sSkgod='2004/05' je isto kao i<br />
EXEC statistika2 @sSkgod='2004/05', @iSem=1<br />
<br />
<br />
"$"A"*<br />
Prilikom navoenja parametara može se primijeniti bilo koji od<br />
navedenih oblika, ali nije mogua njihova kombinacija.<br />
Drugim rjeima, ako se jedan parametar navede u obliku<br />
@parametar=vrijednost, tada svi parametri moraju biti u tom obliku.<br />
Tako se ne može navesti:<br />
6R6?*!*! S!%TDHLP<br />
Prilikom izvršavanja procedure potrebno je navesti sve parametre, osim<br />
onih za koje je u definiciji procedure navedena default vrijednost.
"$"A"*<br />
Ukoliko je procedura definirana sa jednim ili više izlaznih parametara<br />
(OUTPUT opcija parametra), pri izvršavanju procedure takve parametre<br />
potrebno je takoer deklarirati kao izlazne.<br />
Primjer: Jednostavna procedura sa izlaznim parametrom.<br />
<br />
<br />
"$"A"*<br />
Ukoliko se pri pozivu procedure neki od parametara deklarira kao izlazni<br />
parametar, a da taj parametar u isto vrijeme nije deklariran kao izlazni u<br />
definiciji procedure, javlja se greška.<br />
Primjer: Neka za izvršenje procedure djeljenje koristimo slijedee<br />
instrukcije:<br />
Ovakav nain pozivanja procedure generira grešku budui je varijabla<br />
@var1 deklarirana kao izlazna varijabla (koja preuzima vrijednost iz<br />
procedure), a u definiciji procedure pripadajui parametar @divizor nije<br />
deklariran kao izlazni.
"$"A"*<br />
U sluaju kada je parametar naveden kao izlazni u definiciji procedure,<br />
a nije kod izvršavanja procedure, procedura se normalno izvršava, ali<br />
varijabla u pozivu procedure ne prihvaa vrijednost koju procedura šalje<br />
kao izlaznu.<br />
Primjer: Neka za izvršenje procedure djeljenje koristimo slijedee<br />
instrukcije:<br />
Iako je u definiciji procedure parametar @kvocijent naveden kao izlazni<br />
parametar, kod poziva procedure @rezultat nije deklariran kao argument<br />
izlaznog tipa.<br />
Procedura se normalno izvršava, ali varijabla @rezultat ne može prihvatiti<br />
vrijednost koju procedura daje, pa je rezultat NULL.<br />
<br />
<br />
"$"A"*<br />
Uz podatke koje procedure vraaju u obliku skupa rezultata i<br />
izlaznih parametara, procedura daje i poseban podatak o<br />
statusu.<br />
Status oznaava je li procedura izvršena ispravno ili je<br />
tijekom izvršavanja instrukcija koje su sadržane u proceduri<br />
nastupila pogreška.<br />
Status je podatak cjelobrojnog tipa (integer) i naziva se<br />
povratno stanje procedure (return status).<br />
U sluaju da je procedura završena uspješno (sve instrukcije<br />
obavljene bez greške), vrijednost povratnog stanja je 0.<br />
Ako tijekom izvršavanja instrukcija u proceduri nastupi<br />
pogreška, povratno stanje je negativni cijeli broj, kojim je<br />
opisan tip pogreške.
"$"A"*<br />
Izvršavanje procedure, uz prihvaanje povratnog stanja<br />
procedure vrši se instrukcijom oblika:<br />
EXECUTE @lRetStatus = naziv_procedure parametri<br />
gdje je @lRetStatus varijabla cjelobrojnog tipa.<br />
Primjer: Ispis povratnog stanja za proceduru dijeljenja dva broja:<br />
<br />
<br />
"$"A"*<br />
Izvršavanje procedure završava kada se izvrši posljednja<br />
instrukcija u proceduri ili izvršenjem naredbe RETURN.<br />
RETURN znai bezuvjetan izlaz iz procedure.<br />
Instrukcije koje slijede nakon naredbe RETURN ne<br />
izvršavaju se.<br />
Iako se vrijednost povratnog stanja procedure postavlja<br />
sistemski, korisnik može definirati i postaviti vlastita<br />
povratna stanja.<br />
Povratno stanje odreuje se dodavanjem cjelobrojnog<br />
podatka naredbi RETURN:<br />
Npr. RETURN 3
"$"A"*<br />
Primjer:<br />
Deklarirana je procedura koja prima ulazni podatak JMBG studenta, te vraa<br />
prezime i ime studenta u obliku izlaznog parametra.<br />
U proceduri se ispituje valjanost ulaznog podatka, te dobiveni rezultat pretraživanja<br />
i temeljem toga formiraju vrijednosti povratnog stanja.<br />
<br />
<br />
"$"A"*<br />
Primjer – nastavak:<br />
U korištenju procedure potrebno je prihvatiti povratno stanje te na temelju tih<br />
vrijednosti formirati prikaz rezultata korisniku.
"$"A"*<br />
Prilikom obrade baza <strong>podataka</strong>, esta je potreba za ugnježivanjem<br />
SQL procedura (gdje jedna procedura poziva drugu i koristi njezine<br />
rezultate).<br />
Primjer: Deklarirati proceduru O_STUDENTU1 koja prima ulazni podatak JMBG<br />
studenta, te poziva proceduru O_STUDENTU:<br />
Izvršenje procedure O_STUDENTU1:<br />
<br />
<br />
"$"A"*<br />
Primjer:<br />
Zadatak je stvoriti proceduru za unos <strong>podataka</strong> u tablicu STUDENT, uz<br />
poseban mehanizam automatskog generiranja matinog broja.<br />
Princip automatskog generiranja podrazumijeva format x-gggg,<br />
gdje je gggg oznaka godine u kojoj se student upisuje,<br />
a x je njegov redni broj u toj godini.<br />
Dakle student koji se prvi upisuje u 2005. godini imat e matini broj<br />
1-2002 itd.<br />
Zadana je tablica STUDENT:
"$"A"*<br />
Gore navedena procedura vraa podatak o matinom broju za svaki novi<br />
podatak koji se unosi.<br />
Prije upisivanja <strong>podataka</strong><br />
za matine brojeve u<br />
tablicu STUDENT<br />
procedura vraa:<br />
<br />
Primjer: Postojea procedura je<br />
iskorištena za formiranje nove<br />
procedure kojom se obavlja unos<br />
novog studenta (novi red u tablici<br />
STUDENT.
"$"A"*<br />
Za izvršenje procedure mogu se koristiti slijedee instrukcije:<br />
<br />
<br />
Primjer: Zadane su tablice prema relacijskoj shemi:<br />
"$"A"*<br />
Treba napraviti proceduru PROC_UPISNI koja prima slijedee ulazne<br />
parametre: matini broj studenta (MATBR), naziv obrazovnog programa<br />
(OBR_PROG_IME), semestar i školsku godinu,<br />
te temeljem tih <strong>podataka</strong> vrši unos u tablicu UPISNI_LIST.
"$"A"*<br />
<br />
<br />
"$"A"*<br />
Za izvršenje procedure mogu se koristiti instrukcije:
$# " (".%<br />
RUKOVANJE GREŠKAMA<br />
Tijekom izvršavanja niza SQL instrukcija ili SQL procedure<br />
mogue je da u bilo kojoj SQL instrukciji nastupi greška<br />
tijekom njezina izvršavanja.<br />
Za detekciju greške u izvršavanju pojedinog SQL izraza<br />
koristi se sistemska (globalna) varijabla @@ERROR.<br />
Vrijednost ove varijable postavlja sam sustav u zavisnosti<br />
od toga da li SQL instrukcija obavljena ispravno ili ne.<br />
Ako je SQL instrukcija ispravno obavljena, nakon izvršenja<br />
te instrukcije vrijednost @@ERROR je 0.<br />
Ako nastupi pogreška, varijabla @@ERROR sadržava<br />
brojani podatak (integer), koji predstavlja kod pogreške.<br />
Svaki tip pogreške ima svoj jedinstveni kod, temeljem kojeg<br />
je mogue prepoznati o kojoj se vrsti pogreške radi.<br />
<br />
$# " (".%<br />
Pri obradi niza SQL instrukcija ";!*!!*<br />
!".!*"A!<br />
Nakon svake instrukcije u kojoj može nastati greška koja<br />
utjee na rezultate obrade treba obraditi i potencijalnu<br />
grešku.<br />
Ukoliko je vrijednost globalne varijable @@ERROR 0,<br />
potrebno je definirati instrukcije, koje e se izvršiti i sprijeiti<br />
- mogunost pogrešnih akcija u bazi <strong>podataka</strong><br />
- mogunost ‘pucanja’ procedure ili aplikacije koja ju koristi.<br />
Primjeri ispitivanja pogreški dani su u proceduri za unos<br />
novog studenta i u proceduri za unos novog upisnog lista.<br />
Uz sistemsko rukovanje greškama, na formiranje pogreške<br />
može utjecati i sam korisnik.<br />
Pogledajmo ovo na primjeru procedure PROC_STUDENT.
$# " (".%<br />
<br />
$# " (".%
$# " (".%<br />
<br />
$# " (".%
$# " (".%<br />
Prilikom izvršenja procedure PROC_STUDENT, potrebno je ispitati<br />
povratno stanje procedure. Negativni cijeli broj kao povratno stanje<br />
procedure znai da je u proceduri nastupila greška.<br />
Meutim pitanje je gdje je nastupila greška.<br />
Neke pogreške generiraju poruku o tipu i uzroku pogreške, tako da<br />
je mogue locirati pogrešku.<br />
U drugim sluajevima kada nije mogue locirati gdje je nastala<br />
greška, SQL nudi mogunost korisniki oblikovanih poruka o<br />
greškama, tj. korisniku je dana mogunost da uz sistemski<br />
definirane pogreške definira vlastite greške.<br />
<br />
$# " (".%<br />
Svaka pogreška u sustavu ima nekoliko obilježja:<br />
a) jedinstveni kod pogreške<br />
b) tekst pogreške<br />
c) nivo pogreške<br />
d) stanje pogreške.<br />
a) jedinstveni kod pogreške – cijeli broj koji jedinstveno<br />
opisuje pogrešku.<br />
b) tekst pogreške – tekst koji opisuje pogrešku i prikazuje<br />
se prilikom nastupanja pogreške.<br />
Definiran je u obliku formata za ispis koji se koristi<br />
u višim programskim jezicima.
$# " (".%<br />
c) nivo pogreške (severity level) – cijeli broj koji definira nivo<br />
(klasu) pogreške. Uobiajeno se odreuje na temelju<br />
klasa koje su sistemski definirane.<br />
Svaki SQL sustav ime definirani odreeni broj nivoa<br />
(klasa) za odreene tipove pogreški.<br />
Npr. SQL server ima definirane slijedee nivoe<br />
pogreški:<br />
1- sistemske informacije (obuhvaa poruke koje<br />
nastupaju uslijed sistemskih poruka)<br />
7 – statusne informacije – poruke o pojedinim stanjima<br />
poslužitelja<br />
13 - Transakcijske pogreške<br />
14 – poruke vezane za autorizaciju pristupa<br />
15 – SQL sintaksne poruke<br />
16 – Korisnike poruke<br />
17 – poruke nedostupnosti resursa<br />
itd.<br />
<br />
$# " (".%<br />
d) stanje pogreške – kojim se identificira izvor pogreške,<br />
ukoliko odreeni tip pogreške može nastupiti iz<br />
više izvora<br />
Primjer definiranja pogreške:<br />
Kod Tekst Nivo<br />
40000 Operacija nije izvršena! Nismo dobili<br />
ID za novi red u tablici<br />
Nakon što je korisnika pogreška definirana, mogue je generiranje<br />
pogreške primjenom instrukcije RAISERROR, za koju vrijedi sintaksa:<br />
RAISERROR(kod | poruka, nivo, stanje, argumenti),<br />
gdje kod i nivo moraju odgovarati onima koji su navedeni u definiciji<br />
pogreške.<br />
Argumenti predstavljaju parametre koji postaju sastavni dio teksta<br />
poruke (greške), na mjestima u tekstu gdje su argumenti definirani.<br />
16
$# " (".%<br />
Dakle uz definiranu korisniku grešku kao u zadanom<br />
primjeru, u sluaju procedure PROC_STUDENT mogua je<br />
primjena u obliku:<br />
SELECT @lStudent_id=@@IDENTITY<br />
IF @lStudent_id IS NULL<br />
BEGIN<br />
ROLLBACK TRAN<br />
RAISERROR(40000,16,1, 'STUDENT')<br />
RETURN -6<br />
END<br />
U sluaju neispravnog generiranja nove vrijednosti za<br />
STUDENT_ID, pojavit e se poruka:<br />
'Operacija nije izvršena! Nismo dobili ID za novi red u<br />
tablici STUDENT '.<br />
<br />
<br />
-"!("!<br />
OKIDAI (TRIGGERS)<br />
Okidai (trigeri) predstavljaju posebno klasu SQL procedura<br />
koja se izvršava automatski kod izvršavanja akcijskih upita<br />
(UPDATE, INSERT, DELETE) na pojedinim tablicama u bazi.<br />
Trigeri se uglavnom koriste kao oblik proširenja provjere<br />
integriteta i suvislosti <strong>podataka</strong> prema logici procesa kojeg<br />
opisuje baza.
-"!("!<br />
Okidai su uvijek vezani uz tablice, pri emu jedna tablica<br />
može imati više okidaa.<br />
Mogue je definirati posebne okidae za svaki tip promjene<br />
koja se vrši u tablici (unos, promjena ili brisanje <strong>podataka</strong>), ili<br />
zajednike okidae za razliite promjene.<br />
Okidai sadržavaju SQL instrukcije u obliku slinom kao i<br />
SQL procedure.<br />
Okidai se izvršavaju odmah nakon što završi instrukcija koja<br />
ih ‘okida’.<br />
Okidae nije mogue vezati uz poglede ili sistemske tablice u<br />
bazi <strong>podataka</strong>.<br />
<br />
<br />
-"!("!
-"!("!<br />
Primjenom okidaa zabranjuju se ili poništavaju (rollback)<br />
promjene kojima se krši integritet <strong>podataka</strong>.<br />
Okidai omoguavaju uvoenje strožih i složenijih<br />
ogranienja od onih koja se definiraju preko CHECK<br />
ogranienja.<br />
Za razliku od CHECK ogranienja koje djeluje samo na<br />
nivou definirane tablice, okida može pristupiti drugim<br />
tablicama, te provjeravati složenije uvjete integriteta.<br />
Pomou okidaa mogue je ustanoviti razliku izmeu stanja<br />
tablice prije promjena i nakon promjena i poduzeti<br />
odgovarajue akcije u vezi tih promjena.<br />
<br />
<br />
‘Princip rada’<br />
-"!("!<br />
Nakon nastupanja promjena u odreenoj tablici (zbog<br />
unosa, brisanja ili promjene <strong>podataka</strong>), interni mehanizam<br />
baze <strong>podataka</strong> stvara dvije privremene tablice naziva<br />
deleted i inserted.<br />
Tablica deleted pohranjuje kopije svih redova na koje djeluju<br />
instrukcije DELETE ili UPDATE.<br />
Primjenom instrukcije DELETE odreeni redovi se brišu iz<br />
izvorne tablice i prebacuju u privremenu tablicu naziva<br />
deleted.
‘Princip rada’<br />
-"!("!<br />
Tablica inserted pohranjuje kopije svih novounešenih<br />
redova u promatranu tablicu.<br />
To znai da se djelovanjem instrukcije INSERT novi redovi<br />
dodaju istovremeno u tablicu u bazi i sistemsku privremenu<br />
tablicu inserted.<br />
Nakon unosa <strong>podataka</strong> instrukcijom INSERT redovi u tablici<br />
inserted predstavljaju kopiju novounesenih redova u<br />
osnovnoj tablici.<br />
Operacije ažuriranja (UPDATE) tretiraju se kao slijed<br />
brisanja i unosa; podaci prije promjene prenose se u<br />
privremenu tablicu deleted, a novopromijenjeni podaci u<br />
inserted tablicu.<br />
<br />
<br />
-"!("!<br />
Prilikom formiranja okidaa potrebno je definirati<br />
- ime(naziv) okidaa<br />
- tablicu uz koju je okida vezan<br />
- akciju koja aktivira okida<br />
- niz SQL instrukcija koje se izvršavaju aktiviranjem okidaa.<br />
CREATE TRIGGER naziv_okidaa<br />
ON ime_tablice<br />
FOR [DELETE] [,] [INSERT] [,] [UPDATE]<br />
AS<br />
sql_izrazi [1...n]<br />
|<br />
FOR [INSERT] [,] [UPDATE]<br />
AS<br />
IF UPDATE (naziv_kolone) [AND | OR UPDATE (naziv_kolone)]<br />
sql_izrazi [ ...n]
-"!("!<br />
naziv_okidaa – ime okidaa.<br />
Mora zadovoljavati pravilo imenovanja objekata u bazi i biti<br />
jedinstveno u bazi.<br />
ime_tablice – predstavlja naziv tablice za koju se vezuje<br />
okida.<br />
Ne može se navesti naziv pogleda, budui okidae nije<br />
mogue vezati uz poglede.<br />
[DELETE] [,] [INSERT] [,] [UPDATE] | [INSERT] [,]<br />
[UPDATE] - predstavljaju kljune rijei kojima se odreuje tip<br />
akcije, koji svojim izvršenjem aktivira okida.<br />
Potrebno je navesti bar jednu opciju.<br />
Ukoliko se isti okida definira za više razliitih akcija navode<br />
se u obliku liste odvojene zarezom, pri emu nije bitan<br />
redoslijed navoenja.<br />
<br />
<br />
-"!("!<br />
IF UPDATE (naziv_kolone) - izraz kojim se provjerava akcija<br />
unosa ili ažuriranja navedene kolone u tablici.<br />
Ova opcija ne primjenjuje se u okidaima koji su vezani za<br />
operaciju brisanja (DELETE).<br />
U izrazu je mogue navesti vei broj kolona.<br />
Prilikom aktiviranja okidaa (trigera), SQL izrazi navedeni u<br />
sklopu okidaa izvršavaju se na nain kao i u SQL<br />
procedurama (stored procedures).<br />
Prilikom navoenja SQL instrukcija u sklopu okidaa treba<br />
eliminirati mogunost da okida vraa bilo kakve podatke, jer<br />
bi takvi podaci poremetili akciju koja se vrši na tablici. Stoga<br />
se u deklariranju SQL instrukcija u okidau nikad ne koriste<br />
SELECT izrazi koji vraaju rezultat u obliku prikaza.
Primjer:<br />
Zadana je tablica STUDENT izrazom:<br />
-"!("!<br />
CREATE TABLE STUDENT<br />
(student_id int IDENTITY CONSTRAINT PK_STUDENT PRIMARY KEY,<br />
ime varchar(20) NOT NULL,<br />
prezime varchar(30) NOT NULL,<br />
jmbg<br />
char(13),<br />
ime_oca varchar(20),<br />
dat_roenja smalldatetime NOT NULL,<br />
mjesto_rod int NOT NULL,<br />
CONSTRAINT FK_MJESTO_ROD FOREIGN KEY<br />
REFERENCES mjesto(mjesto_id),<br />
mjesto_stan int NOT NULL,<br />
CONSTRAINT FK_MJESTO_STAN FOREIGN KEY<br />
REFERENCES mjesto(mjesto_id),<br />
adresa<br />
varchar(25),<br />
dat_upisa smalldatetime NOT NULL DEFAULT getdate(),<br />
matbr varchar(10) )<br />
<br />
<br />
Kolona jmbg definirana je bez eksplicitnog navoenja<br />
NULL ili NOT NULL, što podrazumijeva svojstvo NULL.<br />
Ovakvom strukturom tablice mogue je evidentirati<br />
studente bez unosa podatka jmbg.<br />
Uz navedenu strukturu u tablici postoji 1000 redova<br />
(studenata).<br />
-"!("!<br />
Recimo da se zbog promjene pravila u evidentiranju<br />
studenata uvodi pravilo da je pri daljnjem upisu studenata<br />
podatak jmbg obavezan. Dakle za svakog slijedeeg<br />
studenta obavezno je unijeti njegov JMBG.<br />
Problem ne možemo riješiti jednostavnom promjenom<br />
svojstva kolone JMBG u NOT NULL, budui u tablici ve<br />
imamo veliki broj redova, bez tog podatka.<br />
Stoga je nužna primjena okidaa, koji e djelovati uz<br />
operacije unosa i promjene <strong>podataka</strong> u tablici STUDENT.
Uz ovako definirani okida, svaki novi unos ili promjena <strong>podataka</strong> 'okida'okida<br />
i pokree izvršavanje instrukcija u okidau.<br />
Svaki novouneseni redak usporedno sa unosom u tablicu STUDENT unosi se i<br />
u sistemsku privremenu tablicu inserted. Za novounešeni red iz tablice<br />
inserted uzimamo vrijednost atributa JMBG te ga pohranjujemo u lokalnu<br />
varijablu @sJMBG.<br />
Ukoliko ne postoji podatak za JMBG<br />
(NULL) takav unos (ili promjena) se<br />
poništava instrukcijom<br />
ROLLBACK TRAN, a korisniku se<br />
prikazuje poruka generirana izrazom<br />
RAISERROR.<br />
1/8611,1U"D!D*<br />
<br />
<br />
-"!("!<br />
Pri tome treba istaknuti nain djelovanja instrukcije<br />
ROLLBACK TRANSACTION, kada se ona primijenjuje<br />
unutar okidaa.<br />
- sve promjene <strong>podataka</strong> koje je izvršila tekua transakcija<br />
se poništavaju (rollback) ukljuujui i promjene koje<br />
eventualno stvara sam okida.<br />
- okida nastavlja sa normalnim izvršavanjem svih<br />
preostalih instrukcija nakon ROLLBACK izraza. Ako neka<br />
od instrukcija koje slijede u okidau vrši promjene na<br />
podacima te promjene se normalno izvršavaju.<br />
- slijed SQL instrukcija ili procedura koja sadrži instrukciju<br />
koja je okinula okida odmah se prekida i preostale<br />
instrukcije koje slijede se ne izvršavaju.
Okida djeluje na nain da svaku izvršnu instrukciju koja ga pokree<br />
podrazumijeva kao dio transakcije.<br />
Pri tome je mogue da instrukcija za npr. unos <strong>podataka</strong> bude navedena<br />
kao jedna od instrukcija u sklopu transakcije:<br />
Na poetku transakcije je niz instrukcija.<br />
Nakon toga se izvrši instrukcija INSERT, koja 'okida'okida vezan za<br />
operaciju unosa, te poinje izvršavanje SQL instrukcija sadržanih u okidau.<br />
Ukoliko se u sklopu okidaa izvrši ROLLBACK TRAN, tekua transakcija<br />
završava sa ROLLBACK-om i sve što je do tada u transakciji obavljeno<br />
poništava se.<br />
Ukoliko u okidau nije aktiviran ROLLBACK, kontrola toka se vraa u<br />
izvornu transakciju i nastavlja se izvršavanje od izraza koji slijedi nakon<br />
instrukcije INSERT.<br />
Transakcija sada završava sa ROLLBACK ili COMMIT prema daljnjem<br />
slijedu instrukcija u nizu.<br />
<br />
Primjer:<br />
Zadana je slijedea<br />
struktura baze <strong>podataka</strong><br />
o studentima:<br />
-";"!!"!";<br />
!: ;!A<br />
!%*<br />
".!""!<br />
!("!<br />
*!I *!A!&<br />
$"!!% *!"% !*(!*D! %(I !!*%*"<br />
! *!!;"!"("%<br />
$"!!% *!"% !*(!*";*!("!(!:!*!<br />
**%*"!%D" ! %(I !!"I!*%*"<br />
*!"(!<br />
,*!("!*!**.*(!:!! %(I<br />
!!.*(!!2 *!*'<br />
+! %(I !!!*!!*"3!*%*"DI<br />
* !.!*%*"!(!* 2!!;"!*!
-"!("!*"&<br />
<br />
+*"!("O<br />
$"!!% *!"% !*(!*D!<br />
%(I !!*%*"! *!<br />
!;"!"("%<br />
$"!!% *!"% !*(!*";*!("!<br />
(!:!*!**%*"!%D" ! %(I<br />
!!"I!*%*" *!"(!<br />
+! %(I !!.*(!!2<br />
*!*'
-"!(" &<br />
+! %(I !!!*!!*<br />
"3!*%*"DI* !.!<br />
*%*"!(!* 2!!;"!*!