SELECT ... INTO语句
该SELECT ... INTO形式SELECT使查询结果存储在变量或将其写入文件:
SELECT ... INTO var_list选择列值并将其存储到变量中。SELECT ... INTO OUTFILE将选定的行写入文件。可以指定列和行终止符以生成特定的输出格式。SELECT ... INTO DUMPFILE将单行写入文件而没有任何格式。
给定的SELECT语句最多可以包含一个INTO子句,尽管如SELECT语法说明所示(请参见“ SELECT语句”),该语句INTO可以出现在不同的位置:
之前
FROM。例:SELECT *INTO @myvarFROM t1;在尾随锁定子句之前。例:
SELECT *FROM t1INTO @myvarFOR UPDATE ;在末尾
SELECT。例:SELECT *FROM t1FOR UPDATE INTO @myvar;
从INTOMySQL 8.0.20开始,该语句末尾的位置是受支持的,并且是首选位置。从MySQL 8.0.20开始,不推荐使用locking子句之前的位置,并且它将在以后的MySQL版本中删除对它的支持。换句话说,INTO在FROM但不结束时SELECT会产生警告。
INTO条款不应该在嵌套使用SELECT,因为这样一个SELECT必须将其结果返回到外部环境。INTO内部UNION语句的使用也受到限制;请参见“ UNION子句”。
对于变体:INTO var_list
var_list命名一个或多个变量的列表,每个变量可以是用户定义的变量,存储过程或函数参数或存储程序局部变量。(在准备好的语句中,仅允许用户定义变量;请参见“局部变量的范围和解决方案”。)SELECT ... INTO var_list所选值将分配给变量。变量数必须与列数匹配。查询应返回一行。如果查询不返回任何行,则会出现错误代码1329的警告(
No data),并且变量值保持不变。如果查询返回多行,则会发生错误1172(Result consisted of more than one row)。如果该语句可能检索多行,则可以LIMIT 1用来将结果集限制为单行。SELECT id,data INTO @x, @yFROM test.t1LIMIT 1;
INTO var_list也可以与TABLE语句一起使用,但要遵守以下限制:
- 变量数必须与表中的列数匹配。
- 如果表包含多个行,则必须使用
LIMIT 1将结果集限制为单行。LIMIT 1必须在INTO关键字之前。
这样的语句示例如下所示:
TABLE employeesORDER BY lnameDESC LIMIT 1INTO @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 tINTO @x,@y,@z;SELECT *FROM (VALUES ROW (2,4,8))AS t(a,b,c)INTO @x,@y,@z;
用户变量名称不区分大小写。请参见“用户定义的变量”。
所述的形式的选择的行写入到一个文件中。该文件是在服务器主机上创建的,因此您必须具有使用此语法的特权。不能是现有文件,除其他外,这可以防止修改诸如和数据库表之类的文件。该系统变量控制文件名的解释。SELECT ... INTO OUTFILE 'file_name'SELECTFILEfile_name/etc/passwdcharacter_set_filesystem
该SELECT ... INTO OUTFILE语句旨在启用将表转储到服务器主机上的文本文件的功能。要在其他主机上创建结果文件,SELECT ... INTO OUTFILE通常是不合适的,因为无法使用相对于服务器主机文件系统的文件写入路径,除非可以使用网络访问文件在远程主机上的位置,服务器主机文件系统上的映射路径。
或者,如果将MySQL客户端软件安装在远程主机上,则可以使用客户端命令在该主机上生成文件。mysql -e "SELECT ...">file_name
SELECT ... INTO OUTFILE是的补充LOAD DATA。将列值转换为该CHARACTER SET子句中指定的字符集。如果不存在此类子句,则使用binary字符集转储值。实际上,没有字符集转换。如果结果集包含多个字符集中的列,则输出数据文件也将包含列,并且可能无法正确地重新加载文件。
export_options语句部分的语法由FIELDS与LINES语句一起使用的和子句组成LOAD DATA。有关FIELDS和LINES子句的信息,包括其默认值和允许值,请参见“ LOAD DATA语句”。
FIELDS ESCAPED BY控制如何编写特殊字符。如果FIELDS ESCAPED BY字符不为空,则在必要时使用该字符,以避免在输出时以下字符之前出现歧义:
- 该
FIELDS ESCAPED BY字符 - 该
FIELDS[OPTIONALLY] ENCLOSED BY字符 FIELDS TERMINATED BY和LINES TERMINATED BY值的第一个字符- ASCII
NUL(零值字节;转义字符后实际写的是ASCII0,而不是零值字节)
FIELDS TERMINATED BY,ENCLOSED BY,ESCAPED BY,或LINES TERMINATED BY字符必须进行转义,这样就可以读取可靠的文件恢复。ASCII NUL被转义以使其更易于在某些寻呼机上参见。
生成的文件不需要符合SQL语法,因此不需要进行其他任何转义。
如果FIELDS ESCAPED BY字符为空,则不会转义任何字符并将NULL其输出为NULL,而不是\N。指定一个空的转义字符可能不是一个好主意,特别是如果数据中的字段值包含刚给出的列表中的任何字符时,尤其如此。
INTO OUTFILETABLE当您要将表的所有列转储到文本文件中时,也可以与语句一起使用。在这种情况下,可以使用ORDER BY和来控制行的顺序和数量LIMIT。这些条款必须在前面INTO OUTFILE。TABLE ... INTO OUTFILE支持相同的export_options一样SELECT ... INTO OUTFILE,它是受上写入文件系统相同的限制。这样的语句示例如下所示:
TABLE employeesORDER BY lnameLIMIT 1000INTO 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 tINTO OUTFILE '/tmp/select-values.txt';
您必须使用表别名。列别名也受支持,并且可以选择仅用于从所需列中写入值。您也可以使用支持的任何或所有导出选项SELECT ... INTO OUTFILE来将输出格式化为文件。
这是一个以许多程序使用的逗号分隔值(CSV)格式生成文件的示例:
SELECT a,b,a+bINTO 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也可以与一起使用。请参见“ VALUES语句”。SELECT * FROM(VALUES ROW()[,...])AS table_alias[LIMIT 1]
注意由运行mysqld帐户的操作系统用户创建
INTO OUTFILE或INTO DUMPFILE拥有的任何文件。(由于这个原因和其他原因,您永远不要运行mysqld。)从MySQL 8.0.17开始,用于文件创建的umask为0640;否则,将创建文件。您必须具有足够的访问权限才能操作文件内容。在MySQL 8.0.17之前,umask为0666,服务器主机上的所有用户均可写入该文件。root如果
secure_file_priv系统变量设置为非空目录名称,则要写入的文件必须位于该目录中。
在SELECT ... INTO作为事件计划程序执行的事件的一部分出现的语句的上下文中,诊断消息(不仅错误,而且警告)被写入错误日志,并在Windows上写入应用程序事件日志。有关更多信息,请参见“事件调度程序状态”。
