Character encoding MySQL-更新时utf8mb4字符串无效

Character encoding MySQL-更新时utf8mb4字符串无效,character-encoding,mysql-5.6,utf8mb4,Character Encoding,Mysql 5.6,Utf8mb4,我的问题和这里的几乎完全一样 没有提出解决方案,而且该人员的帮助(创建临时表)似乎没有帮助。下面是我正在使用的select语句: 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 CH

我的问题和这里的几乎完全一样

没有提出解决方案,而且该人员的帮助(创建临时表)似乎没有帮助。下面是我正在使用的select语句:

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                   |
+-------------------------------+------------------------------+----------------------------------------------------+
我还查看了是否可能是双重编码的问题,但这些都不起作用,我不断得到相同的字符串错误

此外,为了帮助完成转换步骤,我查看了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)
我是怎么来到这里的

因此,提供一些关于这个问题的背景信息可能是有益的,以防是背景中的某些东西导致了这个问题

我有一个数据库,最初被设置为拉丁1编码的一切。然后我运行了以下代码:

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-downlight-or-double-encoding/)


让我知道这是否有帮助,如果有任何更多的信息可以提供。我使用的是MySQL 5.6,所以理论上它应该处理得更好,但谁知道呢。因为只有4行,我可以手动更新每一行,但理论上有一个更大的潜在问题,因为我实际上还有很多列要看,最好能确保我有一个功能性的方法来处理这些情况,以防我得到几行内容。

因为
line_1
是一个blob,而不是一个文本字段,MySQL无法控制其中的“字符”,也不关心它是否是非文本信息(如JPG)。在您给出的示例中,字段中有拉丁文1文本(例如,十六进制F6 forö)。因此,
CONVERT(第1行使用拉丁语)
工作“良好”

我不明白你的目标。您正在尝试将BLOB读取为文本吗?如果是这样,并且如果所有非ascii字符都编码为拉丁文1,那么转换就是答案

如果你的目标是别的,那么让我们从那里开始

它不是“双重编码”,所以它们都不起作用

ALTER TABLE
address
转换为字符集utf8mb4 COLLATE utf8mb4\U unicode\U ci


执行
显示创建表地址
并检查
第1行
的字符集

首先执行
选择十六进制(col),col…
,以便查看字段中的内容。目标是什么?换桌子?或者只是拿出类似于Högbergsgatan的东西?我已经在上面的表中添加了十六进制。目标是能够将所有内容从旧的字符编码转换为新的字符编码。但是我尝试的每一种方法似乎都会遇到字符串无法转换/无效字符串的问题。你有没有做对?我也有同样的问题。不幸的是,似乎没有任何东西能正常工作,因为有些东西是双重编码的,另一些是单一编码的,结果变得一团糟。幸运的是,我们的数据库没有太大,所以我不得不导出数据库,然后手动更新所有错误的字符,修复表上的编码,然后重新导入。从那以后就没有遇到过问题,但这并不有趣=/因此最初该字段被设置为VARCHAR(64)。目标是将DB从latin1转换为utf8mb4。因此,我将名称设置为latin1,将字段更改为blob,转换字符集,然后尝试转换回varchar(64)。当我尝试转换回时,出现以下错误:字符串值不正确:'\xF6gberg…'对于第7578行的列“line_1”,当字节与声明不一致时,将使用2步-alter-thru-blob。您可能需要一步转换。(或者这似乎是您现在需要的。)因此,我认为您需要从当前的BLOB中使用拉丁1字节执行3个步骤:设置拉丁1、ALTER to VARCHAR、ALTER CONVERT。比较“修复程序”:
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)
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);