Predavanje 2-B2

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 15

1

Pohranjene procedure
Pohranjena je procedura (engl. Stored Procedure) upit koji se uva u bazi
na serveru i nije ugraena u kod koji se instalira na klijentskom raunalu.
Zbog ega je dobro uvati upite u bazi na serveru?
smanjeni promet mreom
mala koliina koda
otklanjanje uskih grla
puno bre izvoenje
nije potrebno prevoenje
u memoriji postoji plan izvravanja
jednostavnije upravljanje bazom podataka
centralizacija upita
potrebno je mijenjati upit samo na serveru, a ne na svim klijentima
Upotreba pohranjenih procedura
Dva naina programiranja:
Programi pohranjeni lokalno i aplikacije koje alju naredbe
SQL serveru i same obrauju rezultate;
Programi pohranjeni na SQL serveru kao pohranjene
procedure i aplikacije koje izvravaju procedure i same
obrauju esto puno manje rezultata.
2
Slinosti pohranjenih procedura s
procedurama u drugim programskim jezicima
Mogu primiti ulazne parametre i vratiti vie vrijednosti, u
obliku izlaznih parametara, pozivajuoj proceduri ili
programu;
Sadre naredbe koje vre operacije u bazi podataka i mogu
pozivati druge procedure;
Vraaju vrijednost koja govori o uspjehu ili neuspjehu
obavljane operacije (i razlog neuspjeha).
Prednosti koritenja pohranjenih procedura u
odnosu na programe pohranjene lokalno na klijentu:
Doputaju modularno programiranje;
Bre se izvravaju;
Mogu znaajno smanjiti promet na mrei;
Mogu se koristiti kao zatitni mehanizam.
3
Kreiranje procedura
Pohranjena se procedura sastoji od dva primarna dijela:
specifikacije imena procedure i njenih parametara, te tijela
procedure.
Procedura se kreira SQL naredbom:
CREATE PROC[EDURE] ime_procedure [ ; broj ]
[ { @varijabla tip_podatka }
[ VARYING ] [ = default ] [ OUTPUT ]
] [ ,...n ]
[ WITH
{ RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]
AS sql_statement [ ...n ]
Kreiranje procedura
; broj - opcionalni integer koji omoguava da se zajedno mogu
obrisati procedure istog imena npr. moemo imati procedure:
proc_ispisi_ispite;1, proc_ispisi_ispite;2, itd.
naredba DROP PROCEDURE proc_ispisi_ispite brie sve procedure
u grupi
- sql_statement se moe sastojati od bilo kojeg brojaTransact-SQL
naredbi, postoje neka ogranienja (nije mogue recimo CREATE
PROCEDURE)
VARYING odnosi se na izlazne parametre i koji mogu varirati,
podrava jedino kursore
RECOMPILE za proceduru se ne sprema plan izvoenja u memoriju ve
se ona prevodi tijekom vremena izvoenja (run-time)
ENCRYPTION provodi se enkripcija koda procedure na serveru
4
Control-of-Flow Language
(jezik za kontrolu tijeka)
Izvravanje petlje dok je
uvjet TRUE
WHILE
Postavljanje kanjenja WAITFOR
Bezuvjetan izlaz RETURN
Uvjetno i mogue
izvravanje ako je uvjet
FALSE.
IF...ELSE
Nastavak izvoenja nakon
oznake label
GOTO label
Nova iteracija while petlje CONTINUE
Izlaz iz unutarnje while
petlje
BREAK
Definira blok naredbi BEGIN...END
Opis Kljune rijei
Control-of-Flow Language
(jezik za kontrolu tijeka)
Drugi izrazi koji se mogu koristiti u jeziku za kontrolu tijeka
su:
CASE
/*...*/ (Comment)
-- (Comment)
DECLARE @local_variable
EXECUTE
PRINT
RAISERROR
Od Transact-SQL naredbi esto se pri kreiranju procedura
koristi i naredba SET.
5
BEGIN...END
BEGIN i END naredbe koriste se za grupiranje vie
Transact-SQL naredbi u jedan logiki blok.
Npr., kada IF naredba kontrolira izvravanje jedne Transact-SQL
naredbe, BEGIN i END nisu potrebni:
IF (@iznos <> 0)
SET @placanje = 1
Potrebno je koristiti BEGIN i END ako IF kontrolira izvravanje vie
naredbi:
IF (@iznos <> 0)
BEGIN
SET @placanje = 1
PRINT Ima sredstava na ra unu! '
END
BEGIN...END
BEGIN i END naredbe koriste se u paru: jedna ne moe biti bez druge.
BEGIN se pojavljuje u jednoj liniji koju slijedi blok Transact-SQL
naredbi. Naredba END se pojavljuje u jednom redu i oznaava kraj
bloka. BEGIN i END koristimo kada:
BEGIN i END koristimo kada:
WHILE petlja sadri vie naredbi;
Element CASE naredbe sadri blok naredbi;
IF ili ELSE mora sadravati vie naredbi.
Dozvoljeno je ugnjeivanje BEGINEND blokova.
6
IF...ELSE
Uvodi uvjetno izvravanje naredbi. Ako je uvjet istinit, izvode
se naredbe nakon kljune rijei IF.
Sintaksa:
IF logiki_izraz
{ sql_naredba | blok_naredbi }
[ ELSE
{ sql_naredba | blok_naredbi } ]
Opcionalno se moe koristiti i ELSE koji definira koje se
naredbe izvravaju u sluaju neistinitosti uvjeta.
WHILE
Sintaksa:
WHILE logiki_izraz
{ sql_naredba | blok_naredbi }
[ BREAK ]
{ sql_naredba | blok_naredbi }
[ CONTINUE ]
Petlja ije se izvravanje nastavlja dok je uvjet istinit.
Ponaanje unutar petlje mogue je kontrolirati s BREAK i CONTINUE.
7
CASE
Sintaksa:
CASE ulazni_izraz
WHEN when_izraz THEN izraz
[ ...n ]
[
ELSE else_izraz
]
END
Omoguava definiranje ponaanja za razliite vrijednosti ulaznog
parametra. (npr. WEEKDAY i nazivi dana u tjednu)
CASE - primjer
SELECT au_ime, au_prezime,
CASE drzava
WHEN 'CA' THEN 'California'
WHEN 'KS' THEN 'Kansas'
WHEN 'TN' THEN 'Tennessee'
WHEN 'OR' THEN 'Oregon'
WHEN 'MI' THEN 'Michigan'
WHEN 'IN' THEN 'Indiana
ELSE Nije u SAD-u'
END AS ime_drzave
FROM autori ORDER BY au_prezime
8
WAITFOR
Sintaksa:
WAITFOR { DELAY 'time' | TIME 'time }
Odreuje vrijeme, vremenski interval ili dogaaj koji potie
izvravanje bloka naredbi, procedure ili transakcije.
Primjer:
BEGIN
WAITFOR TIME 23:59'
EXECUTE zavrsi_sve_transakcije
END
Kursori
Operacije se u relacijskoj bazi podataka odvijaju nad n-torkama.
Grupa n-torki koja je rezultat SELECT naredbe sastoji se od svih n-
torki koje zadovoljavaju uvjet u WHERE dijelu naredbe.
Aplikacije, posebice one interaktivne, ne mogu uvijek efikasno raditi
s cijelom grupom n-torki kao jednom jedinicom.
Takvim je aplikacijama potreban mehanizam kojim bi mogli
odjednom raditi s jednom n-torkom ili manjim brojem n-torki.
Kursori su dodatak koji to omoguuje.
9
Kursori omoguuju
Pozicioniranje na eljenu n-torku;
Dohvaanje jedne ili vie n-torki iz trenutne pozicije
djelatnog skupa;
Promjenu podataka nad n-torkama koje su na trenutnoj
poziciji;
Izvedbu procedura i okidaa koji rade nad pojedinim n-torkama.
Rad s kursorom
Generalno se moe rei kako se rad s kursorom sastoji od:
Povezivanja kursora s djelatnom n-torkom i definiranja njegovih
karakteristika (kao npr. mogu li se n-torke u kursoru aurirati);
Izvravanja naredbe kako bi se popunio kursor;
Dohvaanja n-torki iz kursora koje se ele vidjeti. Taj postupak nazivamo
dohvat (fetch). Izvravanje niza dohvata bilo unaprijed ili unazad
naziva se scrolling.
Opcionalno, moe se izvriti operacija auriranja ili brisanja n-torke na
trenutnoj poziciji kursora
10
Deklariranje kursora i povezivanje
s djelatnim skupom
Sintaksa (pojednostavljena):
DECLARE ime_kursora [ INSENSITIVE ] [ SCROLL ] CURSOR
FOR select_naredba
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]
INSENSITIVE auriranja nad temeljnim n-torkama (u originalnim tablicama)
koje grade kursor nisu vidljive u kursoru, takoer, nije
mogue auriranje pomou kursora
SCROLL mogue su sve opcije dohvata n-torki (FIRST, LAST, PRIOR, NEXT,
RELATIVE, ABSOLUTE), ako opcija nije navedena mogue
je samo NEXT
Ako je navedeno OF column_name [,...n], mogue je aurirati samo
navedene atribute. Ako je UPDATE naveden bez liste atributa mogue je
aurirati sve atribute.
Otvaranje kursora i dohvat n-torke
Kursor se nakon deklariranja mora otvoriti.
Naredba OPEN ime_kursora otvara kursor i popunjava ga podacima
definiranim u select_naredbi DECLARE bloka.
Ako je kursor deklariran s INSENSITIVE opcijom naredba OPEN rezultira
stvaranjem privremene tablice.
Uz pomo FETCH naredbe dohvaamo podatke iz kursora.
Sintaksa:
FETCH
[ [ NEXT | PRIOR | FIRST | LAST| ABSOLUTE { n | @nvar }
| RELATIVE { n | @nvar }]
FROM ] {cursor_name }
[ INTO @variable_name [ ,...n ]]
Napomena: Ako kod deklaracije nije navedena opcija SCROLL mogue je
samo NEXT.
11
Kursor za auriranje
Kako aurirati ili obrisati tono odreenu n-torku na kojoj se nalazi kursor?
Kada se uz pomo kursora eli vriti auriranje ili brisanje
potrebno je definirati WHERE CURRENT OF ime_kursora u WHERE dijelu
UPDATE ILI DELETE naredbe.
Primjer:
DELETE FROM ispit
WHERE CURRENT OF kursor_za_ispite
Zatvaranje i dealociranje kursora
Naredbom CLOSE ime_kursora zatvaramo kursor i otputamo djelatni
skup.
Svaki otvoreni kursor je nuno zatvoriti.
Nije dozvoljeno zatvoriti kursor koji nije trenutno otvoren.
Naredbom DEALLOCATE ime_kursora briemo vezu izmeu kursora i
njegova imena.
Takoer, briu se i scroll locks.
12
Izvravanje i brisanje procedura
Procedura se izvrava naredbom:
EXEC[UTE] ime_procedure
[ [ @parameter = ] { value | @variable [ OUTPUT ]][ ,...n ] [WITH RECOMPILE]
Procedura se brie naredbom:
DROP PROC[EDURE] ime_procedure
Primjer
Za bazu zadanu slikom kreirati proceduru koja e za zadano
prezime ispisati imena ljudi.
CREATE Proc Nadji_ime
@tempprezime varchar(15)
AS
SELECT ime FROM osoba
WHERE prezime=@tempprezime
Procedura se izvrava npr. ovako:
EXEC Nadji_ime 'Mari'
13
Primjer
Za bazu iz prolog zadatka napisati proceduru koja e osobi zadanoj
imenom i prezimenom unijeti broj telefona (nema osoba jednakog
imena i prezimena).
CREATE PROC Upisi_Tele @time varchar(10), @tprezime varchar(15), @tbroj
varchar(10), @tpred varchar(5)
AS
DECLARE @o_ID int, @t_ID int, @flg int
SELECT @o_ID=osoba_ID FROM osoba WHERE ime=@time AND prezime=@tprezime
IF (@o_ID IS NULL)
BEGIN
INSERT INTO osoba(ime,prezime) VALUES (@time,@tprezime)
SELECT @o_ID=osoba_ID FROM osoba
WHERE ime=@time
AND prezime=@tprezime
END
Primjer
SELECT @flg=COUNT(*) FROM telefoni WHERE broj=@tbroj AND predbroj=@tpred
IF (@flg<>0)
BEGIN
SELECT @t_ID= tel_ID FROM telefoni WHERE broj=@tbroj AND predbroj=@tpred
INSERT INTO osobaima VALUES (@o_ID,@t_ID,'fiksna mrea')
RETURN
END
INSERT INTO telefoni(broj,predbroj) VALUES (@tbroj,@tpred)
SELECT @t_ID= tel_ID FROM telefoni WHERE broj=@tbroj AND predbroj=@tpred
INSERT INTO osobaima VALUES (@o_ID,@t_ID,'fiksna mrea')
Procedura se izvrava npr.
EXEC Upisi_Tele 'Ana',Ani','01','7024356'
14
Primjer
Za bazu iz prethodnog primjera napisati proceduru koja e za
svaku osobu koja ima broj na mrei 099 obrisati takav telefonski broj.
Neka procedura vrati broj obrisanih telefona
CREATE PROC izbrisi_099 @broj int OUTPUT
AS
DECLARE @po_ID int, @ptel_ID int, @popis varchar(20)
DECLARE cur CURSOR
FOR
SELECT * FROM osobaima
SET @broj=0
OPEN cur
FETCH NEXT FROM cur INTO @po_ID, @ptel_ID, @popis
Primjer
WHILE (@@FETCH_STATUS=0)
BEGIN
IF ((SELECT COUNT(*) FROM telefoni WHERE predbroj='099
AND tel_ID=@ptel_ID)<>0)
BEGIN
DELETE FROM osobaima WHERE CURRENT OF cur
DELETE FROM telefoni WHERE tel_ID=@ptel_ID
SET @broj=@broj+1
END
FETCH NEXT FROM cur INTO @po_ID, @ptel_ID, @popis
END
CLOSE cur
DEALLOCATE cur
15
Primjer
Procedura se poziva:
DECLARE @broj int
EXEC izbrisi_099 @broj OUTPUT
SELECT @broj

You might also like