15.2.13.1 选择...进入语句
SELECT ... INTO 语句的SELECT ... INTO
形式使得查询结果可以存储在变量中或写入到文件中:
-
SELECT ... INTO
从列值中选择值并将其存储到变量中。var_list
-
SELECT ... INTO OUTFILE
将选择的行写入到文件中。可以指定列和行终止符以生成特定的输出格式。 -
SELECT ... INTO DUMPFILE
将单行写入到文件中没有任何格式。
一个给定的SELECT
语句最多只能包含一个INTO
子句,虽然,如SELECT
语法描述所示(见Section 15.2.13, “SELECT 语句”),INTO
可以出现在不同的位置:
-
在
FROM
之前。示例:SELECT * INTO @myvar FROM t1;
-
在锁定子句之前。示例:
SELECT * FROM t1 INTO @myvar FOR UPDATE;
-
在
SELECT
的结尾。示例:SELECT * FROM t1 FOR UPDATE INTO @myvar;
SELECT语句的结尾的INTO
位置是推荐的位置。锁定子句之前的位置已弃用;预计将来版本的MySQL将删除对该位置的支持。在其他字,INTO
在FROM
后面但不是SELECT
的结尾将产生警告。
不应该在嵌套SELECT
中使用INTO
子句,因为嵌套SELECT
必须将结果返回到外部上下文中。还有一些关于在UNION
语句中使用INTO
的限制;见Section 15.2.18, “UNION 子句”。
对于INTO
变体:var_list
-
var_list
是变量列表,其中每个变量可以是用户定义的变量、存储程序或函数参数或存储程序本地变量。在预先编译的SELECT ... INTO
语句中,只允许用户定义的变量;见Section 15.6.4.2, “Local Variable Scope and Resolution”。var_list
-
选择的值将被分配给变量。变量的数量必须与列的数量相匹配。查询应该返回单行。如果查询返回无行,错误代码1329将出现(
No data
),变量的值将保持不变。如果查询返回多行,错误1172将出现(Result consisted of more than one row
)。如果可能的查询可能返回多行,可以使用LIMIT 1
来限制结果集到单行。SELECT id, data INTO @x, @y FROM test.t1 LIMIT 1;
INTO
也可以与var_list
TABLE
语句一起使用,subject to these restrictions:
-
变量的数量必须与表中的列数量相匹配。
-
如果表中包含多行,必须使用
LIMIT 1
来限制结果集到单行。LIMIT 1
必须在INTO
关键字之前。
以下是一个这样的语句的示例:
TABLE employees ORDER BY lname DESC LIMIT 1
INTO @id, @fname, @lname, @hired, @separated, @job_code, @store_id;
您也可以从VALUES
语句中选择值,该语句生成单行并将其分配给用户变量。在这种情况下,您必须使用表别名,并将每个值从值列表分配给变量。以下两个语句是等效的:SET @x=2, @y=4, @z=8
:
SELECT * FROM (VALUES ROW(2,4,8)) AS t INTO @x,@y,@z;
SELECT * FROM (VALUES ROW(2,4,8)) AS t(a,b,c) INTO @x,@y,@z;
用户变量名称不区分大小写。请参阅第11.4节,“用户定义变量”。
以下是SELECT ... INTO OUTFILE '
形式的file_name
'SELECT
语句将选择的行写入到文件中。文件将在服务器主机上创建,因此您必须拥有FILE
权限使用该语句。file_name
不能是现有文件,这些文件包括/etc/passwd和数据库表不能被修改。character_set_filesystem
系统变量控制文件名的解释。
以下是SELECT ... INTO OUTFILE
语句的意图是将表dump到服务器主机上的文本文件上。为了在其他主机上创建结果文件,SELECT ... INTO OUTFILE
通常是不合适的,因为没有办法将文件路径写入到服务器主机文件系统中,除非在服务器主机文件系统中可以访问远程主机文件的网络映射路径。
Alternatively, if the MySQL client software is installed on the remote host, you can use a client command such as mysql -e "SELECT ..." >
to generate the file on that host.file_name
SELECT ... INTO OUTFILE
是 LOAD DATA
的补充。列值将根据 CHARACTER SET
子句指定的字符集进行转换。如果没有该子句,值将使用 binary
字符集。实际上,没有字符集转换。如果结果集包含多个字符集的列,那么输出数据文件也将包含这些字符集,可能无法正确重新加载文件。
语句的 export_options
部分的语法由与 LOAD DATA
语句相同的 FIELDS
和 LINES
子句组成。有关 FIELDS
和 LINES
子句的信息,包括默认值和允许的值,请见 第15.2.9节,“LOAD DATA 语句”。
FIELDS ESCAPED BY
控制如何写入特殊字符。如果 FIELDS ESCAPED BY
字符不为空,它将在必要时用作前缀,以避免歧义:
-
The
FIELDS ESCAPED BY
字符 -
The
FIELDS [OPTIONALLY] ENCLOSED BY
字符 -
The first character of the
FIELDS TERMINATED BY
andLINES TERMINATED BY
values -
ASCII
NUL
(实际写入的字符是 ASCII0
,不是零值字节)
The FIELDS TERMINATED BY
, ENCLOSED BY
, ESCAPED BY
, or LINES TERMINATED BY
字符 必须 被转义,以便可以可靠地读取文件。ASCII NUL
将被转义,以便于使用某些 pager 查看文件。
生成的文件不需要符合 SQL 语法,因此不需要其他转义。
如果 FIELDS ESCAPED BY
字符为空,则不转义任何字符,并将 NULL
输出为 NULL
,而不是 \N
。指定空转义字符可能不是一个好主意,特别是如果字段值包含上述列表中的字符。
INTO OUTFILE
也可以与 TABLE
语句一起使用,以将表中的所有列导出到文本文件。在这种情况下,可以使用 ORDER BY
和 LIMIT
控制行的顺序和数量;这些子句必须在 INTO OUTFILE
之前。TABLE ... INTO OUTFILE
支持与 SELECT ... INTO OUTFILE
相同的 export_options
,并且受同样的文件系统限制。以下是一个示例语句:
TABLE employees ORDER BY lname LIMIT 1000
INTO OUTFILE '/tmp/employee_data_1.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"', ESCAPED BY '\'
LINES TERMINATED BY '\n';
您也可以使用 SELECT ... INTO OUTFILE
与 VALUES
语句将值直接写入到文件中。下面是一个示例:
SELECT * FROM (VALUES ROW(1,2,3),ROW(4,5,6),ROW(7,8,9)) AS t
INTO OUTFILE '/tmp/select-values.txt';
您必须使用表别名;列别名也支持,可以选择性地使用别名来写入从所需列的值。您还可以使用 SELECT ... INTO OUTFILE
支持的任何或所有导出选项来格式化输出到文件中。
以下是一个使用逗号分隔值(CSV)格式的示例,这种格式被许多程序使用:
SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM test_table;
如果您使用 INTO DUMPFILE
而不是 INTO OUTFILE
,MySQL 只将单行写入到文件中,而不进行列或行终止,并且不执行任何转义处理。这对于选择 BLOB
值并将其存储到文件中的情况非常有用。
TABLE
也支持 INTO DUMPFILE
。如果表包含多行,您必须使用 LIMIT 1
来限制输出到单行。 INTO DUMPFILE
也可以与 SELECT * FROM (VALUES ROW()[, ...]) AS
一起使用。请参阅 第15.2.19节,“VALUES 语句”。table_alias
[LIMIT 1]
由 INTO OUTFILE
或 INTO DUMPFILE
创建的任何文件都将由操作系统用户所有,该用户是 mysqld 运行的用户下(您应该 从不 使用 mysqld 作为 root
用户)。文件创建的umask为0640;您必须具有足够的访问权限来操作文件内容。
如果 secure_file_priv
系统变量设置为非空目录名称,那么要写入的文件必须位于该目录中。
在 SELECT ... INTO
语句作为事件执行器执行的事件中,诊断消息(不仅限于错误,还包括警告)将被写入到错误日志中,并且在 Windows 上写入到应用程序事件日志中。有关详细信息,请参阅 第27.4.5节,“Event Scheduler 状态”。
提供了对由 SELECT INTO OUTFILE
和 SELECT INTO DUMPFILE
写入的输出文件的周期性同步支持,可以通过设置select_into_disk_sync
服务器系统变量来启用,该变量在该版本中引入。输出缓冲区大小和可选延迟可以使用,分别使用select_into_buffer_size
和select_into_disk_sync_delay
。更多信息,请参阅这些系统变量的描述。