使用source命令会破坏非Unicode文本编码

时间:2017-10-13 13:52:33

标签: mysql windows

我必须将一些包含未编码为Unicode的国家字符的数据导入到独立的 MySQL版本:5.0.18在Windows7 64bit上运行。经过一些初步问题后,我终于在 MySQL 控制台中使用了它。

但由于数据超过50 MByte键入控制台和/或使用剪贴板是不可能的。所以我创建脚本文件只是为了发现导入后国家字符是乱码。

问题是如果我对任何文件使用source命令,编码就会破坏。如果我打开相同的文件并通过剪贴板将内容复制到控制台,所有工作都应该如此。这里最小的 MCVE 来测试这个:

DROP DATABASE IF EXISTS dbs;
CREATE DATABASE dbs;
USE dbs;

SET NAMES latin2;

DROP TABLE IF EXISTS `tab`;
CREATE TABLE `tab` (`ix` INT default 0,`nam` VARCHAR(50) default '' );
INSERT INTO `tab` VALUES
 (1,'aacdeillnoorrstuuyzAACDEILLNOORRSTUUYZ'),
 (2,'áäčďéíĺľňóôŕřšťú ýžÁ ČĎÉÍĹĽŇÓ ŔŘŠŤÚ ÝŽ');
SELECT * FROM `tab`;

当我通过剪贴板将其复制到 MySQL 控制台时,输出如下:

+------+----------------------------------------+
| ix   | nam                                    |
+------+----------------------------------------+
|    1 | aacdeillnoorrstuuyzAACDEILLNOORRSTUUYZ |
|    2 | áäčďéíĺľňóôŕřšťú ýžÁ ČĎÉÍĹĽŇÓ ŔŘŠŤÚ ÝŽ |
+------+----------------------------------------+
2 rows in set (0.00 sec)

哪个是理想的。但是当我将所有这些放入test.sql文件并运行

source test.sql;

我得到了这个输出:

+------+----------------------------------------+
| ix   | nam                                    |
+------+----------------------------------------+
|    1 | aacdeillnoorrstuuyzAACDEILLNOORRSTUUYZ |
|    2 | ßńŔ´ÚÝňż˛ˇ˘Ó°ÜŁ˙ ř×┴ ╚¤╔═┼╝ĎË └ěŐŹ┌ ŢÄ |
+------+----------------------------------------+

这显然是错误的(看起来像一些默认的 MS-DOS charset)。我认为问题不在表格或数据库的一边,因为对于纯文本输出来说这是相同的:

SET NAMES latin2;
SELECT 'áäčďéíĺľňóôŕřšťú ýžÁ ČĎÉÍĹĽŇÓ ŔŘŠŤÚ ÝŽ' AS 'aacdeillnoorrstuuyzAACDEILLNOORRSTUUYZ';

使用剪贴板输出的内容:

+----------------------------------------+
| aacdeillnoorrstuuyzAACDEILLNOORRSTUUYZ |
+----------------------------------------+
| áäčďéíĺľňóôŕřšťú ýžÁ ČĎÉÍĹĽŇÓ ŔŘŠŤÚ ÝŽ |
+----------------------------------------+

使用source文件:

+----------------------------------------+
| aacdeillnoorrstuuyzAACDEILLNOORRSTUUYZ |
+----------------------------------------+
| ßńŔ´ÚÝňż˛ˇ˘Ó°ÜŁ˙ ř×┴ ╚¤╔═┼╝ĎË └ěŐŹ┌ ŢÄ |
+----------------------------------------+

就像从文件导入一样,编码被搞砸了。或者通过键盘剪贴板输入 MySQL 控制台时,编码发生了变化。

那么是怎么回事以及如何纠正这个问题(没有丢失数据)?

  • 使用<命令行选项代替source无效
  • 使用-e的{​​{1}}命令行选项无效
  • 使用默认的charset命令行选项无效
  • 使用 UTF8 非Unicode字符串导致Data too long errors和数据丢失
  • 剪贴板中的数据与文件中的数据相同

[EDIT1]

我尝试了更新版本的 MySQL 5.7.19 ,这需要花费很长时间才能开始,因为他们改变了初始化和事情(wtf?疯狂得到1.8 GByte没有任何数据!)。无论我做什么,它都表现得一样。所以我尝试使用 UTF8 编码:

source

是的,脚本文件转换为 UTF8 。现在这是my.ini设置:

DROP DATABASE IF EXISTS dbs;
CREATE DATABASE dbs CHARACTER SET utf8 COLLATE 'utf8_unicode_ci';
USE dbs;

SET NAMES utf8;

DROP TABLE IF EXISTS `tab`;
CREATE TABLE `tab` (`ix` INT default 0,`nam` VARCHAR(50) default '' ) CHARACTER SET utf8 COLLATE 'utf8_unicode_ci';
INSERT INTO `tab` VALUES
 (1,'áäčďéíĺľňóôŕřšťú ýžÁ ČĎÉÍĹĽŇÓ ŔŘŠŤÚ ÝŽ'),
 (2,'aacdeillnoorrstuuyzAACDEILLNOORRSTUUYZ');
SELECT * FROM `tab`;

#SELECT 'áäčďéíĺľňóôŕřšťú ýžÁ ČĎÉÍĹĽŇÓ ŔŘŠŤÚ ÝŽ' AS 'aacdeillnoorrstuuyzAACDEILLNOORRSTUUYZ';

#SHOW COLLATION;
#SHOW CHARACTER SET;
SHOW VARIABLES LIKE 'char%';

这个最终使用来使用[mysql] default-character-set=utf8 [mysqld] skip-character-set-client-handshake character-set-server=utf8 collation-server=utf8_unicode_ci 这个结果:

source

1 个答案:

答案 0 :(得分:1)

创建表时必须指定CHARACTER SET,最好是在列本身上。否则,您会从SHOW VARIABLES LIKE 'char%';

获得一些默认值

SET NAMES在客户端建立编码。

INSERTingSELECTing时,编码会从客户端的编码(SET NAMES)更改为列(... VARCHAR ... CHARACTER SET ...)。

你真的需要latin2吗?世界正在转向UTF-8。