MySQL导出到输出文件:CSV转义字符

MySQL导出到输出文件:CSV转义字符,mysql,sql,excel,into-outfile,Mysql,Sql,Excel,Into Outfile,我有一个数据库表,里面有一些常见的字段 id, client_id, project_id, task_id, description, time, date 还有很多,但这就是要点 我有一个表上运行的导出到CSV文件一夜之间给用户一个备份他们的数据。它还用作带有一些自定义报告的宏Excel文件的数据导入 这一切都与我的工作循环通过时间表与php和打印行到一个文件 问题在于,大型数据库可能需要数小时才能运行,这是不可接受的。所以我用MySQL将它重写为OUTFILE命令,并将它缩短到几秒钟来

我有一个数据库表,里面有一些常见的字段

id, client_id, project_id, task_id, description, time, date 
还有很多,但这就是要点

我有一个表上运行的导出到CSV文件一夜之间给用户一个备份他们的数据。它还用作带有一些自定义报告的宏Excel文件的数据导入

这一切都与我的工作循环通过时间表与php和打印行到一个文件

问题在于,大型数据库可能需要数小时才能运行,这是不可接受的。所以我用MySQL将它重写为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向导创建的所有奇特宏和透视表


有没有关于最佳行动方案的想法?

如果您尝试以下方法会发生什么

请尝试以下操作,而不是使用双替换语句:

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

此外,我认为应该是以“\r\n”结尾的行,而不是在没有实际查看输出文件以进行确认的情况下,仅以“\n”结尾的行,我的猜测是您必须删除按值转义的字段

MySQL的转义字段的行为可能有两种方式,这两种方式您都不指望:1它只能是一个字符,所以在您的情况下,它可能只等于一个引号;2它用于在MySQL认为需要转义的每个字符之前,包括以值结尾的字段和行。这对大多数计算机世界来说都是有意义的,但这不是Excel的工作方式


我认为您的双重替换是有效的,并且您成功地用空格替换了文字换行符,在Windows样式的换行符中是两个空格。但是,如果您的数据文本中有逗号,而不是字段分隔符,那么前面会有引号,Excel对引号的处理方式与MySQL大不相同。如果是这样的话,那么错误的换行符会使Excel出错,实际上是MySQL打算用作行终止符的换行符。

我认为您的声明应该如下所示:

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
主要是没有由“”转义的字段选项,可选地用“”括起来将对描述字段等起作用,并且您的数字将被视为Excel中的数字,而不是由数字组成的字符串

也可以尝试拨打:

SET NAMES utf8;
在选择输出文件之前,这可能有助于将字符编码内联到所有UTF8中


让我们了解您的进展情况。

可能没有帮助,但您可以尝试创建包含该内容的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 ....
以下是这里的工作原理: 模拟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';
Excel为行分隔符保存\r\n。 Excel为列数据中的换行符保存\n 必须首先替换数据中的\r\n,否则Excel会认为这是下一行的开始。
下面的过程为我解决了所有转义问题,并使该过程更具通用性

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;

结束

是的,这是我现在实际使用的语句,它似乎有效。为了以防万一,我正在替换\n和。如何确切地使用集合名utf8;?dayne,使用集合名称utf8;作为普通查询,就像查询SELECT或UPDATE语句一样,即在mysql命令行中或通过PHP或Ruby或。。。。在您的SELECT语句之前,如果您有文件权限问题,只需像@Felix Z那样写入/tmp,就可以解决任何问题。这是拼图中缺失的部分!可选地用“转义人”括起来,完成了Windows Office样式的转义。谢谢!这是这里唯一一个对我有用的