[ gilespy @ 04.03.2006. 15:11 ] @
Imam tabelu sa kolonama ID, Ime i Godina.


Korisnik pri unosu ne vidi ID, vec samo Ime i Godinu. Da li je moguce

spreciti duplirani unos imena i godine, tacnije ako vec postoji Pera 1982

onda ne sme biti dozvoljen jos jedan takav unos?


U pitanju je SQL 2000 Personal


Hvala
[ dragancesu @ 04.03.2006. 19:14 ] @
Jedno od resenja je UNIQUE index.

Ne koristim tu bazu
[ _owl_ @ 04.03.2006. 21:30 ] @
Moze i preko trigera koji ce se izvrsavati pre INSERT i UPDATE naredbi. Ovo resenje je losije od prethodno navedenog ali cisto da se zna da moze i ovako da se uradi.
[ gilespy @ 05.03.2006. 11:51 ] @
Jeste li sigurni da moze preko UNIQUE. Mozda gresim, ali kada bih postavio

UNIQUE tada ne bih mogao uneti ni dva puta istu godinu ni dva puta isto

ime.


Poenta je bila da se ne dozvoli unos istog imena i iste godine, tako da

citav red ne moze da se ponovi. Znaci ako u polju ime imamo Peru i u polju

godina 1984, tada necu da se u isti red moze ponovo uneti ta kombinacija,

ali moze Pera 1982 ili Nikola 1984.


Meni je palo na pamet da je ovo moguce preko ROLLBACK trigera za INSERT i

UPDATE, ali nisam siguran kako bih ga realizovao.


Hvala
[ _owl_ @ 05.03.2006. 14:19 ] @
Ne znam kako da ti kaze ali sinko gresis ovaj silno gresis. Indeksi i ogranicenja nisu vezani samo za jedno polje vec mogu da se odnose na vise polja, tako je gle cuda moguce staviti UNIQUE indeks na dve kolone.
Resenje sa triger-ima je upotrebljivo kada je broj kolona na koji treba staviti UNIQUE index veliki ili njihova ukupna velicina premasuje dozvoljenu velicinu za UNIQUE indeks.
[ gilespy @ 05.03.2006. 15:14 ] @
OK. A kako bi izgledalo ako bih hteo ograniciti unos na max dve iste

vrednosti?


Npr. neka je istom onom Peri iz prethodnog primera dovzoljeno da ima max

dve vrednosti za godinu. Naravno, Pera bi se gledao po ID-ju, jer moze biti

vise Pera, a hocu da svaki moze uneti tacno x vrednosti za godinu (znaci za

ID 1 Ime Pera Godina 1984 i za ID 1 Ime Pera Godina 1982)?


Hvala
[ Miloš Baić @ 06.03.2006. 23:25 ] @
Ovaj kod:
Code:
SELECT DISTINCT Ime, Godina
FROM          Naziv_tabele

ispisuje sve podatke iz tabele, ali ne ponavljajući iste vrednosti, ne duplira. Probaj staviti UNIQUE i za godinu i za ime. Neka ti ID bude PRIMARY, a može i UNIQUE... UNIQUE je jedinstveni index i osigurava da dva reda neće sadržati duplirane podatke, možeš ih dodati koliko želiš.
[ gilespy @ 06.03.2006. 23:53 ] @
Nije to to. Na taj nacin nece moci biti dva puta Pera 1984, ali nije u tome

poenta. UNIQUE nece spreciti da ja imam Pera 1984, Pera 1982, Pera 1980...


Stos je da Peri mogu dodeliti max dve razlicite godine. Znaci dozvoljene su

kombinacije Ime1 + godina1 i Ime1 + godina2, ali ne i Ime1 + godina3.


Neka je vrednost u koloni Godina predstavlja godinu mature ( i neka postoji

samo mala i velika matura). Znaci osoba x je maturirala y godine i z

godine, ali nije mogla w godine, jer treca matura ne postoji.
[ jablan @ 07.03.2006. 08:14 ] @
Nikako, osim triggera.

Mada, za slučaj koji navodiš kao primer (mala i velika matura) ispravno je napraviti dva polja, umesto da koristiš dva reda (drugim rečima, glup ti je primer).
[ gilespy @ 07.03.2006. 12:37 ] @
OK, ajde da vidimo taj triger.
[ jablan @ 07.03.2006. 13:12 ] @
Citat:
gilespy: OK, ajde da vidimo taj triger.

Sluga pokorni...
Code:

CREATE TRIGGER t1 ON Tabela
FOR INSERT
AS
declare @c int

select top 1 @c = count(*) from Tabela t
group by t.Ime
order by count(*) desc

IF @c > 2
ROLLBACK TRANSACTION
[ Zidar @ 07.03.2006. 13:43 ] @
A da malo preorganizujes tabelu, pa da dodas polje 'Dogadjaj'. Onda bi imao ovako:

