1

例如,当我写特殊的 latin1 字符时

á, é ã , ê

到一个 utf-8 编码的 mysql 表,数据会丢失吗?

该表的字符集是 utf-8。

有什么方法可以取回 latin1 编码的行,以便我可以转换为 utf-8 并回写(这次以正确的方式)?

更新

我想我对“数据”的含义并不是很具体。数据是指特殊字符,而不是行。

选择时,我仍然得到行和字段,但带有“?” 而不是特殊的 latin1 字符。有可能恢复那些'?并转换为正确的 utf8 格式?

4

3 回答 3

4

如果整个数据库(或整个表)受到影响,您可以首先验证它是 Latin1-as-UTF8 字符集问题SET NAMES Latin1

mysql> select txt from tbl;
+-----------+
| txt       |
+-----------+
| Québec   |
| Québec   |
+-----------+
2 rows in set (0.00 sec)

mysql> SET NAMES Latin1;
Query OK, 0 rows affected (0.00 sec)

mysql> select txt from tbl;
+---------+
| txt     |
+---------+
| Québec  |
| Québec  |
+---------+
2 rows in set (0.00 sec)

如果这得到验证,即您在使用默认字符集 Latin-1 时获得了所需的数据,那么您可以转储整个表强制--default-character-set=latin1,以便使用正确的数据创建文件,尽管使用错误的字符集规范

但是现在您可以替换标题行说明

/*!40101 SET NAMES latin1 */;

使用 UTF8。重新导入数据库,您就完成了。

如果只有一些行受到影响,那就更困难了:

SELECT txt, CAST(CAST(txt AS CHAR CHARACTER SET Latin1) AS BINARY) AS utf8 FROM tbl;

+-----------+---------+
| txt       | utf8    |
+-----------+---------+
| Québec   | Québec  |
+-----------+---------+
1 row in set (0.00 sec)

...但是您有定位受影响行的问题。您可能会发现一些代码点

WHERE txt LIKE '%Ã%'

但对于其他人,您必须手动采样。

于 2012-10-26T14:40:25.930 回答
3

数据不会丢失。请参阅此 SQLFiddle 示例

于 2012-10-26T12:17:04.457 回答
1

可以使用以下命令找到其他受影响的行:

SELECT column
FROM table
WHERE NOT HEX(column) REGEXP '^([0-7][0-9A-F])*$'
于 2014-01-06T12:34:33.407 回答