MySQL导出到outfile:CSV转义字符

时间:2009-07-13 13:01:42

标签: mysql sql excel into-outfile

我有一个包含一些常见字段的时间表的数据库表。

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

还有更多,但这就是它的要点。

我在该表上运行导出过夜的CSV文件,以便为用户提供其数据的备份。它还用作带有一些自定义报告的宏Excel文件的数据导入。

这一切都与我一起使用php循环遍历时间表并将行打印到文件中。

问题在于大型数据库可能需要数小时才能运行,这是不可接受的。所以我用MySQL INTO OUTFILE命令重写了它,并将它缩短到几秒钟才能运行,这很棒。

现在的问题是我似乎无法在描述字段中转义所有新行字符等。实际上,用户可以在此输入任何字符组合,包括回车/新行。

这是我所拥有的MySQL代码的片段:

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 ....

但是...

当我尝试查看输出文件的来源时,文件中仍然存在换行符,因此Excel的CSV导入会破坏Excel向导创建的所有奇特的宏和数据透视表。

关于最佳行动方案的任何想法?

6 个答案:

答案 0 :(得分:68)

我认为你的陈述应该是这样的:

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

主要没有FIELDS ESCAPED BY '""'选项,OPTIONALLY ENCLOSED BY '"'将为描述字段等提供技巧,您的数字将被视为Excel中的数字(不包括数字的字符串)

也可以尝试致电:

SET NAMES utf8;
在你的outfile选择之前

,这可能有助于内联字符编码(所有UTF8)

告诉我们你是如何上场的。

答案 1 :(得分:14)

以下是有用的: 模拟Excel 2003(另存为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保存\ r \ n用于行分隔符。
  2. Excel为列数据中的换行符保存\ n
  3. 必须首先替换数据中的\ r \ n,否则Excel会认为它是下一行的开头。

答案 2 :(得分:2)

如果您尝试以下操作会发生什么?

请尝试:

,而不是双REPLACE语句
REPLACE(IFNULL(ts.description, ''),'\r\n', '\n')

此外,我认为它应该是LINES TERMINATED BY '\r\n',而不仅仅是'\n'

答案 3 :(得分:2)

如果没有实际看到您的输出文件进行确认,我的猜测是您必须摆脱FIELDS ESCAPED BY值。

MySQL的FIELDS ESCAPED BY可能表现为你没有指望的两种方式:(1)它只是一个字符,所以在你的情况下,它可能只等于一个引号; (2)它用于在MySQL认为需要转义的每个字符之前,包括FIELDS TERMINATED BYLINES TERMINATED BY值。这对大多数计算世界都有意义,但它不是Excel逃脱的方式。

我认为您的双REPLACE正在运行,并且您正在使用空格成功替换文字换行符(在Windows样式换行符的情况下为两个空格)。但是如果你的数据中有任何逗号(文字,而不是字段分隔符),那么这些逗号前面都有引号,这与Excel的处理方式大相径庭。如果是这种情况,那么绊倒Excel的错误新行实际上是MySQL打算作为行终止符的新行。

答案 4 :(得分:0)

可能无济于事,但您可以尝试使用该内容创建CSV表格:

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 ....

答案 5 :(得分:0)

以下过程对我有用,可以解决所有转义问题,并使该过程更通用。

CREATE PROCEDURE `export_table`(
IN tab_name varchar(50), 
IN select_columns varchar(1000),
IN filename varchar(100),
IN where_clause varchar(1000),
IN header_row varchar(2000))

BEGIN
INSERT INTO impl_log_activities(TABLE_NAME, LOG_MESSAGE,CREATED_TS) values(tab_name, where_clause,sysdate());
COMMIT;
SELECT CONCAT( "SELECT ", header_row,
    " UNION ALL ",
    "SELECT ", select_columns, 
    " INTO OUTFILE ", "'",filename,"'"
    " FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' ESCAPED BY '""' ",
    " LINES TERMINATED BY '\n'"
    " FROM ", tab_name, " ",
    (case when where_clause is null then "" else where_clause end)
) INTO @SQL_QUERY;

INSERT INTO impl_log_activities(TABLE_NAME, LOG_MESSAGE,CREATED_TS) values(tab_name, @SQL_QUERY, sysdate());
COMMIT;

PREPARE stmt FROM @SQL_QUERY;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

END