不知何故,我的数据库表将我所有的表情符号和外国字符都变成了 Mojibake。我正在尝试通过使用此功能来反转它:
UPDATE table SET user_post = convert(cast(convert(user_post using latin1) as binary) using utf8mb4);
看起来这实际上大部分时间都有效。但我也注意到我的大部分数据都被删除了,我的错误如下:
Invalid utf8 character string: 'FC6265'
我不得不恢复我的数据库表,因为这个函数正在清除我的大量用户帖子,而不仅仅是单个字符。在一个有 500k 个帖子的表上,这可能会对 50k 行产生负面影响。
如果此函数遇到无法正确转换的无效字符,是否有办法防止删除?或者是否有更好的功能将 Mojibake 转换回正确的字符和表情符号?
更新:
我尝试了很多与这篇文章相关的事情:UTF-8 字符的问题;我看到的不是我储存的
根据
HEX
测试,我发现这些字符似乎是“双重编码”的
我尝试使用 CONVERT 方法在测试产品上运行以下查询:
UPDATE table SET description = IFNULL(CONVERT(CONVERT(CONVERT(description USING latin1) USING binary) USING utf8mb4), description );
但是我得到如下错误,然后一半的产品描述被删除/截断:
Warning: #1300 Invalid utf8mb4 character string: 'A02047'
回滚数据库后,我尝试了ALTER方法(这里介绍:http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases)。因为我的专栏已经是 utf8mb4,所以我跳到该指南的第 3 步:
Step 3) ALTER TABLE table MODIFY description LONGTEXT CHARSET latin1;
Step 4) ALTER TABLE table MODIFY description LONGBLOB;
Step 5) ALTER TABLE table MODIFY description LONGTEXT CHARSET utf8mb4;
在第 3 步之后,我得到了一堆这样的错误(但不是每一行):
Warning: #1366 Incorrect string value: '\xE2\x86\x91\xE2\x86\x91...' for column 'description' at row 34882
Warning: #1366 Incorrect string value: '\xE2\x86\x91\xE2\x86\x93...' for column 'description' at row 45270
...
在第 5 步之后,我得到了一堆这样的错误,描述也像 CONVERT 方法一样被截断了:
Warning: #1366 Incorrect string value: '\xA0our m...' for column 'description' at row 20450
Warning: #1366 Incorrect string value: '\xA0</div...' for column 'description' at row 20484
更新#2:
为了清除找到的“A0”,我使用了函数:
UPDATE table SET description = UNHEX(REPLACE(HEX(description), 'A0', ''));
但是我得到了这个错误,结果被截断了:
Warning: #1366 Incorrect string value: '\xC2 GO F...' for column 'description' at row 1
实际存储在数据库中的确切文本是 HTML 格式的字符串。我不确定我在这里发布后您是否能够看到或复制并粘贴“硬空间”:
<p><strong><span style="font-size:22px;"><span style="font-family:Arial, Helvetica, sans-serif;">It is covered by the case. GO FIGURE ???</span></span></strong></p>
我相信“hard space”就在“case.”这个词之后,因为当我运行 REPLACE 查询时,后面的所有内容都会被截断。
你期待
übe
吗? (也许在üben
?)如果是这样,你有这些编码之一cp1250,cp1256,cp1257,dec8,latin1,latin2,latin5,latin7;可能是 latin1.
然而处理期望看到 utf8mb4 或 utf8mb3.
你有可能是 Mojibake 的“对立面”。
也许这行得通?
CONVERT(CONVERT(UNHEX('FC6265') USING latin1) USING utf8mb4)
但我强烈建议先用
SELECT
测试它,而不是UPDATE
。
没有 current UTF-8 字符包括字节十六进制
FC
.
A0
这可能可以去除
A0
垃圾:
UNHEX(REPLACE(HEX(col), 'A0', ''))
(但要准备回滚表。)特别是,它可能会弄乱以这六个字符中的任何一个结尾的行:
*:JZjz
.