LOAD DATA语法如下(mysql5.6及其以上):
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
[REPLACE | IGNORE]
INTO TABLE tbl_name
[PARTITION (partition_name,...)]
[CHARACTER SET charset_name]
[{FIELDS | COLUMNS}
[TERMINATED BY 'string']
[[OPTIONALLY] ENCLOSED BY 'char']
[ESCAPED BY 'char']
]
[LINES
[STARTING BY 'string']
[TERMINATED BY 'string']
]
[IGNORE number {LINES | ROWS}]
[(col_name_or_user_var,...)]
[SET col_name = expr,...]
3 演示数据准备
3.1 创建测试数据库及表
mysql> create database loaddata;
mysql> use loaddata;
mysql> create table loadtest (c1 int(10), c2 varchar(20), c3 varchar(20), c4 varchar(20));
3.2 插入测试数据
mysql> insert into loadtest values (100, 'column2', 'column3', 'column4');
mysql> insert into loadtest values (200, 'line2', 'line3', 'line4');
3.3 将数据导出
[root@localhost /]# mysqldump --tab=/tmp/ loaddata --fields-terminated-by=',' --fields-optionally-enclosed-by='"' --fields-escaped-by='#' --lines-terminated-by='\n'
查看导出数据文件
[root@localhost /]# cat /tmp/loadtest.txt
100,"column2","column3","column4"
200,"line2","line3","line4"
导入数据过程中忽略(外键约束)可以在LOAD DATA前执行SET foreign_key_checks = 0 。
LINES STARTING BY 'prefix_string':如果所有希望读入的行都含有一个我们希望忽略的共用前缀,则可以使用'prefix_string'来跳过前缀(以及该前缀
前的所有字符)。如果某行不包括前缀,则整个行被跳过
例如:
mysql> LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test LINES STARTING BY "xxx";
假如/tmp/test.txt文件内容如下
xxx"abc",1
something xxx"def",2
"ghi",3
则我们读入的内容包括("abc",1) 和 ("def",2),第三行直接被跳过。
LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test IGNORE 1 LINES;
FIELDS 和 LINES:
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
LINES TERMINATED BY '\n' STARTING BY ''
所有field-或line-handling选项都可以指定一个空字符串('')。如果字符串不是空的,
则FIELDS [OPTIONALLY] ENCLOSED BY和FIELDS ESCAPED BY值必须为单一字符。FIELDS TERMINATED BY, LINES STARTING BY和LINES TERMINATED BY值可以超过一个字符。例如,要编写由回车/换行成对字符作为结尾的行,或读取
"1","a string","100.20"
"2","a string containing a , comma","102.20"
"3","a string containing a \" quote","102.20"
"4","a string containing a \", quote and comma","102.20"
如果我们指定OPTIONALLY,只有string数据类型(如 CHAR, BINARY, TEXT, 或 ENUM)的字段才会被ENCLOSED BY指定的字符包裹,例如:
1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a \" quote",102.20
4,"a string containing a \", quote and comma",102.20
注意,如果在字段值内出现ENCLOSED BY字符,则通过使用ESCAPED BY字符作为前缀,对ENCLOSED BY字符进行转义。另外,要注意,如果指定了一个空ESCAPED BY值,则可能会生成不能被LOAD DATAINFILE正确读取的输出值。例如:
1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a " quote",102.20
4,"a string containing a ", quote and comma",102.20
FIELDS ESCAPED BY:用来控制如何对特殊字符进行读写,如上面一个例子,导出和导入时指定FIELDS ESCAPED BY为双引号["]才能被正确的导入,导出的格式如下,对字段内的双引号["]进行了转义。
1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a #" quote",102.20
4,"a string containing a #", quote and comma",102.20
对于输入:
FIELDS TERMINATED BY '"' ENCLOSED BY '"'
如果FIELDS ESCAPED BY为空,字段值包含FIELDS ENCLOSED BY指定字符,或者LINES TERMINATED BY 的字符在 FIELDS TERMINATED BY 之前,都会导致过早的停止 LOAD DATA INFILE操作。因为LOAD DATA INFILE不能准确的确定行或列的结束。
选择导入的列:
下面的语句会导入文件的所有列
LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;mysql> LOAD DATA INFILE '/tmp/loadtest.txt' INTO TABLE loadtest FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '#' LINES TERMINATED BY '\n' (c1, c2, c4, c3);
列的清单可以包含列名或者用户变量,在写入列前我们需要使用SET语句对用户变量进行转换。对set语句及用户变量有如下使用方法:
mysql> LOAD DATA INFILE '/tmp/loadtest.txt' INTO TABLE loadtest FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '#' LINES TERMINATED BY '\n' (@var1, c2, c3, c4) set c1 = @var1/2;
方法2:把c3列设为当前时间(sql-mode使用严格事物模式STRICT_TRANS_TABLES会报错)
mysql> LOAD DATA INFILE '/tmp/loadtest.txt' INTO TABLE loadtest FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '#' LINES TERMINATED BY '\n' (c1, c2, c4) set c3 = CURRENT_DATE;
方法3:把输入赋予用户变量,而不把用户变量赋予表中的列,来丢弃此输入值。
mysql> LOAD DATA INFILE '/tmp/loadtest.txt' INTO TABLE loadtest FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '#' LINES TERMINATED BY '\n' (@dummy, c2, @dummy, c4);
通过管道导入数据:
在unix系统中,如果我们想要从管道(pipe)中load data,需要用如下方法:mkfifo /tmp/ls.dat
chmod 666 /tmp/ls.dat
find / -ls > /tmp/ls.dat &
[root@localhost tmp]# mysql -e "LOAD DATA INFILE '/tmp/ls.dat' INTO TABLE test.tb1 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' ESCAPED BY '#' LINES TERMINATED BY '\n'"
注意:sql-mode使用严格事物模式STRICT_TRANS_TABLES会报错
[root@localhost /]# cat /tmp/loadtest.txt > /tmp/ls.dat
注:可以先读或者先写管道,谁先谁后都可以,在写入管道的数据被全部读出前,处于阻塞状态。
mysql> LOAD DATA INFILE '/tmp/loadtest.txt' INTO TABLE loadtest FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '#' LINES TERMINATED BY '\n' (c1, c2, c4) set c3 = CURRENT_DATE;
ERROR 1262 (01000): Row 1 was truncated; it contained more data than there were input columns
查看sql_mode
mysql> show variables like '%sql_mode%';
+---------------+--------------------------------------------+
| Variable_name | Value |
+---------------+--------------------------------------------+
| sql_mode | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------+
取消严格事务模式才可导入
set sql_mode='NO_ENGINE_SUBSTITUTION';
6.2 windows上的一些错误
C:\Program Files\MySQL\MySQL Server 5.5\bin>mysqldump -uroot -pactionsky --tab=/tmp/ loaddata --fields-terminated-by=',' --fields-optionally-enclosed-by='"' --fields-escaped-by='#' --lines-terminated-by='\r\n'
mysqldump: Got error: 1083: Field separator argument is not what is expected; check the manual when executing 'SELECT INTO OUTFILE'
mysql5.5.30