5

私の質問はここにあるものとほぼ同じです

MySQL - 1300 - 更新時の無効な utf8 文字列

解決策は提示されず、その人の助け (一時テーブルの作成) は役に立たないようでした。私が使用している選択ステートメントは次のとおりです。

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                   |
+-------------------------------+------------------------------+----------------------------------------------------+

次の更新コマンドを実行しようとすると、次のようになります。

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'

次の方法で行を設定しようとしましたが、すべて同じエラーが発生しました。

SET line_1 = CAST(CONVERT(line_1 USING latin1) AS CHAR)
SET line_1 = CONVERT(line_1 USING latin1)

http://jonisalonen.com/2012/fixing-doubly-utf-8-encoded-text-in-mysql/も調べて、二重エンコーディングの問題であるかどうかを確認しましたが、これらのどれも機能せず、取得し続けました同じ文字列エラーです。

さらに、変換手順を支援するためにhttps://mathiasbynens.be/notes/mysql-utf8mb4を調べましたが、utf8mb4 と utf8 がまったく同じ問題を引き起こしています。(最初は utf8 の問題だと思ったので、utf8mb4 に切り替えましたが、それでも同じ問題が発生し続けたとき、より深い問題があることがわかりました)

ご覧のとおり、何か奇妙なことが起こっています。show create address テーブルを見ると、文字セットが適切に設定されていることを確認できます。

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' |

さらに、私のインスタンスでは文字変数が正しいことがわかります。

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)

私はどうやってここに来たのか

そのため、問題の原因が背景にある場合に備えて、問題に関する背景情報を提供することは有益な場合があります。

私は元々、すべてをエンコードする latin1 に設定されていたデータベースを持っていました。次に、次のコードを実行しました。

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

blob に切り替えてから varchar に戻す理由は、通常の推奨手順です。(www.percona.com/blog/2013/10/16/utf8-data-on-latin1-tables-converting-to-utf8-without-downtime-or-double-encoding/)

それが役立つかどうか、また提供できる情報が他にあるかどうか教えてください。私はMySQL 5.6を使用しているので、理論的にはより適切に処理できるはずですが、誰が知っていますか. 4 行しかないので、それぞれを手動で更新できますが、理論的には根本的な問題が大きく、実際にはさらに多くの列を通過する必要があるため、機能的な方法があることを確認することをお勧めします。かなりの数の行で何かを取得した場合に備えて、これらのケースを処理します。

4

1 に答える 1

3

line_1はテキスト フィールドではなく blob であるため、MySQL はその中の「文字」を制御できず、それがテキスト以外の情報 (JPG など) であるかどうかを気にしません。あなたが示した例では、フィールドにlatin1テキストがあります(たとえば、öの16進F6)。したがって、 「正常にCONVERT(line_1 USING latin1)」機能しました。

私はあなたの目標を理解していません。BLOB を TEXT として読み取ろうとしていますか? もしそうなら、そしてすべての非ASCII文字がlatin1でエンコードされているなら、そのCONVERTが答えです。

あなたの目標が何か他のものである場合は、そこからアプローチしましょう。

「二重にエンコード」されていないため、どれも機能しません。

ALTER TABLE addressCONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

aSHOW CREATE TABLE addressを実行し、 の CHARACTER SET を確認しline_1ます。

于 2015-02-24T16:50:03.127 に答える