2012-08-02 12 views
96

błędów MSG na mysql nielegalne mieszanka sortowania (utf8_unicode_ci, bezpośrednia) i (utf8_general_ci, bezpośrednia) dla operacji „=”nielegalne mieszanka sortowania (utf8_unicode_ci, bezpośrednia) i (utf8_general_ci, bezpośrednia) dla operacji „=”

Przeszedłem kilka innych postów i nie byłem w stanie rozwiązać tego problemu. Część dotknięte jest coś podobnego do tego:

CREATE TABLE users (
    userID INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    firstName VARCHAR(24) NOT NULL, 
    lastName VARCHAR(24) NOT NULL, 
    username VARCHAR(24) NOT NULL, 
    password VARCHAR(40) NOT NULL, 
    PRIMARY KEY (userid) 
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci; 

CREATE TABLE products (
    productID INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    title VARCHAR(104) NOT NULL, 
    picturePath VARCHAR(104) NULL, 
    pictureThumb VARCHAR(104) NULL, 
    creationDate DATE NOT NULL, 
    closeDate DATE NULL, 
    deleteDate DATE NULL, 
    varPath VARCHAR(104) NULL, 
    isPublic TINYINT(1) UNSIGNED NOT NULL DEFAULT '1', 
    PRIMARY KEY (productID) 
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci; 

CREATE TABLE productUsers (
    productID INT UNSIGNED NOT NULL, 
    userID INT UNSIGNED NOT NULL, 
    permission VARCHAR(16) NOT NULL, 
    PRIMARY KEY (productID,userID), 
    FOREIGN KEY (productID) REFERENCES products (productID) ON DELETE RESTRICT ON UPDATE NO ACTION, 
    FOREIGN KEY (userID) REFERENCES users (userID) ON DELETE RESTRICT ON UPDATE NO ACTION 
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci; 

Procedura przechowywana używam to:

CREATE PROCEDURE updateProductUsers (IN rUsername VARCHAR(24),IN rProductID INT UNSIGNED,IN rPerm VARCHAR(16)) 
BEGIN 
    UPDATE productUsers 
     INNER JOIN users 
     ON productUsers.userID = users.userID 
     SET productUsers.permission = rPerm 
     WHERE users.username = rUsername 
     AND productUsers.productID = rProductID; 
END 

ja testował z php, ale ten sam błąd jest podawany z SQLyog. Testowałem również odtwarzanie całego DB, ale na nic.

Każda pomoc będzie mile widziane.

Odpowiedz

136

Są cztery opcje:

Opcja 1: dodaj COLLATE do zmiennej wejściowej:

SET @rUsername = ‘aname’ COLLATE utf8_unicode_ci; -- COLLATE added 
CALL updateProductUsers(@rUsername, @rProductID, @rPerm); 

Opcji 2: dodaj COLLATE do WHERE klauzuli:

CREATE PROCEDURE updateProductUsers(
    IN rUsername VARCHAR(24), 
    IN rProductID INT UNSIGNED, 
    IN rPerm VARCHAR(16)) 
BEGIN 
    UPDATE productUsers 
     INNER JOIN users 
     ON productUsers.userID = users.userID 
     SET productUsers.permission = rPerm 
     WHERE users.username = rUsername COLLATE utf8_unicode_ci -- COLLATE added 
     AND productUsers.productID = rProductID; 
END 

Optio n 3: dodać go do definicji IN parametru:

CREATE PROCEDURE updateProductUsers(
    IN rUsername VARCHAR(24) COLLATE utf8_unicode_ci, -- COLLATE added 
    IN rProductID INT UNSIGNED, 
    IN rPerm VARCHAR(16)) 
BEGIN 
    UPDATE productUsers 
     INNER JOIN users 
     ON productUsers.userID = users.userID 
     SET productUsers.permission = rPerm 
     WHERE users.username = rUsername 
     AND productUsers.productID = rProductID; 
END 

Wariant 4: alter boiska sam:

ALTER TABLE users CHARACTER SET utf8 COLLATE utf8_general_ci; 

jako domyślnego sortowania parametrów procedura przechowywana jest utf8_general_ci i można” t wymieszać zbiory.

Jeśli nie chcesz sortować danych w kolejności Unicode, sugerowałbym zmianę wszystkich twoich tabel w celu użycia sortowania utf8_general_ci, ponieważ nie wymaga to zmian w kodzie, a przyśpiesza sortowanie.

+0

Twoja pierwsza opcja była odpowiedź szukałem =). Dziękuję Ci. – Manatax

+1

Możliwe jest również dodanie 'COLLATE utf8_unicode_ci' do stałych łańcuchowych: ' SET @EMAIL = '[email protected]' COLLATE utf8_unicode_ci; '. Jest to szczególnie przydatne, jeśli uruchamiasz skrypt z konsoli, w której domyślne kodowanie konsoli dotyczy stałego zestawienia ciągów znaków. – gaborsch

+0

Lub usuń bazę danych i utwórz nowe za pomocą utf8_general_ci; porównanie. – Oleksii

16

Spędziłem pół dnia szukając odpowiedzi na identyczny błąd "Illegal mix of collations" z konfliktami między utf8_unicode_ci i utf8_general_ci.

Znalazłem, że niektóre kolumny w mojej bazie danych nie zostały specjalnie zebrane utf8_unicode_ci. Wygląda na to, że mysql niejawnie zebrał te kolumny: utf8_general_ci.

szczególności prowadzenie 'SHOW CREATE TABLE tabela1' zapytanie wyprowadzane coś jak następuje:

| table1 | CREATE TABLE `table1` (
`id` int(11) NOT NULL, 
`col1` varchar(4) CHARACTER SET utf8 NOT NULL, 
`col2` int(11) NOT NULL, 
PRIMARY KEY (`photo_id`,`tag`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci | 

Uwaga varchar linia 'Col1' (4) CHARACTER SET utf8 NOT NULL nie ma sortowania określony.Potem prowadził następujące zapytanie:

ALTER TABLE table1 CHANGE col1 col1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;

to rozwiązało mój "Illegal mix sortowania" błędu. Mam nadzieję, że to może pomóc komuś innemu.

+4

dzięki. "SHOW CREATE TABLE" to najprostszy sposób na zrozumienie i naprawę podstawowej przyczyny problemu. – joro

4

Miałem podobny problem, ale przyszło mi do głowy podczas procedury, gdy mój parametr zapytania został ustawiony przy użyciu zmiennej np. SET @value='foo'.

Przyczyną tego był niezgodny zbiór collation_connection i bazy danych. Zmieniono collation_connection w celu dopasowania collation_database, a problem zniknął. Myślę, że jest to bardziej eleganckie podejście niż dodawanie COLLATE po parametrze/wartości.

Podsumowując: wszystkie zestawienia muszą być zgodne. Użyj wartości SHOW VARIABLES i upewnij się, że są one zgodne (sprawdź także sortowanie tabeli przy użyciu SHOW TABLE STATUS [table_name]).

+0

Ten sam problem przydarzył mi się, unikałem zmiany zmiennych collation_YYY przez ustawienie sortowania bezpośrednio w deklaracji zmiennej. 'SET @my_var = 'string1, string2' COLLATE utf8_unicode_ci;' – nkatsar

1

Podobny do odpowiedzi @bpile, moim przypadkiem było ustawienie wpisu my.cnf collation-server = utf8_general_ci. Po uświadomieniu sobie, że (i po wypróbowaniu wszystkiego powyżej), to siłą włączone moja baza do utf8_general_ci zamiast utf8_unicode_ci i to było to:

ALTER DATABASE `db` CHARACTER SET utf8 COLLATE utf8_general_ci; 
+1

To dziwne, że konfiguracje są tak rozrzucone. Wszystkie ustawienia domyślne należy ustawić w tym samym miejscu. – Manatax

Powiązane problemy