MySQL: codage de caractères utilisé par SELECT INTO?

j'essaie d'exporter des données à partir D'une base de données MySQL, mais des choses étranges et merveilleuses arrivent à unicode dans cette table.

je vais me concentrer sur un seul personnage, la gauche smartquote: "

quand j'utilise SELECT à partir de la console, il est imprimé sans problème:

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

cela signifie que les données sont envoyées à mon terminal comme utf-8[0] (ce qui est correct).

cependant, quand j'utilise SELECT * FROM posts INTO OUTFILE '/tmp/x.csv' …; le fichier de sortie est correctement codé:

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

plus Précisément, le est codé avec sept (7!) octets: xc3xa2xe2x82xacxc5x93.

Quel encodage est-ce? Ou comment pourrais-je dire à MySQL d'utiliser un encodage moins déraisonnable?

en outre, quelques faits divers:

  • SELECT @@character_set_database retourne latin1
  • text la colonne est un VARCHAR(42):
  • utf-8, les rendements xe2x80x9c
  • xe2x80x9c décodé comme latin1 puis ré-encodé comme utf-8 les rendements xc3xa2xc2x80xc2x9c (6 octets).
  • un Autre point de données: (utf-8:xe2x80xa6) est codé xc3xa2xe2x82xacxc2xa6

[0]: comme les guillemets intelligents ne sont inclus dans aucun encodage 8 bits, et mon terminal rend correctement les caractères utf-8.

23
demandé sur David Wolever 2012-03-19 08:03:46

8 réponses

de nombreux programmes / normes (y compris MySQL) supposent que "latin1" signifie "cp1252", de sorte que l'octet 0x80 est interprété comme un symbole Euro, ce qui est où \xe2\x82\xac bit (U+20AC) vient du milieu.

quand j'essaie ceci, cela fonctionne correctement (mais notez comment je mets les données, et les variables sur le serveur de base de données):

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)

Et à partir du shell:

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

j'espère qu'il y est une friandise utile...

5
répondu taavi 2012-03-19 19:55:05

Les nouvelles versions de MySQL ont une option pour définir le jeu de caractères dans la clause outfile:

SELECT col1,col2,col3 
FROM table1 
INTO OUTFILE '/tmp/out.txt' 
CHARACTER SET utf8
FIELDS TERMINATED BY ','
23
répondu mvd 2013-02-11 17:46:46

Pour répondre spécifiquement à votre question "qu'est-Ce que cela?", vous avez répondu vous-même:

je soupçonne que c'est parce que "les valeurs de colonne sont évaluées en utilisant le jeu de caractères binaires. En effet, il n'y a pas de conversion de jeu de caractères."- dev.mysql.com/doc/refman/5.0/en/select-into.html

C'est la façon dont MySQL stocke utf8 données codées en interne. C'est une variation terriblement inefficace du stockage Unicode, apparemment en utilisant un total de trois octets pour la plupart des caractères, et ne supporte pas quatre séquences de octets UTF-8.

comment le convertir en UTF-8 réel en utilisant INTO OUTFILE... Je ne sais pas. Utilisation d'autres mysqldump les méthodes le feront cependant.

2
répondu deceze 2012-03-19 05:17:25

comme vous pouvez voir ma base de données MySQL utiliser 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)

chaque fois que j'ai essayé d'exporter la table, j'ai eu un étrange fichier codé CSV. Alors, j'ai mis:

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

comme dans mon exporter script.

alors J'ai une sortie UTF-8 pure.

2
répondu paczor 2012-09-22 11:33:47

j'ai trouvé que cela fonctionne bien.

SELECT convert(col_name USING latin1) FROM posts INTO OUTFILE '/tmp/x.csv' …;
2
répondu dhruvbird 2013-01-28 17:35:34

SET CHARACTER SET <blah> avant votre select, <blah>=utf8 ou latin1 etc... Voir: http://dev.mysql.com/doc/refman/5.6/en/charset-connection.html

Ou SET NAMES utf8; ça pourrait marcher...

1
répondu Hardeep 2012-03-19 06:03:35

vous pouvez exécuter des requêtes MySQL en utilisant L'outil CLI (je crois même avec un format de sortie pour qu'il imprime CSV) et rediriger vers un fichier. Devrait faire la conversion de charset et tout de même vous donner accès à faire jointures, etc.

1
répondu singpolyma 2012-03-19 11:58:34

Vous devez émettre charset utf8 à L'invite MySQL avant d'exécuter le SELECT. Cela indique au serveur sous quoi afficher les résultats.

0
répondu Burhan Khalid 2012-03-19 04:09:50