web-dev-qa-db-fra.com

Exportation MySQL vers le fichier de sortie: caractères d'échappement CSV

J'ai une table de base de données des feuilles de temps avec quelques feilds communs.

id, client_id, project_id, task_id, description, time, date 

Il y en a plus mais c'est l'essentiel.

J'ai une exportation en cours d'exécution sur cette table vers un fichier CSV du jour au lendemain pour donner à l'utilisateur une sauvegarde de leurs données. Il est également utilisé en tant qu'importation de données pour un fichier macro Excel avec certains rapports personnalisés. 

Tout cela fonctionne avec moi en boucle à travers les feuilles de temps avec php et en imprimant les lignes dans un fichier.

Le problème est qu'avec une grosse base de données, l'exécution peut prendre des heures, ce qui n'est pas acceptable. Je l’ai donc réécrit avec la commande MySQL INTO OUTFILE et le réduisait à quelques secondes pour fonctionner, ce qui était super.

Le problème maintenant est que je n'arrive pas à échapper à tous les caractères de la nouvelle ligne, etc., dans le champ de description. En réalité, un utilisateur peut taper n'importe quelle combinaison de caractères ici, y compris les retours à la ligne/les nouvelles lignes.

Ceci est un extrait du code MySQL que j'ai:

SELECT id, 
       client,
       project,
       task,
       REPLACE(REPLACE(ifnull(ts.description,''),'\n',' '),'\r',' ') AS description, 
       time,
       date  
      INTO OUTFILE '/path/to/file.csv'
      FIELDS ESCAPED BY '""'
      TERMINATED BY ',' ENCLOSED BY '"'
      LINES TERMINATED BY '\n'
      FROM ....

Mais...

Lorsque j'essaie de regarder la source du fichier de sortie, il y a toujours des nouvelles lignes dans le fichier. Par conséquent, l'importation CSV pour Excel coupe toutes les macros fantaisie et les tableaux croisés créés par l'assistant Excel. 

Des idées sur un meilleur plan d'action?

39
Derek Organ

Je pense que votre déclaration devrait ressembler à ceci:

SELECT id, 
   client,
   project,
   task,
   description, 
   time,
   date  
  INTO OUTFILE '/path/to/file.csv'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM ts

Principalement sans l'option FIELDS ESCAPED BY '""', OPTIONALLY ENCLOSED BY '"' fera l'affaire pour les champs de description, etc.

Essayez aussi d'appeler:

SET NAMES utf8;

avant que votre fichier de sortie ne soit sélectionné, cela pourrait aider à intégrer les codages de caractères en ligne (tous UTF8)

Fais nous savoir comment tu reussis.

66
Question Mark

Voici ce qui a fonctionné ici: Simulate Excel 2003 (Enregistrer au format CSV)

SELECT 
REPLACE( IFNULL(notes, ''), '\r\n' , '\n' )   AS notes
FROM sometables
INTO OUTFILE '/tmp/test.csv' 
FIELDS TERMINATED BY ',' ENCLOSED BY '"' ESCAPED BY '"'
LINES TERMINATED BY '\r\n';
  1. Excel enregistre\r\n pour les séparateurs de lignes.
  2. Excel enregistre\n pour les caractères de nouvelle ligne dans les données de colonne
  3. Vous devez d'abord remplacer\r\n dans vos données, sinon Excel pensera que c'est un début de ligne.
14
Felix Z

Sans voir votre fichier de sortie pour confirmation, je suppose que vous devez vous débarrasser de la valeur FIELDS ESCAPED BY.

Les champs de MySQL ESCAPED BY se comportent probablement de deux manières sur lesquelles vous ne comptiez pas: (1) il s'agit uniquement d'un caractère, il est donc probablement égal à un guillemet dans votre cas; (2) il est utilisé pour précéder chaque caractère qui, selon MySQL, doit être échappé, y compris les valeurs FIELDS TERMINATED BY et LINES TERMINATED BY. Cela a du sens pour la plupart des environnements informatiques, mais ce n’est pas la façon dont Excel s’échappe.

Je pense que votre double REPLACE fonctionne et que vous remplacez avec succès les nouvelles lignes littérales par des espaces (deux espaces dans le cas des nouvelles lignes de style Windows). Mais si vous avez des virgules dans vos données (littéraux, pas de séparateurs de champs), celles-ci sont précédées de guillemets, qu'Excel traite de manière très différente de MySQL. Si tel est le cas, les nouvelles lignes erronées qui déclenchent Excel sont en fait des nouvelles lignes que MySQL avait prévues comme terminateurs de ligne.

2
John Y

Que se passe-t-il si vous essayez ce qui suit?

Au lieu de votre double déclaration REPLACE, essayez:

REPLACE(IFNULL(ts.description, ''),'\r\n', '\n')

De plus, je pense que cela devrait être LINES TERMINATED BY '\r\n' au lieu de '\n'

2
devuxer

Cela ne vous aidera probablement pas, mais vous pouvez essayer de créer une table CSV avec ce contenu:

DROP TABLE IF EXISTS foo_export;
CREATE TABLE foo_export LIKE foo;
ALTER TABLE foo_export ENGINE=CSV;
INSERT INTO foo_export SELECT id, 
   client,
   project,
   task,
   REPLACE(REPLACE(ifnull(ts.description,''),'\n',' '),'\r',' ') AS description, 
   time,
   date
  FROM ....
0
Jorge Bernal