MySQL转换表到latin1不会将外来字符转换为正确的表示

时间:2015-05-22 17:08:54

标签: mysql utf-8 character-encoding latin1

我有一个数据库,为PHP应用程序提供非英文字符,例如:ç ã é

以前,此数据库已正确存储并显示这些字符,但在备份和恢复后,其中某些字符已被çã组合替换为应显示c

显然,这是一个备份或恢复字符集监督,但是我无法检索以前正常版本的数据库。

此转储文件是数据库的剩余文件,在文本编辑器中打开时,它还会在çã处显示çã之类的组合。

我尝试将其中一个表从utf8_unicode_ci转换为latin1_swedish_ci,反之亦然。但是没有效果。

ALTER TABLE test CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE test CONVERT TO CHARACTER SET latin1 COLLATE latin1_swedish_ci;

如何解决此问题。

谢谢。

注意:来自PHP的 utf8_decode能够将çã转换为ça,但我想在源头解决此问题。

更新:我能够查询受影响的表格,并使用以下查询返回正确的字符。

SELECT convert(cast(convert(field_name using latin1) as binary) using utf8) FROM affectedTable

更新2:

下面的查询能够将字符转换为正确的UTF-8表示。

SELECT convert(cast(convert(field_name using  latin1) as binary) using utf8) FROM affectedTable

因此,按照上一个查询中的方法,如果对每个受影响的表运行以下三个查询,它应该将字符转换为UTF-8。

ALTER TABLE table CONVERT TO CHARACTER SET latin1;
ALTER TABLE table CONVERT TO CHARACTER SET binary;
ALTER TABLE table CONVERT TO CHARACTER SET utf8;

多数民众赞成,çã等字符将转换为ça,依此类推。

这适用于MySQL 5.6.20 - Windows上的社区服务器,它没有使用MySQL 5.5.42 - Linux上的社区服务器。也许有人知道一个跨版本/操作系统解决方案。

2 个答案:

答案 0 :(得分:0)

听起来你的表中的数据存储为latin1,但实际上是utf8。

当'CONVERT TO CHARACTER SET'时,它通常会尝试将字符从'latin1'转换为'utf8'

要在不更改数据的情况下更改类型,您需要先将列转换为二进制列,然后再转换为最终目标字符集,以避免任何实际的字符转换。

这在以下文档中讨论: https://dev.mysql.com/doc/refman/5.5/en/charset-conversion.html

答案 1 :(得分:0)

çãçã的Mojibake。

执行

SELECT col,HEX(col)FROM ... 如果您为C3A7C3A3获得了十六进制çã,那就是utf8编码。但是,如果您看到çã的{​​{1}},则latin1正在进入。如果列声明为col,则表格正常;连接断了。连接时需要CHARACTER SET utf8或等效项。

如果你得到十六进制SET NAMES utf8,你有"双重编码",这是一个不同的解决方案。在完成所有C383C2A7C383C2A3之后,如果你有这个烂摊子,我不会感到惊讶。

" 2步ALTER"使用SET NAMES latin1将utf8字节写入CHARACTER SET latin1列时适用。您的ALTERs显示为çã的症状通常(但并非总是如此)。

çã

(你的三步改变是矫枉过正。)

当INSERTing一个字符串时,3件事对插入的值是好还是坏有所不同。

ALTER TABLE Tbl MODIFY COLUMN col VARBINARY(...) ...;
ALTER TABLE Tbl MODIFY COLUMN col VARCHAR(...) ... CHARACTER SET utf8 ...;