[ idProof @ 07.07.2011. 14:11 ] @
Imam tabelu NastavniPlanovi. U okviru tabele se nalaze dva obelezja "Obavezan" i "izborni" i odnose se na predmete. Posto jedna predmet u isto vreme ne moze da bude "obavezan" i "izborni", ja sam pokusao da kreiram INSTEAD OF okidac. Pre unosa u tabelu Nastavni Planovi, procedura treba da proveri da li je unesena vrednost za "obavezan" i "izborni" ista. Ako je ista, okidac ce da OPALI i da posalje poruku o gresci. Dakle, vrednosti za obelezja "obavezan" i "izborni" bi bile 1 ili 0. Vrednost 1 kazuje da je predmet obavezan ili izborni, a 0 da nije.

NastavniPlanovi (necu sve kolone navesti, samo one obavezne)
(
rbrNastavniPlanovi char(5) primary key not null,
rbrSavke char(15) Primary key not null,
nacinPolaganja char(45) not null,
ESPB INT,
obavezan bit,
izborni bit
)

Tabela ima kompozitni primarni kljuc, sastavljen od obelezja rbrNastavniPlanovi i rbrSavke

, stim da rbrNastavniPlanovi referencira primarni kljuc druge tabele.

Nad ovom tabelom je kreiran pogled imenovan sa "vw_Nastavni_Planovist".

Triger:

ALTER TRIGGER insteadof_nastavniPlanovist
ON vw_Nastavni_Planovist
INSTEAD OF INSERT
AS
BEGIN
DECLARE @izb bit, @obav bit

SELECT @obav=i.Obavezan, @izb=i.Izborni
FROM NastavniPlanoviSt st
JOIN inserted i ON i.RbrNastavnogPl=st.RbrNastavnogPl

IF (@[email protected])
BEGIN
INSERT INTO nastavniPlanoviSt(RbrNastavnogPl, RbrStavke,SifPredmeta,NacinPolaganja,ESPB,Obavezan,Izborni)

SELECT i.RbrNastavnogPl,i.RbrStavke,i.SifPredmeta,i.NacinPolaganja,i.ESPB,@obav, @izb
FROM inserted i
JOIN NastavniPlanoviSt st ON st.RbrNastavnogPl=i.RbrNastavnogPl
END

ELSE
Raiserror ('Greska, uneli ste jednake verdnosti za kolone Obavezan i Izborni',10,1)

END



Pokusaj unosa vrednosti:

INSERT INTO vw_Nastavni_Planovist(
RbrNastavnogPl,
RbrStavke,
SifPredmeta,
NacinPolaganja,
ESPB,
Obavezan,
Izborni)
VALUSE
(59, 131, 'MDM050', 'UP', 2,0, 0)

Poruka: Uneli ste jednake verdnosti za kolone Obavezan i Izborni

(1 row(s) affected)


Drugi pokusaj unosa, sa promenom vrednosti za obelezje "Obavezan"

Pokusaj unosa vrednosti:

INSERT INTO vw_Nastavni_Planovist(
RbrNastavnogPl,
RbrStavke,
SifPredmeta,
NacinPolaganja,
ESPB,
Obavezan,
Izborni)
VALUSE
(59, 131, 'MDM050', 'UP', 2,1, 0)

Poruka o gresci:
Msg 2627, Level 14, State 1, Procedure insteadof_nastavniPlanovist, Line 14
Violation of PRIMARY KEY constraint 'PK_NastavniPlanoviSt'. Cannot insert duplicate key in object 'dbo.NastavniPlanoviSt'.
The statement has been terminated.




Naravno, nisam uneo dupli kljuc.




[ idProof @ 07.07.2011. 18:03 ] @
Resio sam problem .

ALTER TRIGGER insteadof_nastavniPlanovist
ON vw_Nastavni_Planovist
INSTEAD OF INSERT
AS
BEGIN
DECLARE @izb bit, @obav bit

