15.2.9 加载数据语句
LOAD DATA
[LOW_PRIORITY | CONCURRENT] [LOCAL]
INFILE 'file_name'
[REPLACE | IGNORE]
INTO TABLE tbl_name
[PARTITION (partition_name [, 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
[, col_name_or_user_var] ...)]
[SET col_name={expr | DEFAULT}
[, col_name={expr | DEFAULT}] ...]
LOAD DATA 语句从文本文件中快速读取行,并将其写入到表中。文件可以来自服务器主机或客户端主机,取决于是否给出了 LOCAL 修饰符。LOCAL 还影响数据解释和错误处理。
LOAD DATA 是 SELECT ... INTO OUTFILE 的补充。请参阅第15.2.13.1节,“SELECT ... INTO Statement”。要将数据从表中写入到文件中,请使用SELECT ... INTO OUTFILE。要将文件读回表中,请使用LOAD DATA。FIELDS 和 LINES take the same syntax for both statements.
mysqlimport 工具提供了另一种方式来加载数据文件;它通过将LOAD DATA 语句发送到服务器。请参阅第6.5.5节,“mysqlimport — A Data Import Program”。
关于INSERT和LOAD DATA的效率比较,以及加速LOAD DATA的方法,请参阅第10.2.5.1节,“优化INSERT 语句”.
LOCAL 修饰符对LOAD DATA的这些方面产生影响,相比于非 LOCAL 操作:
LOCAL 只能在服务器和客户端都配置了允许它的情况下工作。例如,如果使用mysqld启动时禁用了local_infile系统变量,LOCAL将产生错误。请参阅第8.1.6节,“LOAD DATA LOCAL安全考虑”。
文件名必须作为文字字符串给出。在Windows上,指定路径名中的反斜杠为正斜杠或双反斜杠。服务器使用character_set_filesystem系统变量指示的字符集来解释文件名。
默认情况下,服务器使用character_set_database系统变量指示的字符集来解释文件内容。如果文件内容使用与默认不同的字符集,那么使用CHARACTER SET子句指定该字符集。字符集为binary表示“无转换”。
SET NAMES 和 character_set_client 设置不影响文件内容的解释。
LOAD DATA 将文件中的所有字段解释为具有相同字符集,regardless of the columns into which field values are loaded 的数据类型。为了正确地解释文件,您必须确保它使用了正确的字符集。例如,如果您使用 mysqldump -T 或在 mysql 中执行一个 SELECT ... INTO OUTFILE 语句,确保使用了一个 --default-character-set 选项,以便在文件被 LOAD DATA 加载时使用正确的字符集。
不能加载使用 ucs2、utf16、utf16le 或 utf32 字符集的数据文件。
这些规则确定LOAD DATA输入文件的位置:
-
如果未指定
LOCAL,文件必须位于服务器主机上。服务器直接读取文件,按照以下方式定位:-
如果文件名是绝对路径名,服务器使用它作为给定的。
-
如果文件名是相对路径名且带有leading components,服务器在其数据目录中查找文件。
-
如果文件名没有leading components,服务器在默认数据库的数据库目录中查找文件。
-
-
如果指定了
LOCAL,文件必须位于客户端主机上。客户端程序读取文件,按照以下方式定位:-
如果文件名是绝对路径名,客户端程序使用它作为给定的。
-
如果文件名是相对路径名,客户端程序在其调用目录中查找文件。
当使用
LOCAL时,客户端程序读取文件并将其内容发送到服务器。服务器在临时文件目录中创建文件副本。请参阅第B.3.3.5节,“MySQL存储临时文件的位置”。临时文件目录中缺乏足够空间可以导致LOAD DATA LOCAL语句失败。 -
非LOCAL规则意味着服务器从数据目录中的文件./myfile.txt中读取,而不是从默认数据库的数据库目录中的文件myfile.txt中读取。例如,如果在执行以下LOAD DATA语句时,db1是默认数据库,那么服务器将从db1的数据库目录中读取文件data.txt,即使语句明确地将文件加载到db2数据库中的表中:
LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;
服务器还使用非LOCAL规则来定位IMPORT TABLE语句中的.sdi文件。
安全性要求
对于非LOCAL加载操作,服务器从服务器主机上的文本文件中读取,因此这些安全性要求必须满足:
-
您必须拥有
FILE特权。请参阅第8.2.2节,“MySQL提供的特权”。 -
操作受
secure_file_priv系统变量设置的约束:-
如果变量值是一个非空目录名称,那么文件必须位于该目录中。
-
如果变量值为空(这是不安全的),文件只需要由服务器可读。
-
对于一个LOCAL加载操作,客户端程序从客户端主机上读取文本文件。因为文件内容通过连接由客户端发送到服务器,因此使用LOCAL比服务器直接访问文件慢一些。但是,您不需要FILE权限,文件可以位于客户端程序可访问的任何目录。
REPLACE和IGNORE修饰符控制处理新的(输入)行,这些行在唯一键值上与现有表行重复:PRIMARY KEY或UNIQUE索引值:
-
使用
REPLACE,新的行如果具有与现有行在唯一键值上相同的值,将替换现有行。请参见第15.2.12节,“REPLACE Statement”。 -
使用
IGNORE,新的行如果在唯一键值上与现有行重复,将被忽略。更多信息,请参见The Effect of IGNORE on Statement Execution。
LOCAL修饰符的效果与IGNORE相同。这是因为服务器无法在操作中间停止文件传输。
如果未指定REPLACE、IGNORE或LOCAL,当找到重复键值时将发生错误,并忽略文件的其余部分。
除了对重复键值处理方式的影响外,IGNORE和LOCAL还影响错误处理:
-
如果既没有指定
IGNORE也没有指定LOCAL,数据解释错误将终止操作。 -
如果指定了
IGNORE或LOCAL,数据解释错误将变为警告,并且加载操作将继续,即使SQL模式是限制性的。例如,请参见Column Value Assignment。
要在加载操作中忽略外键约束,执行以下语句:SET foreign_key_checks = 0,然后执行LOAD DATA。
如果您使用LOAD DATA对一个空的MyISAM表,所有非唯一索引将在单独的批次中创建(与REPAIR TABLE相同)。通常,这使得LOAD DATA在您有许多索引时速度更快。在某些极端情况下,您可以通过使用ALTER TABLE ... DISABLE KEYS在加载文件到表之前关闭索引,然后使用ALTER TABLE ... ENABLE KEYS在加载完成后重新创建索引。请参阅第10.2.5.1节,“优化INSERT语句”。
对于LOAD DATA和SELECT ... INTO OUTFILE语句,FIELDS和LINES子句的语法相同。两个子句都是可选的,但如果都指定了,FIELDS必须在LINES之前。
如果您指定了FIELDS子句,每个子句(TERMINATED BY、[OPTIONALLY] ENCLOSED BY和ESCAPED BY)都是可选的,除了您必须指定至少一个之外。这些子句的参数只能包含ASCII字符。
如果您没有指定FIELDS或LINES子句,默认值将是相同的,如果您写入了以下内容:
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
LINES TERMINATED BY '\n' STARTING BY ''
反斜杠(\)在SQL语句中的字符串中是MySQL.escape字符。因此,要指定一个字面上的反斜杠,您必须指定两个反斜杠,以便该值被解释为单个反斜杠。转义序列'\t'和'\n'分别指定制表符和换行符。
换言之,defaults使LOAD DATA在读取输入时按照以下方式操作:
-
在换行符处寻找行边界。
-
不跳过任何行前缀。
-
使用制表符将行分割成字段。
-
不期望字段被包含在任何引号字符中。
-
解释以反斜杠开头的字符为转义序列。例如,
\t、\n和\\分别表示制表符、换行符和反斜杠。请参阅后面的讨论FIELDS ESCAPED BY以获取完整的转义序列列表。
相反,defaults使SELECT ... INTO OUTFILE在写入输出时按照以下方式操作:
-
在字段之间写入制表符。
-
不要在字段中使用任何引号字符。
-
使用
\来转义在字段值中的tab、换行符或\实例。 -
在行尾添加换行符。
对于在Windows系统上生成的文本文件,正确地读取文件可能需要LINES TERMINATED BY '\r\ln',因为Windows程序通常使用两个字符作为行终止符。一些程序,如WordPad,可能在写入文件时使用\r作为行终止符。要读取这些文件,请使用LINES TERMINATED BY '\r'。
如果所有输入行都有一个共同的前缀,您可以使用LINES STARTING BY '来忽略前缀和它之前的任何内容。如果一行不包含前缀,整个行将被忽略。假设您发出以下语句:prefix_string'
LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test
FIELDS TERMINATED BY ',' LINES STARTING BY 'xxx';
如果数据文件看起来像这样:
xxx"abc",1
something xxx"def",2
"ghi",3
结果行是("abc",1)和("def",2)。文件中的第三行被忽略,因为它不包含前缀。
可以使用IGNORE 子句来忽略文件开头的行。例如,您可以使用number LINESIGNORE 1 LINES来跳过包含列名的初始标题行:
LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test IGNORE 1 LINES;
当您使用SELECT ... INTO OUTFILE和LOAD DATA同时将数据库中的数据写入文件,然后在后续读取该文件时,两个语句的字段和行处理选项必须相匹配。否则LOAD DATA将无法正确解释文件内容。假设您使用SELECT ... INTO OUTFILE将文件写入以逗号分隔的字段:
SELECT * INTO OUTFILE 'data.txt'
FIELDS TERMINATED BY ','
FROM table2;
要读取逗号分隔的文件,正确的语句是:
LOAD DATA INFILE 'data.txt' INTO TABLE table2
FIELDS TERMINATED BY ',';
如果您尝试使用以下语句读取文件,它将无法工作,因为它 instructsLOAD DATA寻找tab符之间的字段:
LOAD DATA INFILE 'data.txt' INTO TABLE table2
FIELDS TERMINATED BY '\t';
结果可能是每一行输入将被解释为单个字段。
LOAD DATA可以用来读取来自外部来源的文件。例如,许多程序可以将数据导出到逗号分隔值(CSV)格式中,其中行具有以逗号分隔的字段,并且每个字段都被双引号括起来,第一个行是列名。如果该文件的行以回车符/换行对结尾,那么以下语句展示了您将使用的字段和行处理选项来加载文件:
LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES;
如果输入值不一定包含在引号中,使用OPTIONALLY前缀before the ENCLOSED BY选项。
任何字段或行处理选项都可以指定一个空字符串('').如果不为空,FIELDS [OPTIONALLY] ENCLOSED BY和FIELDS ESCAPED BY值必须是一个单个字符。FIELDS TERMINATED BY、LINES STARTING BY和LINES TERMINATED BY值可以是多个字符。例如,要写入以回车符/换行对结尾的行,或者读取包含这样的行的文件,可以指定一个LINES TERMINATED BY '\r\n'子句。
要读取包含笑话的文件,其中每个笑话由以%%结尾的行分隔,可以这样做:
CREATE TABLE jokes
(a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
joke TEXT NOT NULL);
LOAD DATA INFILE '/tmp/jokes.txt' INTO TABLE jokes
FIELDS TERMINATED BY ''
LINES TERMINATED BY '\n%%\n' (joke);
FIELDS [OPTIONALLY] ENCLOSED BY控制字段的引用。对于输出(SELECT ... INTO OUTFILE),如果省略了OPTIONALLY词,所有字段都将被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"
如果您指定了OPTIONALLY,那么ENCLOSED BY字符只用于将来自字符串数据类型列(例如CHAR、BINARY、TEXT或ENUM)的值:
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字符为前缀来转义。另外,如果您指定了空的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
对于输入,ENCLOSED BY字符,如果存在,将从字段值的两端被删除。无论是否指定OPTIONALLY,OPTIONALLY都不会影响输入解释。出现于ENCLOSED BY字符前面的ESCAPED BY字符将被解释为当前字段值的一部分。
如果字段以ENCLOSED BY字符开始,出现该字符的实例将被识别为终止字段值,只有在跟随着字段或行TERMINATED BY序列时。为了避免歧义,可以将ENCLOSED BY字符中的所有出现都双倍化,并将其解释为单个实例的字符。例如,如果指定了ENCLOSED BY '"',那么引号将被处理如下:
"The ""BIG"" boss" -> The "BIG" boss
The "BIG" boss -> The "BIG" boss
The ""BIG"" boss -> The ""BIG"" boss
FIELDS ESCAPED BY控制如何读取或写入特殊字符:
-
对于输入,如果
FIELDS ESCAPED BY字符不为空,出现该字符将被去除,并且后续的字符将被解释为字段值的一部分。有一些两字符序列是例外,其中第一个字符是转义字符。这些序列在以下表格中显示(使用\表示转义字符)。关于NULL处理的规则将在本节后面描述。Character Escape Sequence \0ASCII NUL( X'00')字符\b退格符(backspace)字符 \n换行(linefeed)字符 \r回车符字符 \t制表符字符。 \ZASCII 26(控制+Z) \NNULL 关于
\-转义语法的更多信息,请见第11.1.1节,“字符串字面量”。如果
FIELDS ESCAPED BY字符为空,转义序列解释不发生。 -
对于输出,如果
FIELDS ESCAPED BY字符非空,则在输出中用于前缀以下字符:-
FIELDS ESCAPED BY字符本身。 -
FIELDS [OPTIONALLY] ENCLOSED BY字符本身。 -
如果
ENCLOSED BY字符为空或未指定,则在输出中用于前缀以下字符: -
ASCII
0(实际写入的内容是ASCII0,而不是一个零值字节)。
如果
FIELDS ESCAPED BY字符为空,則不对任何字符进行转义,并将NULL输出为NULL,而不是\N。指定空 escape 字符可能不是一个好主意,特别是如果您的数据中包含了前面给出的字符列表中的任何字符。 -
在某些情况下,字段和行处理选项会相互影响:
-
如果
LINES TERMINATED BY是一个空字符串,并且FIELDS TERMINATED BY不是空的,那么行也将以FIELDS TERMINATED BY结尾。 -
如果
FIELDS TERMINATED BY和FIELDS ENCLOSED BY值都是空字符串(''),则使用固定行(非分隔)格式。在固定行格式中,不使用字段之间的分隔符,但可以仍然使用行终止符。相反,列值将使用足够宽的字段宽度来读取和写入所有值在该字段中的值。对于TINYINT、SMALLINT、MEDIUMINT、INT和BIGINT,字段宽度分别为4、6、8、11和20,不管声明的显示宽度是什么。LINES TERMINATED BY仍然用于分隔行。如果一行中不包含所有字段,则剩余的列将设置为其默认值。如果您没有行终止符,应该将其设置为''。在这种情况下,文本文件必须包含每行中的所有字段。固定行格式也影响了
NULL值的处理,如后面所述。Note固定大小格式不适用于使用多字节字符集的情况。
处理NULL值的方式取决于使用的FIELDS和LINES选项:
-
对于默认的
FIELDS和LINES值,NULL将被写入为\N字段值,并且一个字段值为\N将被读取为NULL输入(假设ESCAPED BY字符是\)。 -
如果
FIELDS ENCLOSED BY不为空,包含字面值NULL的字段将被读取为NULL值。这与在FIELDS ENCLOSED BY字符中封闭的NULL词不同,该词将被读取为字符串'NULL'。 -
如果
FIELDS ESCAPED BY为空,NULL将被写入为字面值NULL。 -
使用固定行格式(即在
FIELDS TERMINATED BY和FIELDS ENCLOSED BY都为空时)时,NULL将被写入为空字符串。这导致了表中的NULL值和空字符串在文件中无法区分,因为它们都会被写入为空字符串。如果您需要在读取文件时能够区分这两个值,您 shouldn't 使用固定行格式。
将NULL加载到NOT NULL列中时,根据Column Value Assignment规则产生警告或错误。
以下情况不受LOAD DATA支持:
-
固定大小行(
FIELDS TERMINATED BY和FIELDS ENCLOSED BY都为空)和BLOB或TEXT列。 -
如果您指定的分隔符是另一个分隔符的前缀或相同,
LOAD DATA无法正确解释输入。例如,以下FIELDS子句将导致问题:FIELDS TERMINATED BY '"' ENCLOSED BY '"' -
如果
FIELDS ESCAPED BY为空,包含FIELDS ENCLOSED BY或LINES TERMINATED BY后跟FIELDS TERMINATED BY值的字段值将导致LOAD DATA停止读取字段或行太早。这是因为LOAD DATA无法正确确定字段或行值的结尾。
以下示例将加载 persondata 表的所有列:
LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;
默认情况下,如果在 LOAD DATA 语句末尾没有提供列列表,输入行将被期望包含每个表列的字段。如果您想加载某些表的列,请指定列列表:
LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata
(col_name_or_user_var [, col_name_or_user_var] ...);
如果输入文件中的字段顺序与表中的列顺序不同,您也必须指定列列表。否则,MySQL 无法确定如何将输入字段与表列匹配。
在 LOAD DATA 语法中,每个 col_名或_user_var 实例都是列名称或用户变量。使用用户变量,可以在将结果分配给列之前对其值进行预处理转换。
在 SET 子句中使用的用户变量可以用多种方式。以下示例使用输入文件的第一个列直接为 t1.column1 的值,并将第二个输入列分配给一个用户变量,然后对该变量执行除法操作,最后将结果用于 t1.column2 的值:
LOAD DATA INFILE 'file.txt'
INTO TABLE t1
(column1, @var1)
SET column2 = @var1/100;
SET 子句可以用来提供来自输入文件以外的值。以下语句将 column3 设置为当前日期和时间:
LOAD DATA INFILE 'file.txt'
INTO TABLE t1
(column1, column2)
SET column3 = CURRENT_TIMESTAMP;
您也可以丢弃输入值 bằng 将其分配给用户变量,但不将变量分配给任何表列:
LOAD DATA INFILE 'file.txt'
INTO TABLE t1
(column1, @dummy, column2, @dummy, column3);
使用列/变量列表和SET子句的限制如下:
-
在
SET子句中,赋值语句的左侧只能包含列名。 -
您可以在
SET赋值语句的右侧使用子查询。返回要分配给列的值的子查询只能是标量子查询。此外,您不能使用子查询来从正在被加载的表中选择数据。 -
IGNORE子句忽略的行不用于处理列/变量列表或numberLINESSET子句。 -
在使用固定行格式加载数据时,不能使用用户变量,因为用户变量没有显示宽度。
LOAD DATA将输入行分割成字段,并根据列/变量列表和SET子句,如果存在,使用值。然后,将生成的行插入到表中。如果表中有BEFORE INSERT或AFTER INSERT触发器,它们将在插入行之前或之后激活。
字段值的解释和对表列的分配取决于以下因素:
-
SQL 模式(系统变量
sql_模式的值)。该模式可以是非限制性或以多种方式限制。例如,可以启用严格 SQL 模式,也可以包括值,如NO_ZERO_DATE或NO_ZERO_IN_DATE。 -
IGNORE和LOCAL修饰符的存在或缺失。
这些因素组合产生了LOAD DATA对数据的限制性或非限制性解释:
-
如果 SQL 模式是限制性的且未指定
IGNORE或LOCAL修饰符,数据解释将是限制性的。错误终止加载操作。 -
如果 SQL 模式是非限制性的或指定了
IGNORE或LOCAL修饰符,数据解释将是非限制性的。(特别是,如果指定了修饰符且未指定REPLACE修饰符时,它将覆盖限制性 SQL 模式。)错误变为警告,加载操作继续。
限制性数据解释使用以下规则:
-
字段数量太多或太少结果错误。
-
将
NULL(即\N) 分配给非NULL列结果错误。 -
值超出列数据类型范围结果错误。
-
无效值将产生错误。例如,对于数值列的值,如
'x',将导致错误,而不是转换为0。
相比之下,非限制性数据解释使用以下规则:
-
如果输入行有太多字段,额外的字段将被忽略,并且警告次数增加。
-
如果输入行有太少字段,那些缺少输入字段的列将被分配其默认值。默认值分配在第13.6节,“数据类型默认值”中有描述。
-
将
NULL(即\N)分配给非NULL列将导致对该列数据类型的隐式默认值的分配。隐式默认值在第13.6节,“数据类型默认值”中有描述。 -
无效值将产生警告,而不是错误,并且将被转换为该列数据类型的“最近”有效值。示例:
-
对数值列的值,如
'x',将导致转换为0。 -
超出范围的数值或时间值将被截断到该列数据类型的范围端点closest。
-
无效的值将被插入到
DATETIME、DATE或TIME列中,regardless of SQL 模式NO_ZERO_DATE设置。隐含的默认值是适当的“零” 值('0000-00-00 00:00:00'、'0000-00-00'或'00:00:00')。请参阅第13.2节,“日期和时间数据类型”。
-
-
LOAD DATA对空字段值的解释不同于缺少字段:-
对于字符串类型,列将被设置为空字符串。
-
对于数字类型,列将被设置为
0。 -
对于日期和时间类型,列将被设置为适当的“零” 值。请参阅第13.2节,“日期和时间数据类型”。
-
TIMESTAMP 列只有在该列没有指定值(即\N)且该列不允许空值,或者该列的默认值是当前时间戳且未在字段列表中指定时才被设置为当前日期和时间。
LOAD DATA 将所有输入视为字符串,因此不能像使用INSERT语句那样使用数字值来指定ENUM或SET列的值。所有ENUM和SET值都必须指定为字符串。
BIT 值不能直接使用二进制表示法加载(例如,b'011010')。为了解决这个问题,可以使用 SET 子句将前导的 b' 和尾部的 ' 剥离,并对其进行base-2到base-10转换,以便 MySQL 正确地加载值到BIT 列中:
$> cat /tmp/bit_test.txt
b'10'
b'1111111'
$> mysql test
mysql> LOAD DATA INFILE '/tmp/bit_test.txt'
INTO TABLE bit_test (@var1)
SET b = CAST(CONV(MID(@var1, 3, LENGTH(@var1)-3), 2, 10) AS UNSIGNED);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Deleted: 0 Skipped: 0 Warnings: 0
mysql> SELECT BIN(b+0) FROM bit_test;
+----------+
| BIN(b+0) |
+----------+
| 10 |
| 1111111 |
+----------+
2 rows in set (0.00 sec)
对于在 0b 二进制表示法中的BIT 值(例如,0b011010),可以使用以下 SET 子句来剥离前导的 0b:
SET b = CAST(CONV(MID(@var1, 3, LENGTH(@var1)-2), 2, 10) AS UNSIGNED)
LOAD DATA 支持使用 PARTITION 子句指定一个或多个逗号分隔的分区、子分区或两者名称列表。使用该子句时,如果文件中的任何行不能插入到名单中指定的分区或子分区中,该语句将失败,并返回错误Found a row not matching the given partition set。更多信息和示例,请见第26.5节,“Partition Selection”。
使用LOW_RIORITY修饰符,执行LOAD DATA语句将被延迟,直到没有其他客户端正在读取该表。这只影响使用表级锁定的存储引擎(例如MyISAM、MEMORY和MERGE)。
使用CONCURRENT修饰符和一个满足并发插入条件的MyISAM表(即该表中没有中间空块),其他线程可以在执行LOAD DATA语句时从该表中检索数据。这修饰符对LOAD DATA语句的性能产生一些影响,即使没有其他线程正在使用该表。
当LOAD DATA语句完成时,它将返回以下格式的信息字符串:
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
警告在与使用INSERT语句插入值相同的情况下发生(见第15.2.7节,“INSERT 语句”),except that LOAD DATA也会在输入行中字段太少或太多时生成警告。
您可以使用SHOW WARNINGS获取关于错误信息的列表,了解什么地方出错。请参阅第15.7.7.41节,“SHOW WARNINGS Statement”。
如果您使用C API,可以通过调用mysql_info()函数获取关于语句的信息。请参阅mysql_info()。
复制考虑
LOAD 数据 在语句级别复制中被认为是安全的。如果您使用LOAD 数据 和binlog_格式=STATEMENT,那么在应用更改的每个副本上,创建一个临时文件,其中包含数据。这個临时文件,即使源服务器上的二进制日志加密也没有加密。如果需要加密,可以使用行级别或混合二进制日志格式,而不是语句级别格式,因为副本不需要创建临时文件。关于LOAD 数据 和复制的交互,请参阅第19.5.1.19节,“复制和 LOAD 数据”。
在 Unix 上,如果您需要LOAD 数据 从管道中读取,可以使用以下技术(示例将/目录的列表加载到表db1.t1):
mkfifo /mysql/data/db1/ls.dat
chmod 666 /mysql/data/db1/ls.dat
find / -ls > /mysql/data/db1/ls.dat &
mysql -e "LOAD DATA INFILE 'ls.dat' INTO TABLE t1" db1
在这里,您需要运行生成要加载数据的命令和mysql命令,或者在单独的终端窗口中运行数据生成过程(如前一个示例所示)。如果您不这样做,管道将阻塞直到mysql进程读取数据。