Niedozwolona kombinacja zestawień Błąd MySQL

124

Otrzymuję ten dziwny błąd podczas przetwarzania dużej liczby danych ...

Error Number: 1267

Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '='

SELECT COUNT(*) as num from keywords WHERE campaignId='12' AND LCASE(keyword)='hello again 昔 ã‹ã‚‰ ã‚ã‚‹ å ´æ‰€'

Co mogę zrobić, aby rozwiązać ten problem? Czy mogę jakoś uciec od ciągu, aby ten błąd się nie pojawił, czy też muszę jakoś zmienić kodowanie mojej tabeli, a jeśli tak, to na co mam to zmienić?

Kliknij opcję Głos za
źródło
ten błąd to do wstrzyknięcia czy nie?
hamza irizaj
1
Czy to odpowiada na twoje pytanie? Niedozwolona kombinacja błędów sortowania w MySql
Farhan

Odpowiedzi:

289
SET collation_connection = 'utf8_general_ci';

następnie dla twoich baz danych

ALTER DATABASE your_database_name CHARACTER SET utf8 COLLATE utf8_general_ci;

ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

MySQL wkrada się tam czasem po szwedzku bez rozsądnego powodu.

Ben Hughes
źródło
3
@Ben: Dziękuję za rozwiązanie do bezpośredniego kopiowania i wklejania. Zaoszczędziło mi mnóstwo czasu.
Pistos
15
@Ben: Początkowo został opracowany przez szwedzką firmę ... To jest przyczyna irytujących początkowych ustawień latin1_swedish_ci .. :(
Vajk Hermecz
1
Nie masz uprawnień do zrobienia pierwszego komunikatu, ale to działało po prostu robi tabelę
Rob Sedgwick
Kocham cię za to! : P
prateekkathal
Wygląda na to, że to działa dla wielu osób, ale niestety nadal mam ten problem, nawet po wypróbowaniu całego urządzenia w tym wątku. Domyślne sortowanie mojej bazy danych uparcie odmawia zmiany z „ucs2_bin”, więc próbowałem nawet zmienić wszystkie tabele i sortowanie połączeń na „usc2_bin”, ale nadal otrzymuję błąd „Błąd SQL (1267): Niedozwolona kombinacja sortowań (utf8_general_ci, IMPLICIT) i (ucs2_bin, IMPLICIT) dla operacji '=' ".
bikeman868
15

Powinieneś ustawić zarówno kodowanie tabeli, jak i kodowanie połączenia na UTF-8:

ALTER TABLE keywords CHARACTER SET UTF8; -- run once

i

SET NAMES 'UTF8';
SET CHARACTER SET 'UTF8';
Quassnoi
źródło
Czy oba są potrzebne, czy mogę po prostu wykonać jedną z nich?
Kliknij opcję Głos za głosem
ALTER DATABASE myDb DEFAULT ZESTAW ZNAKÓW utf8 SORTOWANIE utf8_bin. Czy to zadziała? Robi się to tak, aby wpłynęło to na wszystkie moje stoły, a nie tylko na jeden z nich
kliknij Upvote
1
ALTER DATABASE nie zmieni aktualnych ustawień tabeli, tylko nowo utworzone. Jednak zmiana domyślnego zestawu znaków również dla bazy danych nie zaszkodzi.
Quassnoi
SET NAMES i SET CHARACTER SET zmienią kodowanie połączenia. Musisz wydawać te polecenia przy każdym połączeniu. Twoja biblioteka klienta może obsługiwać bardziej elegancką metodę (php :: mysqli tak, php :: mysql nie).
Quassnoi
Wydaje się, że na razie działa, zaakceptuję po kilku dalszych testach. Czy drugie zapytania należy uruchamiać raz, czy na początku każdego skryptu?
Kliknij opcję Głos za głosem
13
CONVERT(column1 USING utf8)

Rozwiązuje mój problem. Gdzie kolumna1 to kolumna, która wyświetla ten błąd.

Binaya Shrestha
źródło
U mnie zadziałało: CONVERT ("column1" USING LATIN1)
shasi kanth
4

Użyj poniższej instrukcji dla błędu

uważaj na swoje dane, wykonaj kopię zapasową, jeśli dane są w tabeli.

 ALTER TABLE twoja_nazwa_tabeli KONWERTUJ NA ZESTAW ZNAKÓW utf8 Sortuj utf8_general_ci;
vpgodara
źródło
2

Ogólnie najlepszym sposobem jest zmiana sortowania tabeli. Jednak mam starą aplikację i nie jestem w stanie oszacować wyniku, czy ma to skutki uboczne. Dlatego próbowałem w jakiś sposób przekonwertować ciąg na inny format, który rozwiązał problem z sortowaniem. To, co znalazłem, to porównanie ciągów poprzez konwersję ciągów na szesnastkową reprezentację jego znaków. W bazie danych można to zrobić za pomocą HEX(column).Dla PHP możesz użyć tej funkcji:

public static function strToHex($string)
{
    $hex = '';
    for ($i=0; $i<strlen($string); $i++){
        $ord = ord($string[$i]);
        $hexCode = dechex($ord);
        $hex .= substr('0'.$hexCode, -2);
    }
    return strToUpper($hex);
}

Podczas wykonywania zapytania do bazy danych, oryginalny łańcuch UTF8 musi najpierw zostać przekonwertowany na ciąg iso (np. Przy użyciu utf8_decode()w PHP) przed użyciem go w bazie danych. Ze względu na typ sortowania baza danych nie może zawierać znaków UTF8 w środku, więc porównanie powinno działać, chociaż powoduje to zmianę oryginalnego ciągu (konwersja znaków UTF8, które nie istnieją w zestawie znaków ISO, powoduje? Lub są one całkowicie usuwane). Po prostu upewnij się, że zapisując dane w bazie danych, używasz tej samej konwersji UTF8 na ISO.

Stephan
źródło
2

Pierwotnie utworzyłem tabelę z CHARSET = latin1 . Po konwersji tabeli na utf8 niektóre kolumny nie zostały przekonwertowane, jednak nie było to do końca oczywiste. Możesz spróbować uruchomić SHOW CREATE TABLE my_table;i zobaczyć, która kolumna nie została przekonwertowana lub po prostu naprawić nieprawidłowy zestaw znaków w problematycznej kolumnie za pomocą poniższego zapytania (zmień długość varchar oraz ZESTAW ZNAKÓW i SORTOWANIE zgodnie z potrzebami):

 ALTER TABLE `my_table` CHANGE `my_column` `my_column` VARCHAR(10) CHARSET utf8 
 COLLATE utf8_general_ci NULL;
Kunin
źródło
2

Zmień zestaw znaków tabeli na utf8

ALTER TABLE twoja_nazwa_tabeli KONWERTUJ NA ZESTAW ZNAKÓW utf8

Jamsheer Mohammed
źródło
0

Po wprowadzeniu poprawek wymienionych w pierwszej odpowiedzi zmień domyślne ustawienia serwera.

W swoim „ /etc/my.cnf.d/server.cnf ” lub gdziekolwiek się znajduje, dodaj wartości domyślne do sekcji [mysqld], aby wyglądało to tak:

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

Źródło: https://dev.mysql.com/doc/refman/5.7/en/charset-applications.html

ITI
źródło
0

Stwierdziłem, że cast()najlepszym rozwiązaniem jest dla mnie używanie :

cast(Format(amount, "Standard") AS CHAR CHARACTER SET utf8) AS Amount

Jest też convert()funkcja. Więcej szczegółów na ten temat tutaj

Kolejny zasób tutaj

Nitin Nanda
źródło
0

Moje konto użytkownika nie miało uprawnień do zmiany bazy danych i tabeli, jak zasugerowano w tym rozwiązaniu .

Jeśli tak jak ja nie obchodzi Cię sortowanie znaków (używasz operatora „=”), możesz zastosować poprawkę odwrotną. Uruchom to przed SELECT:

SET collation_connection = 'latin1_swedish_ci';
pyb
źródło