SELECT @obav=Obavezan, @izb=Izborni
FROM INSERTED

IF (@[email protected])
BEGIN
Raiserror ('Greska, uneli ste jednake verdnosti za kolone Obavezan i Izborni',10,1)
RETURN
END
INSERT INTO nastavniPlanoviSt(RbrNastavnogPl, RbrStavke,SifPredmeta,NacinPolaganja,ESPB,Obavezan,Izborni)

SELECT RbrNastavnogPl,RbrStavke,SifPredmeta,NacinPolaganja,ESPB,@obav, @izb
FROM inserted
END

Zabrljao sam malo kod. Sada sve radi kako treba. I naravno, sada sam naveo ispravan kod.
Pozdrav svima
[ idProof @ 07.07.2011. 18:04 ] @
Resio sam problem .

ALTER TRIGGER insteadof_nastavniPlanovist
ON vw_Nastavni_Planovist
INSTEAD OF INSERT
AS
BEGIN
DECLARE @izb bit, @obav bit

SELECT @obav=Obavezan, @izb=Izborni
FROM INSERTED

IF (@[email protected])
BEGIN
Raiserror ('Greska, uneli ste jednake verdnosti za kolone Obavezan i Izborni',10,1)
RETURN
END
INSERT INTO nastavniPlanoviSt(RbrNastavnogPl, RbrStavke,SifPredmeta,NacinPolaganja,ESPB,Obavezan,Izborni)

SELECT RbrNastavnogPl,RbrStavke,SifPredmeta,NacinPolaganja,ESPB,@obav, @izb
FROM inserted
END

Zabrljao sam u kodu, jer sam spajao sto se nije moglo spojiti. I naravno, sada sam naveo ispravljenu verziju trigera.
Pozdrav svima
[ Zidar @ 07.07.2011. 21:49 ] @
Triger ti uospte ne treba. Mozes da napises CHECK constraint koji sprecava los unos. Ovako:

Code:
ALTER TABLE NastavniPlanovi
ADD CONSTRAINT CK_Obavezni_ili_Izborni
CHECK (
        1 = CASE 
                WHEN Obavezni IS NULL AND Izborni IS NOT NULL THEN 1
                WHEN Obavezni IS NOT NULL AND Izborni IS NULL THEN 1
                ELSE 0
            END
        
;        )


U prevodu - jedan od atributa (Izborni,Obavezni) u svakom momentu mora biti NULL a drugi ne sme biti NULL. Ne dozvoljava se da istovremeno ona budu NULL ili da su oba NOT NULL.

Triggere koristis samo kad absolutno moras. U praksi, obicno nema potrebe da se poslovna pravila nametnu u bazi pomocu trigera, samo sto to malo ljudi zna. Postoje situacije kada se triger ne moze izbeci, ali ovo nije takva situacija.

Ako si pisao triger za vezbu, OK, vezba nije losa stvar. Ako je za praksu, preskoci triger ako moze. Ako ima previse trigera u bazi koji namecu poslovna pravila, nesto ne valja u pocetnoj ideji.

[ Zidar @ 07.07.2011. 22:06 ] @
U stvari, i ovo sa CHECK u prethodnom postu nije najbolje. Samo sam hteo da pokazem kako se pise takav CHECK.

Svaka kolona u tebli sme da zavisi samo od PK i nicega drugog. Ove dve kolone zavise jedna od druge => tabela nije dovoljno normalizovana. Najbolje je bilo da se umesto ove dve kolone uvede jedna, NOT NULL sa dve dozvoljene vrednosti, recimo 1 ili 2 gde 1 znaci 'Izborni predmet' a 2 znaci 'obavezni predmet'. Posto je NOT NULL, nesto se mora uneti, a posto se dozvoljava samo 1 ili 2 lako je napisti CHECK koji ce to da obezbedi.

CHECK NovaKolona IN (1,2)

Stos je razumeti biznis, nije stos nauciti da se programira.

Zidareva teorema: "The best code is no code at all."