引言
我们会经常遇到需要将SQL查询结果导出到文件,以便后续的传输或数据分析的场景,为了满足这个需求,Mysql的select语句提供了into子句可以讲查询结果直接导出到文本文件,本文就Mysql中的select ... into
的用法进行演示
SELECT … into语句简介
select ... into
语句不仅仅能够将查询结果导出到csv文件,实际上它有3中用法:
select ... into @var_list from...
: 将查询结果写入到一组变量中
select ... into outfile from ...
: 将数据写入操作系统文件,可以自定义数据格式(分隔符、包裹符、转义符、换行符等)
select ... into dunmpfile from ...
: 将单一行写入文件没有任何格式化
1.1 基本语法
根据官方文挡,into
子句可以出现在以下3个位置,虽然3个位置都符合语法,但select 语句中最多只能有一个into语句(3选1)
查询字段之后,from子句前
锁定字段前
语句最后
这里推荐into子句放在位置3,即语句的末尾,这样相对普通的select语句更为接近,更容易理解
用法示例
查询结果保存到变量
into
子句的一个常用场景就是将查询结果暂时保存到变量中,以便后续查询或使用,唯二要注意的点是变量的数量要和返回列数量匹配,并且最多只能返回一行数据
样例数据
1
2
3
4
5
6
7
8
9
10
11
12CREATE TABLE `t_order` (
`id` int NOT NULL AUTO_INCREMENT,
`order_no` varchar(255) DEFAULT NULL comment '订单编号',
`user_id` varchar(255) DEFAULT NULL comment '下单用户',
`commodity_code` varchar(255) DEFAULT NULL comment '商品编码',
`count` int DEFAULT '0' comment '订单数量',
`amount` double(14,2) DEFAULT '0.00' comment '订单金额',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-- 插入数据
INSERT INTO `t_order` (`id`, `order_no`, `user_id`, `commodity_code`, `count`, `amount`) VALUES (1, 'SP0001', '1', '40301', 100, 99.99);查询3个结果,分别保存到三个变量中
1
2
3
4
5
6
7
8
9
10SELECT commodity_code, user_id, amount FROM t_order LIMIT 1 into @commodity_code,@user_id,@amount;
Query OK, 1 row affected (0.00 sec)
select @commodity_code,@user_id,@amount;
+-----------------+----------+---------+
| @commodity_code | @user_id | @amount |
+-----------------+----------+---------+
| 40301 | 1 | 99.99 |
+-----------------+----------+---------+
1 row in set (0.00 sec)这里用
limit 1
子句限制返回的结果只有1行,否则会报错,而且返回的是3个字段,就需要声明3个变量接收
查询结果保存到文本文件
into outfile
子句可以将查询结果导出到文本文件,虽然不一定是要csv格式,但大多数情况我们都会选择这种格式。
要将Mysql中的数据写入到操作系统的文件中,首先需要具有FILE权限,需要配置安全参数secure_file_priv
,不然就会出现The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
这错误,这个参数是限制Mysql可以写入文件的目录
1 | show variables like 'secure_file_priv'; |
secure_file_priv: 变量用于控制哪些目录可以用于LOAD DATA INFILE
和SELCT ... INTO OUTFILE
语句,如果这个变量被设置为一个特定的目录路径,那只有这个目录下,文件操作才被允许,如果没有设置或者设置为空,这些操作将被禁止,以增加服务器的安全性
修改方式有以下两种:
- 在Mysql配置文件中设置,例如:
1
2[mysqld]
secure_file_priv="/path/to/your/directory" - 在运行时通过管理员权限设置 这里是临时更改
1
SET GLOBAL secure_file_priv = '/path/to/your/directory';
secure_file_priv
的值,服务器重启失效
禁用secure_file_priv
,可以通过设置为空SET GLOBAL secure_file_priv = '';
来完成
在普通的select
语句最后添加into outfile file_name
即可将查询结果写入文件,这里的path就是secure_file_priv
定义的目录
1 | select * from t_order into outfile '/Users/xiaoyuge/Desktop/order.txt'; |
其实into outfile
文件还隐式在文件后面附加了2个子句:
1 | fields terminated by '\t' enclosed by '' escaped by '\\' |
filds
: 表示字段属性terminated by '\t'
:以制表符分割字段enclosed by ''
: 不包裹字段escaped by '\\'
: 反斜杠表示转义符lines
: 表示行属性terminated by '\n'
: 表示换行符starting by ''
:行的起点字符是空
如果要导出CSV格式的文件,并且以双引号”包裹字段,那么只需要增加一个fields terminated by ‘,’ enclosed by ‘“‘子句即可,其他的保持默认;
1 | select * from t_order into outfile '/Users/xiaoyuge/Desktop/order.csv' fields terminated by ',' encolsed by '"'; |
查询结果保存到dumpfile
into dumpfile
子句可以将一行数据导出到文件,但是它不会做任何的分割,格式的定义,转义等操作。相对应用场景较少,这个操作通常用于将大型的BLOB字段保存到文件中,了解即可
1 | -- 注意select语句只能返回一行结果,否则会报错。 |
导出的数据没有任何分隔,都连在了一起,连换行都没