Tabel LjudiDogadjaji:
Ime, Dogadjaj, Godina
------------------------
'Pera', 'Mala Matura', 1984
'Pera', 'Velika Matura', 1988

Broj dogadjaja koji se mogu pripisati Imenu moze se kontrolisati kroz looku-up atbelu Dogadjaji, pa stavis Foreign Key u tabelu LjudiDogadjaji. Stavis u tabelu Dogadjaji dve reda:

Dogadjaj
---------
'mala matura'
'velika matura'

Onda stavis UNIQUE INDEX na polja (Ime,Dogadjaj) Ovo ce spreciti Peru da ima vise od jedne Male Mature na primer. Ali ne sprecaba te da uneses na primer

Ime, Dogadjaj, Godina
------------------------
'Pera', 'Mala Matura', 1984
'Pera', 'Velika Matura', 1984

Kako spreciti da velika i mala matura imaju istu godinu? Pa, jos jedan index, ovoga puta po poljima (Ime,Godina). Tako pera nece moci da ima rekord sa godinom 1984 dva puta.

Ostaje jos jedan problem - kako da Velika matura ima datum veci od Male Mature?
Ovo pitanje nam dokazuje da dizajn tabela koji smo postavili nije dobar. Naravno da se moze resiti pomocu triggera - kad se radi INSERT u tabelu LjudiDogadjaji, treba videti koja se vrednost insertuje u kolonu Dogadjaj, pa na osnovu toga i vrednosti u koloni Dogadjaj za istog covek u nekom prethodnom redu, odluciti da li je godina dobra ili nije.
[ _owl_ @ 07.03.2006. 20:36 ] @
Pored trigera mogu se koristiti i ogranicenja (constraints) na vrednosti podataka u tabeli. Cini mi se da je ovo bolje resenje u odnosu na trigere pogotovo ako se radi o malo slozenijim ogranicenjima ili kada je vec potrebno koristiti trigere za druge svrhe (dodatna azuriranja).
Uz instalaciju Oracle-a dolazi i "test" baza u kojoj se lepo vide primeri koriscenja i constrainta koji se odnose samo na moguce vrednosti podataka i trigera koji onemogucuju unos samo u specijalnim slucajevima (npr. vezano za vreme kada se podaci unose).
[ dekibre @ 08.03.2006. 13:02 ] @
Citat:
Pored trigera mogu se koristiti i ogranicenja (constraints) na vrednosti podataka u tabeli. Cini mi se da je ovo bolje resenje u odnosu na trigere pogotovo ako se radi o malo slozenijim ogranicenjima ili kada je vec potrebno koristiti trigere za druge svrhe (dodatna azuriranja).

Mozes li owl da pokazes kako bi ovo resio pomocu constrainta?

[ dekibre @ 08.03.2006. 13:16 ] @
Ponudjeno resenje sa UNIQUE INDEXOM nad kolonama je interesantno, ono sto je ostalo kao mala nedoumica u inicijalnom pitanju, da li su dozvoljene null vrednosti za Ime, Godina? Ako jesu, onda kada se postavi UNIQUE INDEX nad kolonama dozvoljena je i kombinacija.

Ime Godina
Pera NULL
NULL 1982
NULL NULL
[ Zidar @ 08.03.2006. 13:52 ] @
Posto jos niko nije definisao tacno sta su NULL vrednosti, preporucujem ti da ih zabranis. Ako ih i dopustis, imaces ono sto si naveo. Kavu ti informaciju daje onaj red u kome je u koloni Godina vrednost NULL a u koloni Dogadjaj neka vrednost? Mozda to znaci da "Pera ima malu maturu ali ne znamo koje godine". Ako ti je NULL u polju Ime, onda to znaci "neko (ne znamo ko) imao je malu/veliku maturu, neke godine" Kakva je vrednost tog iskaza? Ili onaj u konme su sve vrednsoti NULL? "Ne znamo ko, ne znamo koje godine imao je maturu, veliku ili malu, ne znamo ni to".

Ime Godina
Pera NULL = Pera je nesto radio, ali ne znamo kada
NULL 1982 = neko je nesto radio 1982 godine, ali ne znamo ko
NULL NULL = neko je neke godine radio nesto, ne znamo ko, ne znamo kada

NULL vrednsoti su nedefinisane i ako ih dozvolis, dobices u najboljem slucaju nekompletnu informaciju (Pera ima veliku maturu ali ne znamo od koje godine) ili potpuno besmislenu informacije - neko peolizo veliku maturu 1979. I ja sam polozio veliku maturu 1979 godine, pa dakle mozes da me ubacis u svoju tabelu. I jos 250 iz moje gimnazije. I 350 iz neke druge gimnazije, iz nekog drugog grada.

