@ Dado: Imas dakle DVE dileme. Prva, kako da cuvas serijske brojeve vozila. Druga, kako da pratis kretanje osnovnih sredstava kroz firmu.
Prva dilema je ovde:
Citat:
Ja imam dilemu kako evidentirati te serijske brojeve
Druga dilema je opsiana ovde:
Citat:
Sam ulaz moze biti nabavka novog sredstva od nasih dobavljaca-firmi partnera ili premjestanje iz jednog magacina u drugi. Izlaz moze da bude otpis zbog dotrajalosti ili neceg drugog, zatim moze da bude zbog kretanja samog sredstva unutar firme, jer postoji vise lokacija sa vise lica koja duze ta sredstva. Zbog toga mi je sve ovo potrebno da u datom momentu znam gdje se i kod koga odredjeno sredstvo nalazi kao i to da znam koliko cega ima "UKUPNO" i koliko cega na kojoj lokaciji ili koliko koje lice duzi tih sredstava. Imam cesta pomjeranja tih sredstava i ja to zovem ulaz ili izaz.
Osnaovna sredstva delis na barem dve kategorije: 1) velike masine i vozila - imaju serijski broj, 2) sitnije srtvari (telefoni, kopir masine, kompjuteri, stampaci itd.) koji mozda imaju a mozda i nemaju serijski broj. Ne interesuje za sada te potrosni materijal (papir, so za posipanje puteva, gorivo, mazivo, sijalice, toalet papir, spajalice, municija za heftalice, fascikle itd). I hoces da pratis u jednom istom sistemu zajedno 1)velike masine i vozile i 2) sitnije stvari (telefoni, kompjuteri, printeri, forokopiri itd.)
Prvu dilemu ti je resio Zonic i Zoran - serijski broj vodis u tabeli gde vodis osnovna sredstva, neka se zove OsnovnaSredstva. Taj serijski broj je i veoma dobar kandidat za PK takve jedne tabele, ali ljudi vole da uvedu neki autonumber. Necu da se svadjam, ako imas autonumber za pK, neka ga. Znaci, Serijski broj ide u tabelu gde se osnovno sredstvo upisuje tacno jednom. Serisjski broj treba da bude, ako je iakko moguce, NOT NULL (Required u Accessu) i da bude UNIQUE. UNIQUE svakako, cak i ako su NULL vrednosti dozvoljene. To Accesu moze, unique indeksi zanemaruju NULL vrednosti po defaultu.
Za sada imamo ovakvu tabelu
OsnovnaSredstva: {OsnSredID autonumber, SerijskiBroj UNIQUE, Opis NOT NULL, Tip NOT NULL kao ('voizlo','kancelrijska oprema')}
Da probamo dilemu 2 - kako pretiti ULAz i IZLAZ. Pokazacemo jedna nacin, koji moze da prodje, iako ostavlja puno otvorenih pitanja. Kako lepo rece Zoran, oprobano u praksi i uglavnom se moze osloniti na ovu logiku.
U tabelu OsnovnaSredstva mozes, da dodas jos dve kolone - DatumNabavke i DatumOtpisa, sa ogranicenjem da je [DatumNabavke] < [DatumOtpisa]. Time bi naoko resio deo druge dileme, zapisao si ulaz i konacan izlaz. To je kao kad maticar upise u krstenicu datum rodjenja i datum smrti.
OsnovnaSredstva (atribute i ogranicenja originalnih kolna ne ponavlja zbog ustede prostora):
OsnovnaSredstva: {OsnSredID autonumber, SerijskiBroj , Opis , Tip, DatumNabavke NOT NULL, DatumOtpisa NULL}
Sadam oramo da vodimo racuna da podaci imaju smisla -ne moze se otpisati sredstvo pre nego sto je nabavljeno. Stoga:
OsnovnaSredstva: (CHECK: DatumNabavke < DatumOtpisa WHEN DatumOtpisa NOT NULL)
Ostaje probelm da se resi ono izmedju. Gde se kada nalazilo koje materijalno sredstvo. Najprostiji zahtev je da znas za sadasnji trenutak kod koga se nalazi osnovno sredstvo. Mogao bi da pokusas da dodas kolonu Zaduzio = ID radnika koji trenutno duzi osnovno sredstvo. Tako bi znao ko duzi osnovno sredstvo u svakom trenutku. Dobro, i DatumZaduzenja. Onda znas ko duzi trenutno ovo osnovno sredstvo i od kada. Ali ne znas ko je duzio osnovno sredstvo pre toga, ali te to mozda i ne interesuje. Imali bi dakle ovako tabelu:
OsnovnaSredstva: {OsnSredID autonumber, SerijskiBroj , Opis , Tip, DatumNabavke , DatumOtpisa, Zaduzio NULL, DatumZaduzenja NULL}
OsnovnaSredstva: (CHECK 1: DatumNabavke < DatumOtpisa WHNE DatumOtpisa NOT NULL)
Ako je sredstvo zaduzeno mora se znati ko duzi i od kada. Ako nije zaduzeno, ne sme pisati ni datum zaduzenja
OsnovnaSredstva: (CHECK 2: (DatumZaduzenja i Zaduzio su ili ona NULL ili nijedan nije NULL))
Naravno, datum zaduzenja mora biti veci ili jednak od DatumNabavke:
OsnovnaSredstva: (CHECK 3: (DatumZaduzenja >= DatumNabavke))
I naravno, ne moze se zadusiti sredstvo koje je otpisano:
OsnovnaSredstva: (CHECK 4: (Kad je DatumOtpisa NOT NULL ond moraju biti (Zaduzio = NULL AND DatumZaduzenja = NULL)))
kao sto vidis, tabela raste, dodajemo nove kolone, po dve zajedno is njima raste i broj ogranicenja koje ce garantovati da su podaci kvalitetni. Kakva vajda od baze podataka u kojoj pise da je kamion otpisan 1996 godina, ali ga jos uvek duzi Zika a ne zna se od kada, dok za datum nabavke pise 2001 godina?
Zasto sam rekao da ovakav nacin nije najbolji? Pa upravo zbog ovih ogranicenja koja se jednostavno moraju uspostaviti, iance ode mast u propast. Ogranicenja na tabeli se u Accesu tesko psotavljaju ako su iole slozenija. CHECK 1 se lako psotavlja (table design, properties, validation rule). Ostala ogranicenja su komplikovanija da se postave. Cak i ako uspemo da ih postavimo kao logicki izraz koj je FALSe ili TRUE, ostaje problem da ih upisemo u ValidationRule. Mislim da je limit 1024 karaktera i ako nista, zbog toga verovatno nevemo moci da postavimo ova pravila. Ako mislite da cete lako u aplikaciji postaviti ova ogranicenja, varate se grdno. Zasto ljudi ipak prihvataju ovakvo resenje? Iz dva razloga. Prvo, malo ljudi zna za bolje resenje. Drugo, ako i znamo, nije lako da se odradi.
Zavrsni udarac: mozemo da pokazemo koji radnik duzi koje sredstvo. A sta ako niko ne duzi ovo sredstvo? Ono se nalazi ili u nekom magacinu, ili je otpisano. Da dodamo jos dve kolone Magacin, DatumUlaskaUMagacin uz ogranicenje da ako postoji (Zaduzio,DatumZaduzenja) onda ne sme da postoji (Magacin,DatumUlaskaUMagacin). I naravno, ako je stvar otpisana, ne sme da postoji (Magacin,DatumUlaskaUMagacin). Recimo da ito postavimo nekako. Pogledajmo na sta lici tabela:
OsnovnaSredstva: {OsnSredID autonumber, SerijskiBroj , Opis , Tip, DatumNabavke , DatumOtpisa, Zaduzio NULL, DatumZaduzenja NULL, Magacin NULL, DatumUlaskaUMagacin NULL}
OsnovnaSredstva: (CHECK 1: DatumNabavke < DatumOtpisa kad DatumOtpisa NOT NULL)
OsnovnaSredstva: (CHECK 2: (DatumZaduzenja i Zaduzio su ili ona NULL ili nijedan nije NULL))
OsnovnaSredstva: (CHECK 3: (DatumZaduzenja >= DatumNabavke))
OsnovnaSredstva: (CHECK 4: (Kad je DatumOtpisa NOT NULL ond moraju biti (Zaduzio = NULL AND DatumZaduzenja = NULL AND Magacin = NULL AND DatumMAgacina = NULL)))
OsnovnaSredstva: (CHECK 5: (DatumUlaskaUMagacin >= DatumNabavke))
OsnovnaSredstva: (CHECK 6: (DatumUlaskaUMagacin i Magacin su ili ona NULL ili nijedan nije NULL))
I sve ovo pre nego sto smo dodali ostale kolone koje su vazne za osnovno sredstvo (vidi Zoranov model). Posto su sva navedena ogranicenja nad jednim redom u atbeli, teorijski je moguce postaviti ih. U praksi, u nekom drugom sistemu (MS SQL, ORACLE i slicno) MOGUCE je postaviti ova ogranicenja, ali u Accesu je to fizicki nemoguce zbog ogranicenja u broju karaktera u Table Val;idation Rule. Mozda bi kroz JEt moglo da se kaze neko ALTER TABLE ADD CONSTRAINT.... (Boze sacuvaj gde smo zabasali;-) ali se posle to ne moze videti niti editovati (i ako moze, vrlo tesko), prakticno, u Accesu nemoguce. Pa sta, kazacet, skinem SQL Express i uradim to tamo.
Namece se jos jedno pitanje: Ako je nako duzio kamion od 12 Marta 2008 do 10 januara 2011 i onda kamion odlazi u magacin. Brisemo sve iz (Zaduzio, DatumZaduzenja) i upisujemo (Magacin = 'm1', DatumUlaskaUmagacin = #10 januar 2010#). Ko garantuje da cemo tacno upisati datum ulaska u magacin? Sa ovako definisanom tabelom, ni u SQL serveri ni u ORACLE to nije moguce odraditi bez trigera. E sad odosmo i u trigere. Sto je mnogo, mnogo je. Ovako mozemo do sutra, stalno ce se pojavljivati neko novo ogranicenej koga se nismo setili do malopre.
A i preksrisli smo neko tamo pravilo normalizacije koje kaze: svaka kolona u tablei sme da zavisi samo i samo od PK. Ako kolone zavise jedna od druge to nije dobro. Zasto? Zato sto je tesko garntovati integritet (istinitost) podataka. Zato sto smo narusili pravilo normalizacije moramo da se vadimo kroz CHECK constraints.
I sva ova nevolja i rabota da bi videli gde se u samo ovom momentu nalazi koje sredstvo. Nikakva istorija, nista. A toliko mogucnosti za greske i naravno - malverzacije. Zamislite da ne znate gde vam se nalazi kamion ili buldozer. Ili tenk. Kako cemo ponovo da ratujemo ako ne znamo gde nam je tenk?
Rekoh, moze ovako, ali da se vodi racuna o ogranicenjima.
Moze li nekako drugacije? Moze, ali je veoma razlict pristup, nije jednostavan i sve je toliko novo da nema ni velikih iskustava. Ako hocete da budete pioniri novijh metoda ili da naucite nesto sto ce biti norma za deset godina, mozeo da pokusamo.
Ko je za?