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;