Documentation Home
MySQL 8.0 参考手册  / 第 13 章 SQL 语句  / 13.2 数据操作语句  / 13.2.10 SELECT 语句  /  13.2.10.1 SELECT ... INTO 语句

13.2.10.1 SELECT ... INTO 语句

SELECT ... INTO形式SELECT 使查询结果可以存储在变量中或写入文件:

  • SELECT ... INTO var_list选择列值并将它们存储到变量中。

  • SELECT ... INTO OUTFILE将选定的行写入文件。可以指定列和行终止符以生成特定的输出格式。

  • SELECT ... INTO DUMPFILE将单行写入文件,不带任何格式。

一个给定的SELECT语句最多可以包含一个INTO子句,尽管如SELECT语法描述所示(请参阅第 13.2.10 节,“SELECT 语句”),它们 INTO可以出现在不同的位置:

  • 之前FROM。例子:

    SELECT * INTO @myvar FROM t1;
  • 在尾随锁定子句之前。例子:

    SELECT * FROM t1 INTO @myvar FOR UPDATE;
  • 在结束时SELECT。例子:

    SELECT * FROM t1 FOR UPDATE INTO @myvar;

INTO从 MySQL 8.0.20 开始支持语句末尾的位置,并且是首选位置 。从 MySQL 8.0.20 开始,不推荐使用锁定子句之前的位置;希望在未来版本的 MySQL 中删除对它的支持。换句话说,INTOFROM而不是结束时 SELECT会产生警告。

INTO不应在嵌套中使用子句, 因为SELECT这样 的子句SELECT必须将其结果返回到外部上下文。INTOwithin UNION语句的使用也有限制 ;参见 第 13.2.10.3 节,“UNION 子句”

对于变体: INTO var_list

  • var_list命名一个或多个变量的列表,每个变量可以是用户定义的变量、存储过程或函数参数,或存储程序局部变量。(在准备好的 语句中,只允许使用用户定义的变量;请参阅 第 13.6.4.2 节,“局部变量范围和解析”。) SELECT ... INTO 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 语句一起使用,但要遵守以下限制:

  • 变量的数量必须与表中的列数相匹配。

  • 如果表包含多行,则必须使用 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;

用户变量名称不区分大小写。请参阅 第 9.4 节,“用户定义的变量”

将所选行写入文件 的形式 。该文件是在服务器主机上创建的,因此您必须具有使用此语法的权限。不能是现有文件,除其他事项外,这会防止 修改数据库表等文件。系统变量控制文件名的 解释。 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 语句部分的 语法由与语句一起使用的相同FIELDSLINES子句组成LOAD DATA 。有关FIELDSLINES子句的信息,包括它们的默认值和允许值,请参阅第 13.2.7 节,“加载数据语句”

FIELDS ESCAPED BY控制如何写入特殊字符。如果该FIELDS ESCAPED BY 字符不为空,则在必要时将其用作输出中以下字符之前的前缀以避免歧义:

  • FIELDS ESCAPED BY性格 _

  • FIELDS [OPTIONALLY] ENCLOSED BY 性格 _

  • FIELDS TERMINATED BYLINES TERMINATED BY 值 的第一个字符

  • ASCII NUL(零值字节;转义符后面实际写的是 ASCII 0,不是零值字节)

FIELDS TERMINATED BY、或字符必须ENCLOSED BY进行转义,以便您可以可靠地读回文件。ASCII 被转义以使其更易于使用某些寻呼机查看。 ESCAPED BYLINES TERMINATED BYNUL

生成的文件不需要符合 SQL 语法,因此不需要转义任何其他内容。

如果该FIELDS ESCAPED BY字符为空,则不会转义任何字符并NULL输出为NULL,而不是\N。指定一个空的转义字符可能不是一个好主意,尤其是当数据中的字段值包含刚刚给出的列表中的任何字符时。

INTO OUTFILETABLE当您想将表的所有列转储到文本文件中时,也可以与 语句一起使用。在这种情况下,可以使用 ORDER BYand控制行的顺序和数量LIMIT;这些子句必须在 之前INTO OUTFILETABLE ... INTO OUTFILE支持与 export_optionsdoes 相同SELECT ... INTO OUTFILE,并且在写入文件系统时受到相同的限制。此处显示了此类声明的示例:

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 OUTFILEwithVALUES语句将值直接写入文件。此处显示了一个示例:

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 DUMPFILEinstead of INTO OUTFILE,MySQL 只将一行写入文件,没有任何列或行终止,也不执行任何转义处理。这对于选择一个 BLOB值并将其存储在文件中很有用。

TABLE也支持INTO DUMPFILE。如果表包含多行,则还必须使用LIMIT 1将输出限制为单行。INTO DUMPFILE也可以与 一起使用。请参阅 第 13.2.14 节,“VALUES 语句”SELECT * FROM (VALUES ROW()[, ...]) AS table_alias [LIMIT 1]

笔记

由运行mysqld的操作系统用户 创建INTO OUTFILE或 拥有的任何文件 。(出于这个和其他原因,你永远不应该运行mysqld从 MySQL 8.0.17 开始,用于创建文件的 umask 是 0640;您必须具有足够的访问权限才能操作文件内容。在 MySQL 8.0.17 之前,umask 是 0666 并且该文件对服务器主机上的所有用户都是可写的。 INTO DUMPFILEroot

如果secure_file_priv 系统变量设置为非空目录名,则要写入的文件必须位于该目录中。

在作为事件计划程序执行的事件的一部分出现的语句的上下文中 SELECT ... INTO,诊断消息(不仅是错误,还有警告)被写入错误日志,并且在 Windows 上,写入应用程序事件日志。有关其他信息,请参阅第 25.4.5 节,“事件调度器状态”

从 MySQL 8.0.22 开始,支持定期同步由SELECT INTO OUTFILE和写入的输出文件SELECT INTO DUMPFILE,通过设置该 select_into_disk_sync版本中引入的服务器系统变量启用。可以分别使用 select_into_buffer_size和 设置输出缓冲区大小和可选延迟select_into_disk_sync_delay。有关详细信息,请参阅这些系统变量的说明。