MySQL:SELECT INTO使用的字符编码?

时间:2012-03-19 04:03:47

标签: mysql utf-8 character-encoding

我正在尝试从MySQL数据库中导出一些数据,但是该表中的unicode发生了奇怪而美妙的事情。

我将专注于一个角色,左侧智能引用:“

当我从控制台使用SELECT时,打印时没有问题:

mysql> SELECT text FROM posts;
+-------+
| text  |
+-------+
| “foo” |
+-------+

这意味着数据以utf-8 [0]的形式发送到我的终端(这是正确的)。

但是,当我使用SELECT * FROM posts INTO OUTFILE '/tmp/x.csv' …;时,输出文件正确编码:

$ cat /tmp/x.csv
“fooâ€

具体来说,编码为七(7!)个字节:\xc3\xa2\xe2\x82\xac\xc5\x93

这是什么编码?或者我怎么能告诉MySQL使用不那么不合理的编码呢?

另外,一些其他事实:

  • SELECT @@character_set_database返回latin1
  • text列是VARCHAR(42)
    mysql> DESCRIBE posts;
    +-------+-------------+------+-----+---------+-------+
    | Field | Type        | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | text  | varchar(42) | NO   | MUL |         |       |
    +-------+-------------+------+-----+---------+-------+
    
  • 编码为utf-8的
  • 会产生\xe2\x80\x9c
  • \xe2\x80\x9c解码为latin1,然后重新编码为utf-8,产生\xc3\xa2\xc2\x80\xc2\x9c(6个字节)。
  • 另一个数据点:(utf-8:\xe2\x80\xa6)已编码为\xc3\xa2\xe2\x82\xac\xc2\xa6

[0]:因为智能引号不包含在任何8位编码中,并且我的终端正确呈现utf-8字符。

6 个答案:

答案 0 :(得分:24)

较新版本的MySQL可以选择在outfile子句中设置字符集:

SELECT col1,col2,col3 
FROM table1 
INTO OUTFILE '/tmp/out.txt' 
CHARACTER SET utf8
FIELDS TERMINATED BY ','

答案 1 :(得分:6)

许多程序/标准(包括MySQL)假设“latin1”表示“cp1252”,因此0x80字节被解释为欧元符号,这是\xe2\x82\xac位(U + 20AC)来自的地方中间。

当我尝试这个时,它可以正常工作(但请注意我如何放入数据,以及在数据库服务器上设置的变量):

mysql> set names utf8; -- http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html
mysql> create table sq (c varchar(10)) character set utf8;
mysql> show create table sq\G
*************************** 1. row ***************************
       Table: sq
Create Table: CREATE TABLE `sq` (
  `c` varchar(10) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.19 sec)

mysql> insert into sq values (unhex('E2809C'));
Query OK, 1 row affected (0.00 sec)

mysql> select hex(c), c from sq;
+--------+------+
| hex(c) | c    |
+--------+------+
| E2809C | “  |
+--------+------+
1 row in set (0.00 sec)

mysql> select * from sq into outfile '/tmp/x.csv';
Query OK, 1 row affected (0.02 sec)

mysql> show variables like "%char%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       | 
| character_set_connection | utf8                       | 
| character_set_database   | utf8                       | 
| character_set_filesystem | binary                     | 
| character_set_results    | utf8                       | 
| character_set_server     | latin1                     | 
| character_set_system     | utf8                       | 
| character_sets_dir       | /usr/share/mysql/charsets/ | 
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

从shell开始:

/tmp$ hexdump -C x.csv
00000000  e2 80 9c 0a                                       |....|
00000004

希望那里有一个有用的花絮...

答案 2 :(得分:3)

我发现这很有效。

SELECT convert(col_name USING latin1) FROM posts INTO OUTFILE '/tmp/x.csv' …;

答案 3 :(得分:2)

正如您所见,我的MySQL数据库使用latin1而系统是utf-8

mysql> SHOW VARIABLES LIKE 'character\_set\_%';
+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| character_set_client     | latin1 |
| character_set_connection | latin1 |
| character_set_database   | latin1 |
| character_set_filesystem | binary |
| character_set_results    | latin1 |
| character_set_server     | latin1 |
| character_set_system     | utf8   |
+--------------------------+--------+
7 rows in set (0.00 sec)

每当我尝试导出表格时,我都会得到奇怪的编码CSV文件。 所以,我说:

mysql_query("SET NAMES CP1252");
header('Content-Type: text/csv; charset=cp1252');
header('Content-Disposition: attachment;filename=output.csv');

export script一样。

然后我有纯UTF-8输出。

答案 4 :(得分:1)

您可以使用CLI工具执行MySQL查询(我相信即使使用输出格式,因此它打印出CSV)并重定向到文件。应该进行字符集转换,并仍然允许您访问连接等。

答案 5 :(得分:0)

在运行charset utf8之前,您需要在MySQL提示符处发出SELECT。这告诉服务器将结果输出为。