mysql load data infile要求文件在服务器本地且用户有file权限,需指定fields/lines子句处理csv格式,用ignore 1 rows跳过标题,nullif和str_to_date处理空值与日期,并注意字符集为utf8mb4。

LOAD DATA语句的基本写法和必需条件
MySQL的 LOAD DATA INFILE 是真正能批量导入CSV的原生命令,但默认情况下它要求文件在数据库服务器本地磁盘上,且用户需有 FILE 权限。如果你用的是客户端连接远程MySQL(比如本地电脑连云服务器),直接写本地路径会报错 ERROR 13 (HY000): Can't get stat of ... (Errcode: 2) —— 这不是路径写错了,是MySQL根本没权限读你的本地文件。
实操建议:
使用 qbo-mileage CLI 及用户凭证,从 Airtable、Outlook 或 Google Calendar 记录生成 QuickBooks Online 里程 CSV 文件。
- 确认当前用户有
FILE权限:SHOW GRANTS;,没有就找DBA加GRANT FILE ON *.* TO 'user'@'%'; - 把CSV文件先上传到MySQL服务器的某个目录(如
/tmp/或/var/lib/mysql-files/),再在SQL中引用该绝对路径 - 如果用的是MySQL 8.0+,
secure_file_priv可能限制了可读目录,查一下:SHOW VARIABLES LIKE 'secure_file_priv';,只能往这个值指定的路径里放文件
处理CSV字段分隔符、引号与换行符
CSV不是标准格式,不同工具导出的字段包裹方式差异很大:有的用双引号包字符串,有的用单引号;有的字段含换行符,有的用逗号分隔但字段本身也有逗号。MySQL默认按制表符分隔、不识别引号,所以必须显式声明。
常见错误现象:导入后某一行数据“塌陷”进前一行,或字段错位,大概率是换行符没被正确识别。
实操建议:
- 用
FIELDS TERMINATED BY ','明确分隔符(不是默认的\t) - 若字段被双引号包围,加上
OPTIONALLY ENCLOSED BY '"';如果所有字段都强制带引号(包括数字),去掉OPTIONALLY,只写ENCLOSED BY '"' - 若CSV里有真实换行符(比如文本字段含回车),必须指定
LINES TERMINATED BY '\n'(Linux)或'\r\n'(Windows),否则MySQL会把换行当成新记录起点 - 示例完整语句:
LOAD DATA INFILE '/tmp/data.csv' INTO TABLE mytable FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS;
跳过标题行、处理NULL和日期格式
Excel或Python导出的CSV通常第一行是列名,直接导入会导致第一行变成脏数据;另外,空单元格在MySQL里可能被当成空字符串而不是 NULL,日期字段也可能因格式不匹配变成 0000-00-00。
实操建议:
- 用
IGNORE 1 ROWS跳过首行(注意不是SKIP 1,这是常见拼写错误) - 让空字段转成
NULL:在列列表后加SET col_name = NULLIF(col_name, ''),例如:LOAD DATA ... (@col1,@col2) SET name = @col1, created_at = NULLIF(@col2, '') - 日期字段需转换:如果CSV里是
2023-10-05,MySQL能自动识别;但如果是05/10/2023,得用STR_TO_DATE(@col3, '%d/%m/%Y') - 字段顺序必须和表定义一致,除非显式列出列名,例如:
... INTO TABLE mytable (id, name, created_at)
替代方案:当无法用LOAD DATA INFILE时怎么办
很多云数据库(如阿里云RDS、AWS RDS)禁用了 LOAD DATA INFILE,或者你没服务器文件权限。这时候别硬刚,换更实际的方式。
实操建议:
- 用
mysqlimport命令行工具(本质是LOAD DATA的封装),支持--local参数从客户端读文件:mysqlimport --local -u user -p db_name /path/to/data.csv;但服务端需开启local_infile=ON(查SHOW VARIABLES LIKE 'local_infile';) - 用
LOAD DATA LOCAL INFILE(注意多了一个LOCAL),前提是客户端连接时加了--local-infile=1,且MySQL服务端允许(local_infile=ON) - 实在不行,用
INSERT ... VALUES批量拼接(每条语句插1000行),或借助csvsql(from csvkit)生成SQL再执行
最容易被忽略的一点:字符集。如果CSV是UTF-8 with BOM,或者含中文但没声明 CHARACTER SET utf8mb4,导入后全是问号或乱码。务必在语句开头加 CHARACTER SET utf8mb4,并确认表和列也是该字符集。










