Moze li ovako:
Kad insertujes stavke, ti u stvari prepisujes ime proizvoda iz tabele proizvodi - u tome je denormalizacija. OK. Razumeo sam da imas triger koji to radi, i to je OK.
Sada zelis dve stvari:
1. ako neko pokusa da promeni NazivProizvoda u tabeli Stavke da se to spreci
2. AKo se u tabeli Proizvodi promeni naziv za neki proizvod, da se ta promena propagira u atbelu Stavke.
Moze trigerima a i ne mora. Ako ti je zadatak da pokazes kako znas da napises ovakav triger onda evo:
-- 1. ako neko pokusa da promeni NazivProizvoda u tabeli Stavke da se to spreci
CREATE TRIGGER t_UPD_StavkaPor
ON StavkaPor
FOR UPDATE
AS
BEGIN
IF UPDATE(NazivProizvod) BEGIN rollback END
END
Uoci da je triger FOR UPDATE, nije FOR INSERT, UPDATE. Broj redova koji se pokusavaju promeniti nema veze, jedan ili vise, svejedno. Triger na INSERT prepisuje naziv iz tabele Proizvodi, Triger an UPDATE provereva da li je slucajno pokusan UPDATE na koloni NAzivproizvoda tabela StavkaPor, i ako jeste, odbacuje transakciju.
Onaj tvoj prvi triger, koji prepisuje ime MORA da bude samo FOR INSERT.
Zahtev 2. je u suprotnosti sa zahtevom 1. Mozes naravno na tabeli Proizvod da napises triger koji ce propagira izmenu, ali ce je triger t_UPD_StavkaPor odbaciti. Zahtev 1 kaze 'promene naziva u Stavkama se zabranjuje' a zahtev 2 kaze 'e bas hocu da proemnim nazive u Stavke kad se promeni naziv u Proizvodi'. Trigeri ce jedan drugog da ponistavaju, Znaci, trigerima ovo nece moci.
Resenje bez trigera je da koristis FK, na malo prosiren nacin, sa CASCADE UPDATE opcjom.
Tabela Proizvod (IDProizvod, Naziv, PRIMARY KEY (IDProizvod), UNIQUE (IDProizvod, Naziv) )
Tabela Porudzbina (IDPor, Datum)
Tabela StavkaPor (IDPor, Rb, IDProizvod, Kol, NazivProizvod
, FOREIGN KEY( IDProizvod, NazivProizvod) REFERENCES Proizvod (IDProizvod, Naziv) ON UPDATE CASCADE
, FOREIGN KEY (IDPor) REFERNCES Porudzbina (IDPor))
)
Trik je dodati constraint UNIQUE (IDProizvod, Naziv) na tabelu Proizvod. Naoko nepotrebno, jer je IDProizvod vec jedinstven, to je PK. Nista ne smeta da PK prositimo i dobijemo 'super key'. Zasto? Da bi mogli da na tabeli StavkaPor napravimo FOREIGN KEY. FK mora da gleda u nesto sto je UNIQUE u referenciranoj tabeli, a to je nas 'super key'. FK ce spreciti izmenu naziva u StavkaPor, svaki naziv mora da se slaze sa svojim prizvodID u svakom momentu. Time smo zadovoljili zahtev 1.
On UPDATE CASCADE na definiciji FK zavrsava posao za zahtev 2. Ako u tabeli Proizvod promenis naziv nekom proizvodu, ta ce se promena propagirati u tabelu StavkaPor, automatski. Ne treba ti triger. I to je potpuno u skaldu za Zidarevom teoremom, koja glasi "The best code is no code at all". Nazalost, ta teorem se ne uci u skolama, steta.
Primedba:
Zahtev 2 (propagacija promena imena iz Proizvod u Stavke), ima za posledicu da ako je nesto prodato kao ( IDproizvod = 1, NazivProizvod = 'kosulja muska') pre godinu dana, a mi danas promenimo u tabeli Proizvod da kaze ( IDproizvod = 1, NazivProizvod = 'kosulja za muskarce') to ce se promniti i u tabeli StavkaPor. Ako smo pre godinu dana odstampali fakturu, na njoj je pisalo 'kosulja muska'. Ako danas odstampamo tu istu fakturu, pisace 'kosulja za muskarce'. Ne znam koliko je to pametno, ali ako je takav zadatak, onda neka. IZ ovoga vidis da denormalizacija nije samo formalna stvar, vec stvara gomilu drugih problema, koje na prvi pogled i ne vidimo, jer smo fokusirani na uspostavljanje integriteta podataka na silu, trigerima i super kljucevima.
Zato je bolje zahtev 2 jednostavno izbaciti iz igre. Ako vec prenosis naziv u Stavke, OK, imas triger, lepo. Sada imas nacin i da sprecis promene - onaj drugi triger, ili FK, ali bez CASCADE UPDATE.
Nadam se da je pomoglo?