Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL导出到输出文件:CSV转义字符_Mysql_Sql_Excel_Into Outfile - Fatal编程技术网

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
语句:

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

另外,我认为它应该是以“\r\n”结尾的
行,而不仅仅是
'\n'

而没有实际查看您的输出文件进行确认,我的猜测是您必须去掉由
值转义的
字段

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


我认为您的双
REPLACE
功能正常,并且您成功地将文字换行符替换为空格(对于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格式)

  • 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;作为一个普通查询(就像在mysql命令行中或通过PHP或Ruby或……)在SELECT语句之前查询SELECT或UPDATE语句一样。如果您有文件权限问题,只需像@Felix Z那样写入/tmp,就可以解决任何问题。
    或者
    是拼图中缺失的一块!
    或者用“.”括起来“逃逸者”“
    帮了我的忙(Windows Office风格的逃逸)。谢谢!这是这里唯一一个对我有效的方法
    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;