Kakvo pitanje, takav i odgovor
Salim se, pitanje nije uopste glupo niti je problem koji imas jednsotavan za resavanje. Medjutim, pitanje je lose postavljeno pa je dobijen odgovor saglasno tome.
Odgovor je tehnicki tacan, tako se moze napraviti triger koji koju radi UPDATE jedne kolone kada se promeni neka druga kolona.
Medjutim, pitanje je postavljeno naopkao. Kroz pitanje je ponudjeno i idejno resenje i odgovor je pokazao kako se tehnicki realizuje ponudjena ideja, koja na zalost nije dobra. Ne zalosti se, to se resenej namece nekako 'prirodno' i mnogo iskusniji bi to isto predlozili. Nekako prirodno izgleda da je i Zemlja ravna, ili malo brdovita, a nikako okrugla. I prirodno izgleda, cak je ocigledno da se Sunce okrece oko zemlje, u stvari izlazi na istoku a zalazi na Zapadu, ne vidi se da se okrece. Ipak, mi znamo da je u stvari to drugacije. Tako i sa ovim problemom.
Stvarni problem je da postojeca tabela ima naru da prati stanja ili faze u zivitu nekog entiteta. Stanja su ..."aktivna", "realizovana", "zakljucena"... . Entitet prelazi iz stanaj u stanje u odredjenim momentima. Recimo da je entitet neka 'porudzba'. Porudzba je prvo aktivna, onda je zakljucena i na kraju je realizovana. Postojeca tabela ima boolean kolone za svaku od faza, sa vrednostima 0 ili 1, gde se vidi da se nesto desilo, ali ne i kada se to desilo. Sada se zeli 'kompletirati' resenje, da se vidi i kada se nesto desilo. Na prvi pogled, dodavanja novih kolona tipa DateTime je ocigledno resenje. Medjutim....
Problem je sto ce nove kolone da budu zavisne od postojecih kolona. Ako je u postojecoj koloni 'realizovana' vrednost 0 (nije jos realizovana) onda u koloni DatumRealizovana treba da bude NULL. Obrnuto, ako je kolone 'realizovana' jednaka 1, onda DatumRealizovana mora da bude NOT NULL. To je ta zavisnost izmedju te dve kolone. DatumRealizovanja nije zavisan samo od kolone 'Realizovana'. DatumRealizovana ne sme da bude manji od recimo DatumAktiviranja. Ovo stoga sto se ocekuje da faze u zivotu 'porudzbine' idu u nekom redosledu. Iz ovog sledi da su sve kolone koje opisuju stanja zavisne jedna od druge. I ako se ta zavisnost ne postuje, podaci na izvestajima ce izgledati nelogicno. Imaces u jednom mesecu entitete koji su zakljuceni a da nikad nisu bili realizovani..... A nesto mi govori da ima mnogo vise kolona sa stanjima nego sto je pomenuto u originalnom postu.
Toliko o mogucim problemima koji ce iz ovakvog resenja proizici. Ima li 'pravog' resenja. Naravno da ima, ali nije lako, i naravno, to se u skolama ne predaje. Valjda se nema vremena od ucenja kako s episu kursori i trigeri
Za one koje mozda interesuje, napisacu ipak kako se moze malo drugacije pristupiti ovakvoj vrsti problema.
Pravo resenje bi bilo da se izbace kolone sa stanjima iz te tabele gde su sada i da se uvede nova tabela koja prati progres entiteta. Pretpostavimo da pratiomo zivot jedne 'Narudzbe', nas entitet je dakle 'Narudzba'. Narudzba prolazi kroz mnogo mogucih stanja (faza). Ako stanja nisu kolone u tabeli, nije problem dodavati nova.
Deo baze podataka koji prati zivot narudzbe mogao bi da izgleda ovako:
Code:
Narudzbe: {
(NarudzbaID NOT NULL, Kupac NOT NULL, DatumOtvarnajNarudzbe NOT NULL);
PK: NarudzbaID
}
MogucaStanja: {
(Stanje NOT NULL, Opis NOT NULL, RedniBroj UNIQUE NOT NULL);
PK:Stanje
}
PromenaStanja: {(NarudzbaID NOT NULL, Stanje NOT NULL, DatumUlaskaUStanje NOT NULL) ;
PK: NarudzbaID, Stanje;
FK1: NarudzbaIDreferences EntitetPK u tabeli 'Narudzbe';
FK2: Stanje REEFERENCES MogucaStanja(Stanje);
}
Ovim dobijamo neogranicen broj mogucih stanja. Ostaje problem da se garantuje da ce datumi promene stanja biti u rastucem redosledu. To se ne radi nikakvim trigerom ili 'kroz program'. Kao i sve ostalu u relacionim bazama, problem se resava uvodjenjem novih tabela. Samo jedne u ovom slucaju, a to je tabela koja opisuje dozvoljene promene stanja. Mladji kolege ce ovo s pravom povezati sa "UML State Transition" diagramiama. Ako u jednu kolonu upisemo pocetno stanje, i u drugu zavrsno stanje, onda bismo dobili nesto ovako:
Code:
Moguce promene stanja za 'Porudzbine':
PocetnoStanje ZavrsnoStanje
-----------------------------
NULL 'Otvorena'
'Otvorena', 'Aktivna'
'Aktivna', 'Realizovana'
'Realizovana', 'Zakljucena'
Naoruzani tabelom dozvoljenh promena stanja, treba da malo promenimo tabeli PromenaStanja, da bi dobili ovo:
Code:
Tabela PromenaStanja:
NarudzbaID Iz_Stanja U_Stanje DatumPromeneStanja
1 NULL 'Otvorena' '15 May 2010'
1 'Otvorena' 'Aktivna' '25 Maj 2010'
1 'Aktivna', 'Realizovana' '28 Maj 2010'
1 'Realizovana', 'Zakljucena' '15 Jun 2010'
Sada jos moramo da garantujemo da ce uvek prvi rekord za neku narudzbu da bude par promen sa NULL na 'Otvorena' i da ce svaki sledeci rekord imati u Iz_Stanja ono sto je bilo U_Stanje u prethodnom rekordu. E tu treba trigger, ili CONSTARINT koji koristi neku User Defined Function.
Koga zanima, moze da procita dva clanka u blogu
http://www.baze-podataka.net/category/ms-sql-server/ - potrazite
http://www.baze-podataka.net/2...-funkcija-u-check-constraints/ i
http://www.baze-podataka.net/2...nstraint-sql-rezervacija-soba/ Nema bas konkretno ovo o promeni stanja, ali ima nekoliko primera koji pokazuju kako se mogu realizovati CHECK constraints koje gledaju u vise redova u istoj tabeli ili cak u druge tabele.
Da napomenem da ne mora da bude uvek promena stanja u samo jednom mogucem rasporedu. Moguce je na primer da je narudzbu nemoguce ostvariti. Tada se iz stanja 'Otvorena' prelazi u stanje 'Odbacena'. Znaci da bi iz stanja 'Otvorena' mogli da predjemo u dva moguca stanja (za sada): 'Aktivirana' i 'Odbacena'. U realnom zivotu se stvari i desavaju tako, na svakom koraku imate neki IF. Da se te situacije opisu, pomaze UML State Transition Diagram. To je graf na kome su upisana stanja i moguci prelazi iz jednog u drugo - strelice koje povezuju stanja. Svaka strelica postaje red u tabeli MogucePromeneStanja, a svaki kriuzic postaje Iz_Stanja ili U_Stanje.
Evo dva dijagrama. jedan je "Ko sta radi" a drugi je "Promena Stanja". "Ko sta radi" dijagram pokazuje aktivnosti u sitemu. "Promene stanja" radi to isto, ali su pokazane i promene stanja. Svaka aktivnost prevodi sistem iz jednog stanja u neko drugo stanje. U nasem slucaju, pratiom entite koji se zove 'Narudzba'. Svaka aktivnost u sistemu prvodi 'narudzbu' iz jednog stanja u drugo, dok ne doved deo nekog 'happy end' ili 'not so happy end'. Tabele 'DozvoljenePromeneStanja" je objekt kojim u bazi podataka prikazujemo dijagram promena stanja.
Ko sta radi:
Promene stanja:
[Ovu poruku je menjao Zidar dana 24.09.2010. u 17:23 GMT+1]
