jump to navigation

Zapis podataka u tablicu pomoću stored procedure October 22, 2009

Posted by admin in : SQL , trackback

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

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.


Comments»

1. Gusar - 23.10.2009

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. admin - 23.10.2009

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. Gusar - 25.10.2009

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. Gusar - 25.10.2009

greška, ovo je ispravno, sory
select count(*) into z from proba where A=a;

5. admin - 26.10.2009

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. Gusar - 26.10.2009

nije istina.
sa count se provjeri, ako vrati 0 ide insert, ako vrati 1 ide update.

isprobano i 100 % radi.

7. Gusar - 26.10.2009

za to ne treba error handlong, jer count vraća 0 i takav imamo uvjet.

8. Gusar - 26.10.2009

ili 1

9. Gusar - 26.10.2009

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. Gusar - 26.10.2009

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. admin - 26.10.2009

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. Smeđi - 09.11.2009

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. admin - 10.11.2009

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. Smeđi - 10.11.2009

č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. admin - 10.11.2009

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.