[ fikri @ 23.09.2010. 20:39 ] @
Imam u firmi instaliran MS SQL server na mrezi koji je otvorenog tipa, znači imam full pristup bazama i tabelama.
Eh sad, potrebne su mi neke dorade u softweru koji koristi ove baze ali firma od koje smo ga nabavili ne radi više, a softwer smo naručili posebno za našu firmu i prilagodili ga.
Da skratim, potrebno mi je nekako da napravim da se svaka promjena vrijednosti nekog podatka u nekoj tabeli zabilježi nekako tj. da se napravi još jedna dodatna kolona sa datumom i vremenom izmjene susjedne kolone.
Ne poznajem bas dobro principe funkcionisanja SQL SERVERA, pa sam se pitao da li je moguće napraviti direktno na serveru u bazi nekakve procedure koje bi to radile? Da li je to moguće, ima li neko neku ideju kako bi se to moglo riješiti?
Hvala
[ stevs986 @ 23.09.2010. 21:23 ] @
Ne znam kakvo pracenje konkretno zelis, samo datum izmene ili jos nesto. Moguce je napraviti recimo zurnal tabele u koje triggerom smestas sve promene koje se dese nad glavnom tabelom.

Zurnal tabela je nista drugo nego tabela sa strukturom istom kao glavna tabela (ona nad kojom pratis izmene) i mozda jos par dodatnih kolona, zavisi sta ti je potrebno.

Napr. ukoliko se desi update, insertujes i ono sto je bilo ranije i ono sta si update - ovao, tako da imas citavu istoriju promena. Isto mozes i za delete, insert... Kazem, zavisi sta ti je potrebno.
[ fikri @ 23.09.2010. 22:18 ] @
Mozda nisam bio bas najjasniji...

Potrebno mi je vrijeme nastajanja novog podatka i vrijeme izmjene postojećih...
Imam tabelu sa kolonama: ..."aktivna", "realizovana", "zakljucena"... sa mogucim vrijednostima 0 ili 1..

Potrebna mi je nekakva dodatna kolona
"aktivna_datumpromjene", "realizovana_datumpromjene", "zakljucena_datumpromjene" i datum_kreiranja
u kojoj bi se stavljao datum nakon sto neka od ovih podataka promijeni vrijednost, odnosno nakon sto se kreira novi podatak..
Te bi vrijednosti kasnije koristio za neke izvještaje koji su mi potrebni.

E sad moze li se to izvesti i kako je najbolje to uraditi?
I ako moze malo jednostavnije to objasnjenje, nisam bas iskusan sa SQL serverom.. Trenutno ga koristim preko FOX-a i super mi radi, sami bi mi ove dorade ustedjele mnogo vremena jer to inace radim rucno..

Ovako sam ja to zamislio, a ako imas neko bolje rjesenje slobodno javi...





[ stevs986 @ 24.09.2010. 09:05 ] @
Evo primera.


Alterujes tabelu nad kojojm pratis promene, dodas kolonu recimo datum_promene.

Napravis triger nad tabelom, napr.

Code:


 CREATE TRIGGER Test
 ON Ime_Tabele AFTER UPDATE
 AS
 IF UPDATE(kolona1) OR UPDATE ( kolona2) OR ...
 BEGIN
  -- Radi update kolone datum_izmene trenutnim datumom
 END




Pazis samo da kada navodis imena kolona izostavis datum_izmene, da ne napravis beskonacnu petlju.


Jasnije od ovog ne moze... ;)
[ Zidar @ 24.09.2010. 16:13 ] @
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]
[ fikri @ 24.09.2010. 17:55 ] @
Hvala na iscrpnom odgovoru!
Trebaće mi malo vremena da sve analiziram...
Hvala jos jednom