NULL dakle zabarani. Ako pak treba da cuvas i nekompletne informacije, onda je potreban radikalno drugaciji dizajn tabela, koji bi ti omogucio da znas da je Pera polozio veliku maturu, ali da ti nedostaje podatak o godini a da nemas NULL vrednosti. O tome ne mozem sad da raspravljamo sada jer ne znamo sta u stvari modeliras.

Usput, ako je drupa kolona definisana kao PK, ne moze ni jedna od njih biti NULL, SQL to ne dozvoljava. Ako je grupa kolona definisana kao UNIQUE INDEX, mozes da imas NULL vrednosti, ali samo po jedamput (U Accessu mozes da imas koliko hoces NULL vrednosti iako je index UNIQUE, ali ne i u MS SQL)

:-)

[Ovu poruku je menjao Zidar dana 08.03.2006. u 14:52 GMT+1]
[ gilespy @ 08.03.2006. 22:29 ] @
Meni nije jasno kako UNIQUE sprecava da za Peru bude vise od dve godine.


Osim toga, ne moze UNIQUE u tom obliku, jer mozda ima jos neki pera koji je

maturirao iste godine. Fora je da Pera moze imati jednu ili dve godine

(znaci moze NULL) ali ne i vise od dve. Isto tako mogu imati x Pera, koji

se razlikuju samo po ID-jevima.


Jedino sto sam ja pronasao je resenje preko UDF-a koji se proverava preko

CHECK constraint-a, ali taj primer nisam mogao implementirati na ovaj

slucaj, jer se odnosio na dve tabele (glavna (referentna) i pomocna), a

ovde se radi o tri, gde su tabele Osobe i Godine tabele iz kojih se ID-jevi

prepisuju u referentnu tabelu Maturanti.


Nemojte da pitate sto godine i imena nisu u jednoj tabeli. Ovo je

hipoteticka postavka. Prave tabele su drugacije i deo su velikog IS-a, ali

ovako sam pojednostavio i posmatrajte kao da se organizacija tabela ne moze

menjati.
[ Zidar @ 09.03.2006. 14:51 ] @
Citat:
Meni nije jasno kako UNIQUE sprecava da za Peru bude vise od dve godine.


Osim toga, ne moze UNIQUE u tom obliku, jer mozda ima jos neki pera koji je

maturirao iste godine. Fora je da Pera moze imati jednu ili dve godine

(znaci moze NULL) ali ne i vise od dve. Isto tako mogu imati x Pera, koji

se razlikuju samo po ID-jevima.



Dogadjaj
------------
'Mala Matura',
'Velika Matura'

I ako imas FK na tabelu u kojoj je Pera, na polje Dogadjaj, ni jedan Pera nece moci da ima niste drugo u koloni Dogadjaj osim sta je dato u tblListaMogucihDogadjaja.
Rekao sam ti i ovo:
Citat:

Onda stavis UNIQUE INDEX na polja (Ime,Dogadjaj) Ovo ce spreciti Peru da ima vise od jedne Male Mature na primer.


bez problema ces da uneses:
Ime Dogadjaj Godina
---------------------------
Pera, 'Velika Matura', 1985
Pera, 'Mala matura', 1985

Za Peru vise ne mozes da uneses ni jedan rekord jer ces uneti duplikat po indeksu (Ime, Dogadjaj). Ne mozes da uneses ni neki novi dogadjaj, jer te sprecava tabela tblListaMogucihDogadjaja. Znaci, postigli smo cilj, ne vise od dva rekorda za Peru

Pa sam ti rekao:
Citat:
Kako spreciti da velika i mala matura imaju istu godinu? Pa, jos jedan index, ovoga puta po poljima (Ime,Godina).


Kako da obezbedis da mala matura bude pre velike mature? Triger i funkcija.

Ako se dozvoljava vise od jednog Pere, onda sam Pera nije dovoljan da bude deo unique indeksa. Mora bti nesto u tabeli da ti kaze kako da razlikujes Peru od drugog Pere. Lepo to dodas u one indekse, i zavrsio si posao.

Ako struktura tabela ne sme da se menja, a treba da postavis logicko ogranicenje, onda je najbolje to uraditi kroz triger, koji ce mozda da poziva neku funkciju. Na primer, na svaki insert proveri koliko taj Pera vec ima godina, pa ako vec ima dovoljno, odbaci transakciju. To ti je neko lepo gore predlozio. Ponovo je problem kako znas koji Pera je koji? Ako ti funkcija pomaze da odredis sta je sta, onda OK, ti si resio problem.

[ gilespy @ 09.03.2006. 17:41 ] @
Da, to je OK.


Mora se spustiti FK na tabelu u kojoj je Pera i tada je problem resen.


Hvala svima.