MySQL - Ungültige utf8mb4 Zeichenkette auf update
Meine Frage ist fast genau der gleiche wie der hier
MySQL - 1300 - Ungültige utf8-Zeichen-string auf update
Keine Lösung präsentiert und die Hilfe, die von der person (erstellen einer temporären Tabelle) schien nicht zu helfen. Hier ist die select-Anweisung, die ich benutze:
SELECT
CONVERT(line_1 USING utf8mb4),
CONVERT(line_1 USING latin1),
HEX(line_1)
FROM address
WHERE ((CAST(CONVERT(line_1 USING latin1) AS CHAR)) <> (CAST(line_1 AS CHAR)))
AND CONVERT(line_1 USING utf8mb4) IS NULL;
+-------------------------------+------------------------------+----------------------------------------------------+
| CONVERT(line_1 USING utf8mb4) | CONVERT(line_1 USING latin1) | hex(line_1) |
+-------------------------------+------------------------------+----------------------------------------------------+
| NULL | Högbergsgatan 97 | 48F6676265726773676174616E203937 |
| NULL | Zücherstrasse 161 | 5AFC636865727374726173736520313631 |
| NULL | 2275, Rue de l'Université | 323237352C20527565206465206C27556E69766572736974E9 |
| NULL | Högbergsgatan 97 | 48F6676265726773676174616E203937 |
+-------------------------------+------------------------------+----------------------------------------------------+
Wenn ich versuche, führen Sie die folgenden update-Befehl, den ich bekommen:
UPDATE address
SET line_1 = CONVERT(CAST(CONVERT(line_1 USING latin1) AS CHAR) USING utf8mb4)
WHERE (CAST(CONVERT(line_1 USING latin1) AS CHAR) <> CAST(line_1 AS CHAR))
AND CONVERT(line_1 USING utf8mb4) IS NULL;
ERROR 1300 (HY000): Invalid utf8mb4 character string: 'F66762'
Ich habe versucht, die Zeile in die folgenden Möglichkeiten, die alle produzieren die gleichen Fehler:
SET line_1 = CAST(CONVERT(line_1 USING latin1) AS CHAR)
SET line_1 = CONVERT(line_1 USING latin1)
Schaute mich auch http://jonisalonen.com/2012/fixing-doubly-utf-8-encoded-text-in-mysql/ um zu sehen, ob vielleicht war es ein Doppel-encoding-Problem, aber keiner von Ihnen gearbeitet, und ich hielt immer den gleichen Zeichen-string-Fehler.
Zusätzlich, schaute ich https://mathiasbynens.be/notes/mysql-utf8mb4, um zu helfen, mit der Umstellung Schritte, aber utf8mb4 und utf-8 sind, was die exakt gleichen Probleme. (Zuerst dachte ich, es war ein utf8-Sache so wechselte ich auf utf8mb4-und wenn ich noch immer die gleichen Probleme, wusste ich, es war ein tiefer liegendes problem)
Wie Sie sehen können, ist etwas seltsames passiert. Ein Blick auf meine Karte erstellen Adressen-Tabelle, die ich überprüfen kann, dass der Zeichensatz richtig eingestellt ist:
SHOW CREATE TABLE address;
| address | CREATE TABLE `address` (
`addressid` bigint(20) NOT NULL AUTO_INCREMENT,
`addressuuid` char(32) COLLATE utf8mb4_unicode_ci NOT NULL,
`line_1` blob,
PRIMARY KEY (`addressid`)
) ENGINE=InnoDB AUTO_INCREMENT=48970 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='All potential addresses' |
Außerdem können Sie sehen, mein char-Variablen sind richtig, in meinem Beispiel:
mysql> show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/|
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
Wie habe ich hier
So könnte es von Vorteil sein zu geben, einige hintergrund-Informationen über das Problem nur für den Fall es ist etwas im hintergrund, die das Problem verursacht.
Hatte ich eine Datenbank, die ursprünglich festgelegt wurde latin1-Codierung alles. Ich lief dann den folgenden code:
SET NAMES 'latin1';
/* We must change things to blob and then back again */
ALTER TABLE `address` CHANGE line_1 line_1 BLOB;
ALTER TABLE `address` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `address` CHANGE line_1 line_1 VARCHAR(64);
Den Grund für den Wechsel in den blob und dann zurück zu varchar ist die normale, empfohlene Vorgehensweise. (www.percona.com/blog/2013/10/16/utf8-data-on-latin1-tables-converting-to-utf8-without-downtime-or-double-encoding/)
Lassen Sie mich wissen, ob das hilft, und wenn es mehr Informationen, die bereitgestellt werden kann. Ich bin mit MySQL 5.6, also theoretisch sollte es Griff die Dinge besser, aber wer weiß. Da es nur 4 Zeilen konnte ich nur manuell aktualisieren jeden, aber theoretisch gibt es eine größere zugrunde liegende Problem und da ich eigentlich schon ein paar mehr Spalten, um durch zu gehen, wäre es schön, sicher, ich habe ein funktionaler Weg, um diese Fälle zu behandeln, falls ich etwas bekommen mit ganz wenigen Linien.
- Beginnen, indem Sie eine
SELECT HEX(col), col ...
so können wir sehen, was in das Feld ein. Was ist das Ziel? Die änderung der Tabelle? Oder einfach nur etwas ähnliches wieHögbergsgatan
? - Ich habe hex in der Tabelle oben. Das Ziel ist es, in der Lage sein, alles zu konvertieren von der alten character encoding in das neue. Aber jede Methode, die ich versuchen scheint es Probleme mit strings nicht in der Lage zu konvertieren/ungültige Zeichenfolgen.
- Haben Sie jemals das richtig? Ich habe das gleiche Problem.
- Also leider nichts schien zu funktionieren richtig, wie einige Dinge wurden doppelt codiert, andere single, und es wurde eine riesige Sauerei. Zum Glück haben unsere Datenbank war nicht zu verrückt zu groß, so landete ich mit der export unserer DB, die ich dann manuell aktualisiert alle falschen Zeichen, die Feste Codierung auf den Tischen, und dann wieder importiert. Hatte noch keine Probleme da, aber es war nicht lustig =/
Du musst angemeldet sein, um einen Kommentar abzugeben.
Seit
line_1
ist ein Fleck, nicht ein Textfeld, MySQL hat keine Kontrolle über die "Zeichen", und nicht Pflege, wenn Sie nicht-text-Informationen (z.B. als JPG). In die Beispiele, die Sie gab, haben Sie latin1 text in das Feld ein (zB hex F6 für ö). DaherCONVERT(line_1 USING latin1)
gearbeitet "fine".Ich verstehe nicht Ihr Ziel. Sind Sie versuchen, zu Lesen das BLOB als TEXT? Wenn dem so ist, und, wenn alle nicht-ascii-Zeichen codiert sind, latin1, dann KONVERTIEREN, dass ist die Antwort.
Wenn Ihr Ziel ist es etwas anderes, dann nähern wir uns von dort aus.
War es nicht "doppelt-codiert", so dass keiner von Ihnen funktionieren würde.
Tun
SHOW CREATE TABLE address
und überprüfen Sie den Zeichensatz derline_1
.