Ova procedura ima dvojaku ulogu, zapisuje slog ukoliko se radi o novom zapisu i radi izmjenu sloga ako se radi o postojećem zapisu.
Zadatak procedure za zapis i iumjenu u našoj tablici MP_VALUTA je
- prihvat svih podataka potrebnih za zapis u tablicu
- provjera postojanja primarnog ključu pomoću procedure mp_valuta_exists
- ako je novi slog radi se INSERT, za postojeći slog se radi UPDATE
- u pomoćnu varijablu zapisati upješnost izvršenja radnje
Evo kako bi ta procedura izgledala:
CREATE PROCEDURE dbo.mp_valuta_insert @valuta CHAR(3), @naziv VARCHAR(60) = '', @oznaka CHAR(3) = '', @insert TINYINT, @postoji TINYINT OUT AS SET NOCOUNT ON DECLARE @ima INT, @err INT, @pomerr INT SET @err = -1 SET @pomerr = 1 EXEC @pomerr = dbo.mp_valuta_exists @valuta = @valuta, @out_ima = @ima OUT SET @err = @err + CASE @pomerr WHEN -1 THEN 0 ELSE 1 END SET @postoji = 0 IF @ima = 0 BEGIN INSERT INTO MP_VALUTA ( VALUTA, NAZIV, OZNAKA) VALUES ( @valuta, @naziv, @oznaka) SET @err = @err + @@ERROR END ELSE IF @insert = 0 BEGIN UPDATE MP_VALUTA SET NAZIV = @naziv, OZNAKA = @oznaka WHERE VALUTA = @valuta SET @err = @err + @@ERROR END ELSE SET @postoji = 1 RETURN @err GO
Prihvaćaju se podaci u varijable
@valuta CHAR(3), @naziv VARCHAR(60) = '', @oznaka CHAR(3) = '', @insert TINYINT,
rade se deklaracije pomoćnih varijabli, poziva se procedura mp_valuta_exists koja vraća @ima = 1 ako postoji slog sa istom šifrom valute odnosno @ima = 0 ako šifre nema.
Ako šifre nema, radi se INSERT podataka, a ako šifra postoji radi se UPDATE ukoliko smo to željeli (@insert = 0). Ako smo željeli zapisati novi slog (@insert = 1), a šifra valute je već zapisana, output varijabla @postoji će biti postavljena na 1 i neće se izvršiti niti INSERT niti UPDATE.
#1 by Gusar on 23.10.2009 - 12:20
malo je komplicirano ovo rješenje.
a dali je ovako ok?
prvi query
sad neznam kako se u sql serveru puni varijabla
select count(*) from valuta where valuta = @valuta
upišemo vrijednost u varijablu
if varijabla=0 then
insert
else
update
end
#2 by admin on 23.10.2009 - 12:33
To rješenje koje navodite je za tablice koje imaju generičku šifru. Taj primjer će biti uskoro obrađen.
U ovom slučaju, slučaju tablice MP_VALUTA koja ima određene vrijednosti, u proceduru šaljemo varijablu @insert koja ima vrijednost 1 ako želimo upisati novu valutu. Shodno tome, ako se želi upisati postojeća valuta, vrijednost varijable @postoji se stavlja na 1 i zapis neće biti napravljen.
#3 by Gusar on 25.10.2009 - 22:17
komplicira se nepotrebno
evo recimo taj primjer na mysql, jednostavno bez puno kompliciranja.užasno komplicirate.ovako bi izgledalo i na postgresql-u i na firebirdu i na oraclu i na nekoj drugoj bazi.ovo radi bez obzira dali je polje varchar, integer , autoincrement…….
DELIMITER $$
CREATE
PROCEDURE `mojabaza`.`proba`(a varchar(10),b varchar(10),c varchar(20))
BEGIN
declare z int DEFAULT 0;
select count(*) into z from proba where A=b;
if z=0 then
insert into proba(A,B,C) values(a,b,c);
else
update proba set B=b,C=c where A=a;
end if;
END$$
DELIMITER ;
#4 by Gusar on 25.10.2009 - 22:20
greška, ovo je ispravno, sory
select count(*) into z from proba where A=a;
#5 by admin on 26.10.2009 - 10:56
Vaše rješenje dozvoljava da se konstantno radi zapis “novog” sloga premda takav slog već postoji. Nema povratne informacije koja je u procedurama jako bitna kao ni error handling koji je također bitan u proceurama.
#6 by Gusar on 26.10.2009 - 20:55
nije istina.
sa count se provjeri, ako vrati 0 ide insert, ako vrati 1 ide update.
isprobano i 100 % radi.
#7 by Gusar on 26.10.2009 - 20:56
za to ne treba error handlong, jer count vraća 0 i takav imamo uvjet.
#8 by Gusar on 26.10.2009 - 20:58
ili 1
#9 by Gusar on 26.10.2009 - 20:59
DELIMITER $$
CREATE
PROCEDURE `mojabaza`.`proba`(a varchar(10),b varchar(10),c varchar(20))
BEGIN
declare z int DEFAULT 0;
select count(*) into z from proba where A=a; -> vraća 0 ili 1
if z=0 then -> ako je nula ide insert
insert into proba(A,B,C) values(a,b,c);
else -> ako je 1 ide update
update proba set B=b,C=c where A=a;
end if;
END$$
DELIMITER ;
i ne treba nam error handling.
treba pametno napraviti procedure i ne bude problema.
#10 by Gusar on 26.10.2009 - 21:02
a ovako koristiti sve i svašta i pozivati jednu ili više procedura iz neke druge nije pametno.
svaka linija sql coda troši resurse.
#11 by admin on 26.10.2009 - 22:40
Ako proceduru gledaš kao LEGO kockicu, vidjet ćeš da svaka LEGO kockica ima modus kako se spaja sa ostalim kockicama. Isto tako, rijetko koja procedura živi sama za sebe, često se poziva jedna procedura iz druge. Jedini način da se to ispravno učini je da postoji error handling.
#12 by Smeđi on 09.11.2009 - 19:31
krivo!!!
zbog optimizacije baze nikad ne pozivati proceduru iz procedure i sve treba odraditi u jednoj proceduri.
ako hočeš kvalitetu i brzinu od baze koristi postgresql.
besplatan u sve svrhe.
mana -> ne podržava clustering i replikaciju u core-u.
ima alata za replikaciju , recimo dbreplicator radi dobro.
također ima firebird, isto besplatan u sve svrhe.
neke firme koriste firebird za knjigovodstvene programe.
jednostavna baza, mala, a ima sve što ti treba od procedura nadalje.
hočeš još bolje performance, stavi postgresql na 64 bitni linux ili freebsd pa da vidiš kako leti.
linux -> jedno do 40 % brži od windowsa, a freebsd brži jedno 60 % od windowsa.
jedna i druga baza imaju cdrivere za popularne jezike.
.net, javu, perl, python, itd…
#13 by admin on 10.11.2009 - 11:37
Ne bi se složio da sve treba odraditi u jednoj proceduri. Naravno da treba pokušati napraviti sve u jednoj ali ako to proces ne dozvoljava ili se neki dio ponavlja, logično je da se neki dio izdvoji u posebnu procku i onda se po potrebi poziva.
U bazi koristim 3000+ procedura. Neke su zanemarivo male, neke su prilično složene. Da sam išao logikom “sve u jednu proceduru”, sigurno broj ne bi bio tako velik ali bi održavanje bilo garantirano kompliciranije.
Hvala na informacijama o bazama ali mi se čini da sam se “zahaklo” na MS SQL Server i nema mi pomoći. Dosta dugo radim s njim i nisam siguran da ću preći na neku drugu bazu. Ali,… nikad ne reci nikad.
#14 by Smeđi on 10.11.2009 - 11:52
čitam knjige od oracle stručnjaka i jedan od primjera je provjera dali nešto postoji u drugoj tablici.
on je to odradio sve u hodu.
#15 by admin on 10.11.2009 - 11:58
To je samo primjer. Ako ikada u knjizi dođe do složenijih stvari, treba vidjeti da li će sve odraditi u hodu ili će se ipak odlučiti na grananje s dodatnom procedurom.