Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: unikalnosc rozbudowanego wyrazenia w MySQL
Forum PHP.pl > Forum > Bazy danych > MySQL
kanan
W jaki sposob mozna z sukcesem przy tworzeniu nowej tabeli utworzyc unikalnosc na np. dwoch kolumnach?

Niestety takiego cos nie przynosi pozytywnego rezultatu:

CREATE TABLE a (
key INT(8) PRIMARY KEY,
a TINYINT(2) DEFAULT NULL,
b TINYINT(3) DEFAULT NULL,
c TINYINT(4),
UNIQUE unique_ab (a,cool.gif
);
elessar
  1. CREATE TABLE a (
  2. `key` INT(8),
  3. `a` TINYINT(2) DEFAULT NULL,
  4. `b` TINYINT(3) DEFAULT NULL,
  5. `c` TINYINT(4),
  6. PRIMARY KEY (`key`),
  7. UNIQUE KEY `a` (`a`),
  8. UNIQUE KEY `b` (`b`)
  9. ) ENGINE=MyISAM DEFAULT CHARSET=latin2;
kanan
Ale czy to zapewnia, ze unikalnosc ma byc tylko w przypadku albo A albo B? Chodzi mi o to by para byla unikalna, natomiast osobno moga pojawic sie duplikaty. Np.

1, 1,
1, 2,
1, NULL,
itd.
nospor
kanan, zjadles w swoim sql slowo key:
  1. UNIQUE KEY unique_ab (a,b )

to powinno juz dzialac
kanan
Niestety taki uklad nie dziala sad.gif Moge dodac ile razy chce pare 1,NULL...
nospor
dziwne. bo mi taki zapis blokuje dodawanie takich wpisów.
a czy moglbys jeszcze raz dokladnie zapodac to zapytanie, juz z moimi zmianami?
kanan
  1. CREATE TABLE `a` (
  2. `test_key` int(8) NOT NULL,
  3. `a` tinyint(2) DEFAULT NULL,
  4. `b` tinyint(3) DEFAULT NULL,
  5. `c` tinyint(4) DEFAULT NULL,
  6. PRIMARY KEY (`test_key`),
  7. UNIQUE KEY `unique_ab` (`a`,`b`)
  8. ) ENGINE=MyISAM DEFAULT CHARSET=latin2;


Prosto z admina.
nospor
po edycji po przedniego posta widze, ze ty walisz nulle do tego (swoją drogą moglem to juz wczesniej zauwazyc sad.gif ). No niestety nulle nie są brane pod uwage smile.gif
http://dev.mysql.com/doc/refman/5.0/en/create-table.html
Cytat
A UNIQUE index creates a constraint such that all values in the index must be distinct. An error occurs if you try to add a new row with a key that matches an existing row. The exception to this is that if a column in the index is allowed to contain NULL values, it can contain multiple NULL values.
kanan
Chyba nie do konca...
  1. INSERT
  2. INTO `a`
  3. ( `test_key` , `a` , `b` , `c` )
  4. VALUES (
  5. '', '1', NULL , NULL
  6. ), (
  7. '', '1', NULL , NULL
  8. )


MySQL said: Documentation
#1062 - Duplicate entry '0' for key 1

Jak to wyjasnic??
Dodaje nulla i tu juz dziala. Jednak zapomnialem dodac jedna rzecz. Dziala to wtedy gdy nie ma kluczy obcych. Dodatkowo w tej tabeli jest klucz obcy c i wtedy moge dodawac co mi sie podoba.
nospor
nie kanan. twoj aktualny blad wynika z tego, ze nie nadales autoincrement na klucz glowny. w wyniku czego, przy takim dodawaniu rekordów co pokazales, do bazy do klucza glownego wstawiane jest 0. a ze klucz glowny nie moze sie powtarzac, wiec poraz drugi 0 nie mozesz wstawic, a ty to wlasnie robisz. Error ci to wlasnie sygnalizuje smile.gif
kanan
Tak wlasnie zauwazylem sad.gif Czy nie ma mozliwosci aby to obejsc. Rozwiazanie wychodzi latwe, ale moze jest jakas inna mozliwosc? Bo najlatwiej byloby zmienic wartosc NULL na 0, ale to pociaga za soba inne zmiany, wiec jest troche niemile widziane.
Adiasz
Mozesz napisac procedure sprawdzajaca czy istnieje jakis rekord z tymi dwoma wartosciami i stworzyc triggera before insert.
kanan
Tak, tez o tym myslalem, ale jest jeden problem w jaki sposob w trigerach w mySQL wyrzucic blad? Bo nie ma zadnej funkcji, ktora by tego mogla dokonac. Chyba, ze obsluga triggera moze miec inna postac? Bo ja chcialem zrobic w ten sposob:
jesli dana wartosc istnieje, to rzuc wyjatek/blad, ale tak sie nie da w prosty sposob.
Adiasz
Przyznam sie ze nie mialem jeszcze okazji napisac trigera w mysql. Ale filozofi raczej nie ma bo przeciez gdy select wartosciami zwroci jakis rekord wtedy insert nie zadziala, zatem mozesz sprawdzic w phpcu affected rows (zmodyfikowane wiersze) i gdy wartosc bedize 0 wtedy masz wyjatek :-)
kanan
Nie rozumiem co masz dokladnie na mysli, w tym przypadku trigger powinien robic taka rzecz:

sprawdza czy dane pole, ktore posiada a oraz b juz istnieje, jesli tak rzuca wyjatek, w przeciwnym wypadku doda do bazy. Tylko w jaki sposob w triggerze mySQL rzucic wyjatek?

Nie rozumiem tego zdania:
Cytat
przeciez gdy select wartosciami zwroci jakis rekord wtedy insert nie zadziala,
. Mozesz przyblizyc swoja koncepcje?
Adiasz
nie wiem jak sie wyrzuca w mysql wyjatek, ale jezeli INSERTa zawrzesz w IFie sprawdzajacym podany przez Ciebie warunek to sie nie wykona i zadne wiersz mysqla nie zostanie przetworzony prawda?
A pozniej na identyfikatorze polaczenia robisz mysql_affected_rows i jezeli bedzie 0 to znaczy ze wartosci takie juz istnieja w bazie i masz w ten sposob przechwycony wyjatek.
Nie testowalem tego i nie jestem do konca pewien czy takie rozwiazania Ci e zadawala. Wydaje mi sie jednak logiczne w tej sytuacji, chyba ze sie myle?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.