MySQL的SQL语句 - 数据操作语句(9)- LOAD DATA 语句(2)

列列表规范

以下示例加载 persondata 表的所有列:

1. LOAD DATA INFILE ‘persondata.txt‘ INTO TABLE persondata;

默认情况下,当 LOAD DATA 语句末尾未提供列列表时,输入行应包含表的每个字段。如果只想加载表的某些列,请指定字段列表:

1. LOAD DATA INFILE ‘persondata.txt‘ INTO TABLE persondata
2. (col_name_or_user_var [, col_name_or_user_var] ...);

如果输入文件中字段的顺序与表中列的顺序不同,也必须要指定列列表。否则,MySQL 无法告诉将输入字段与表列匹配。

输入预处理

每个 col_name_or_user_var 值都是列名或用户变量。对于用户变量,SET 子句使您能够在将结果分配给列之前对其值执行预处理转换。

SET 子句中的用户变量可以用多种方式使用。以下示例将第一个输入列直接用于 t1.column1 的值,并将第二个输入列指定给一个用户变量,该变量在用于 t1.column2 之前,要经过除法运算:

1. LOAD DATA INFILE ‘file.txt‘
2.   INTO TABLE t1
3.   (column1, @var1)
4.   SET column2 = @var1/100;

SET 子句可用于提供不是从输入文件派生的值。以下语句将 column3 的值设置为当前日期和时间:

1. LOAD DATA INFILE ‘file.txt‘
2.   INTO TABLE t1
3.   (column1, column2)
4.   SET column3 = CURRENT_TIMESTAMP;

也可以通过将输入值分配给用户变量而不将该变量分配给表列来放弃输入值:

1. LOAD DATA INFILE ‘file.txt‘
2.   INTO TABLE t1
3.   (column1, @dummy, column2, @dummy, column3);

列/变量 列表和 SET 子句的使用受以下限制:

● SET 子句中只有列名能在赋值运算符的左边。

● 可以在 SET 赋值的右侧使用子查询。返回要分配给列的值的子查询只能是标量子查询。此外,不能使用子查询从正在加载的表中进行选择。

● 被 IGNORE 子句忽略的行不会用于对于 列/变量 列表或 SET 子句。

● 加载固定行格式的数据时不能使用用户变量,因为用户变量没有显示宽度。

在处理输入行时,LOAD DATA 会将其拆分为多个字段,并根据 列/变量 列表和 SET 子句(如果存在)使用这些值。然后将结果行插入到表中。如果表有 BEFORE INSERT 或 AFTER INSERT 触发器,则在插入行之前或之后分别激活它们。

如果输入行中的字段太多,则忽略多余的字段并增加警告的数量。

如果输入行的字段太少,则缺少输入字段的表列将设置为其默认值。

空字段值与缺失字段的解析不同:

● 对于字符串类型,列设置为空字符串。

● 对于数字类型,列设置为0。

● 对于日期和时间类型,列设置为该类型的适当“零”值。

如果在 INSERT 或 UPDATE 语句中显式地将空字符串指定给字符类型、数字类型、日期型或时间类型,则会产生相同的值。

如果SQL模式设置为限制性值,则对空字段值或不正确字段值的处理与刚才描述的不同。例如,如果 sql_mode 设置为 TRADITIONAL,将空值或一个值,如 ‘x‘ 转换为数值列的值会导致错误,而不是转换为 0。(使用 LOCAL 或 IGNORE,即使使用限制性的 sql_mode 值,也是出现警告而不是错误,并且插入行时使用与非限制性 SQL 模式相同的最接近值行为。这是因为服务器无法在操作过程中停止文件的传输。)

只有当列的值为 NULL(即,\N)且该列未声明为允许 NULL 值时,或者如果 TIMESTAMP 列的默认值为当前时间戳,并且在指定字段列表时从字段列表中省略,则 TIMESTAMP 列才会设置为当前日期和时间。

LOAD DATA 将所有输入视为字符串,因此不能像 INSERT 语句那样对 ENUM 或 SET 列使用数值。所有 ENUM 和 SET 值都必须指定为字符串。

不能使用二进制表示法直接加载 BIT 值(例如,b‘011010‘)。要解决这个问题,请使用 SET 子句去掉前导 b‘ 和结尾的 ‘ 并执行2进制到10进制的转换,以便 MySQL 将值正确加载到 BIT 列中:

1. shell> cat /tmp/bit_test.txt
2. b‘10‘
3. b‘1111111‘
4. shell> mysql test
5. mysql> LOAD DATA INFILE ‘/tmp/bit_test.txt‘
6.        INTO TABLE bit_test (@var1)
7.        SET b = CAST(CONV(MID(@var1, 3, LENGTH(@var1)-3), 2, 10) AS UNSIGNED);
8. Query OK, 2 rows affected (0.00 sec)
9. Records: 2  Deleted: 0  Skipped: 0  Warnings: 0
10. 
11.mysql> SELECT BIN(b+0) FROM bit_test;
12. +----------+
13. | BIN(b+0) |
14. +----------+
15. | 10       |
16. | 1111111  |
17. +----------+
18. 2 rows in set (0.00 sec)  

对于0b二进制表示法中的 BIT 值(例如0b011010),请使用此 SET 子句来去掉前导的 0b:

1. SET b = CAST(CONV(MID(@var1, 3, LENGTH(@var1)-2), 2, 10) AS UNSIGNED)

语句结果信息

LOAD DATA 语句完成后,将返回以下格式的信息字符串:

1. Records: 1  Deleted: 0  Skipped: 0  Warnings: 0

使用 INSERT 语句插入值警告发生的情况也是相同的,不同的是,当输入行中的字段太少或太多时,LOAD DATA 也会生成警告。

可以使用 SHOW WARNINGS 语句来获取前 max_error_count 个警告的列表,作为出错的信息。

如果使用的是 C API,则可以通过调用 mysql_info() 函数来获取有关语句的信息。

其他主题

在 Unix 上,如果需要使用 LOAD DATA 语句从管道中读取数据,可以使用以下技术(示例将/目录的列表加载到表 db1.t1 中):

1. mkfifo /mysql/data/db1/ls.dat
2. chmod 666 /mysql/data/db1/ls.dat
3. find / -ls > /mysql/data/db1/ls.dat &
4. mysql -e "LOAD DATA INFILE ‘ls.dat‘ INTO TABLE t1" db1

在这个例子中,必须运行命令来生成要加载的数据,mysql 命令必须在一个单独的终端,或后台运行,如果不这样做,管道将阻塞,直到 mysql 进程读取数据。

官方网址:
https://dev.mysql.com/doc/refman/8.0/en/load-data.html

MySQL的SQL语句 - 数据操作语句(9)- LOAD DATA 语句(2)

上一篇:MySQL的SQL语句 - 数据操作语句(5)- IMPORT TABLE 语句


下一篇:sql根据一个表查询的数据作为条件查询另一个表