Unzulässige Mischung von Kollatierungen MySQL-Fehler


124

Ich erhalte diesen seltsamen Fehler beim Verarbeiten einer großen Anzahl von Daten ...

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 昔 ã‹ã‚‰ ã‚ã‚‹ å ´æ‰€'

Was kann ich tun, um dieses Problem zu beheben? Kann ich der Zeichenfolge irgendwie entkommen, damit dieser Fehler nicht auftritt, oder muss ich meine Tabellencodierung irgendwie ändern, und wenn ja, in was soll ich sie ändern?


Dieser Fehler ist ein injizierbarer oder nicht?
Hamza Irizaj

Antworten:


288
SET collation_connection = 'utf8_general_ci';

dann für Ihre Datenbanken

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 schleicht sich dort manchmal ohne vernünftigen Grund schwedisch ein.


3
@ Ben: Vielen Dank für eine direkt kopierbare Lösung. Hat mir viel Zeit gespart.
Pistos

15
@ Ben: Es wurde ursprünglich von einer schwedischen Firma entwickelt ... Das ist der Grund für die nervige Grundeinstellung latin1_swedish_ci .. :(
Vajk Hermecz

1
Ich hatte keine Erlaubnis, die erste Aussage zu machen, aber es funktionierte nur am Tisch
Rob Sedgwick

Ich liebe dich dafür! : P
prateekkathal

Es sieht so aus, als ob dies für viele Leute funktioniert, aber leider habe ich dieses Problem immer noch, selbst nachdem ich das gesamte Gerät in diesem Thread ausprobiert habe. Die Standardkollatierung meiner Datenbank weigert sich hartnäckig, von 'ucs2_bin' zu wechseln, und hat sogar versucht, alle Tabellen und die Verbindungskollatierung in 'usc2_bin' zu ändern. Es wird jedoch weiterhin der Fehler "SQL-Fehler (1267): Unzulässige Mischung von Kollatierungen (utf8_general_ci, IMPLICIT) und (ucs2_bin, IMPLICIT) für die Operation '=' ".
Bikeman868

15

Sie sollten sowohl Ihre Tabellencodierung als auch Ihre Verbindungscodierung auf Folgendes einstellen UTF-8:

ALTER TABLE keywords CHARACTER SET UTF8; -- run once

und

SET NAMES 'UTF8';
SET CHARACTER SET 'UTF8';

Werden beide benötigt oder kann ich nur einen davon machen?
Klicken Sie auf Upvote

ALTER DATABASE myDbDEFAULT CHARACTER SET utf8 COLLATE utf8_bin. Funktioniert das? Dies geschieht so, dass alle meine Tabellen betroffen sind, nicht nur eine
Klicken Sie auf Upvote

1
ALTER DATABASE ändert Ihre aktuellen Tabelleneinstellungen nicht, sondern nur die neu erstellten. Es schadet jedoch nicht, den Standardzeichensatz auch für die Datenbank zu ändern.
Quassnoi

SET NAMES und SET CHARACTER SET ändern Ihre Verbindungscodierung. Sie müssen diese Befehle jedes Mal ausgeben, wenn Sie eine Verbindung herstellen. Ihre Client-Bibliothek unterstützt möglicherweise eine elegantere Methode (php :: mysqli, php :: mysql nicht).
Quassnoi

Scheint vorerst zu funktionieren, ich werde nach einigen weiteren Tests akzeptieren. Müssen die zweiten Abfragen einmal oder zu Beginn jedes Skripts ausgeführt werden?
Klicken Sie auf Upvote

13
CONVERT(column1 USING utf8)

Löst mein Problem. Wobei Spalte1 die Spalte ist, die mir diesen Fehler gibt.


Für mich hat das funktioniert: CONVERT ("column1" USING LATIN1)
shasi kanth

4

Verwenden Sie die folgende Anweisung für Fehler

Seien Sie vorsichtig, wenn Ihre Daten gesichert werden, wenn die Daten in der Tabelle enthalten sind.

 ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

2

Im Allgemeinen ist es am besten, die Tabellensortierung zu ändern. Ich habe jedoch eine alte Anwendung und kann das Ergebnis nicht wirklich abschätzen, ob dies Nebenwirkungen hat. Deshalb habe ich irgendwie versucht, den String in ein anderes Format zu konvertieren, das das Sortierproblem gelöst hat. Was ich als funktionierend empfunden habe, ist das Vergleichen der Zeichenfolge, indem die Zeichenfolgen in eine hexadezimale Darstellung der Zeichen konvertiert werden. In der Datenbank geschieht dies mit HEX(column).Für PHP können Sie diese Funktion verwenden:

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);
}

Bei der Datenbankabfrage muss Ihre ursprüngliche UTF8-Zeichenfolge zuerst in eine ISO-Zeichenfolge konvertiert werden (z. B. utf8_decode()in PHP), bevor sie in der Datenbank verwendet wird . Aufgrund des Sortierungstyps kann die Datenbank keine UTF8-Zeichen enthalten, sodass der Vergleich funktionieren sollte, obwohl dies die ursprüngliche Zeichenfolge ändert (das Konvertieren von UTF8-Zeichen, die im ISO-Zeichensatz nicht vorhanden sind, führt zu einem? Oder diese werden vollständig entfernt). Stellen Sie einfach sicher, dass Sie beim Schreiben von Daten in die Datenbank dieselbe Konvertierung von UTF8 in ISO verwenden.


2

Ich hatte meine Tabelle ursprünglich mit CHARSET = latin1 erstellt . Nach der Tabellenkonvertierung in utf8 wurden einige Spalten nicht konvertiert, was jedoch nicht wirklich offensichtlich war. Sie können versuchen, auszuführen SHOW CREATE TABLE my_table;und zu sehen, welche Spalte nicht konvertiert wurde, oder einfach den falschen Zeichensatz in der problematischen Spalte mit der folgenden Abfrage korrigieren (ändern Sie die varchar-Länge und CHARSET und COLLATE entsprechend Ihren Anforderungen):

 ALTER TABLE `my_table` CHANGE `my_column` `my_column` VARCHAR(10) CHARSET utf8 
 COLLATE utf8_general_ci NULL;

2

Ändern Sie den Zeichensatz der Tabelle in utf8

ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8


0

Ändern Sie die Standardeinstellungen Ihres Servers, nachdem Sie die in der oberen Antwort aufgeführten Korrekturen vorgenommen haben.

Fügen Sie in Ihrem " /etc/my.cnf.d/server.cnf " oder wo immer es sich befindet, die Standardeinstellungen zum Abschnitt [mysqld] hinzu, damit es so aussieht:

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

Quelle: https://dev.mysql.com/doc/refman/5.7/en/charset-applications.html


0

Ich fand, dass die Verwendung cast()die beste Lösung für mich war:

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

Es gibt auch eine convert()Funktion. Weitere Details dazu hier

Eine weitere Ressource hier


0

Mein Benutzerkonto hatte nicht die Berechtigung, die Datenbank und die Tabelle zu ändern, wie in dieser Lösung vorgeschlagen .

Wenn Sie sich wie ich nicht um die Zeichensortierung kümmern (Sie verwenden den Operator '='), können Sie den umgekehrten Fix anwenden. Führen Sie dies aus, bevor Sie SELECT:

SET collation_connection = 'latin1_swedish_ci';
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.