文档首页
MySQL 9.0 参考手册
相关文档 下载此手册

MySQL 9.0 参考手册  /  ...  /  SELECT ... INTO 语句

15.2.13.1 SELECT ... INTO 语句

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

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

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

  • SELECT ... INTO DUMPFILE 将一行写入文件,不进行任何格式化。

给定的 SELECT 语句最多可以包含一个 INTO 子句,尽管如 SELECT 语法描述所示(见 第 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;

在语句末尾使用 INTO 关键字是首选位置。在锁定子句之前的位置已弃用;预计在未来版本的 MySQL 中会删除对它的支持。换句话说,在 FROM 之后但不在 SELECT 语句末尾使用 INTO 关键字会产生警告。

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

对于 INTO var_list 变体

  • var_list 指定一个或多个变量的列表,每个变量可以是用户定义的变量、存储过程或函数参数,或者存储程序局部变量。(在准备好的 SELECT ... INTO var_list 语句中,只允许使用用户定义的变量;请参阅 第 15.6.4.2 节“局部变量的作用域和解析”。)

  • 选定的值将分配给这些变量。变量数量必须与列数匹配。查询应返回单行。如果查询不返回任何行,则会发生带有错误代码 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;

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

SELECT ... INTO OUTFILE 'file_name' 形式的 SELECT 语句将选定的行写入文件。文件是在服务器主机上创建的,因此您必须具有 FILE 权限才能使用此语法。 file_name 不能是现有文件,这在防止诸如 /etc/passwd 之类的文件和数据库表被修改方面起着至关重要的作用。 character_set_filesystem 系统变量控制文件名解释。

SELECT ... INTO OUTFILE 语句旨在支持将表转储到服务器主机上的文本文件。要创建远程主机上的结果文件, SELECT ... INTO OUTFILE 通常不适合,因为没有办法写入相对于服务器主机文件系统的文件路径,除非可以使用服务器主机文件系统上的网络映射路径访问远程主机上的文件位置。

或者,如果 MySQL 客户端软件安装在远程主机上,则可以使用客户端命令(例如 mysql -e "SELECT ..." > file_name)在该主机上生成文件。

SELECT ... INTO OUTFILELOAD DATA 的补充。列值将转换为 CHARACTER SET 子句中指定的字符集。如果不存在此类子句,则使用 binary 字符集转储值。实际上,没有字符集转换。如果结果集包含多个字符集中的列,则输出数据文件也是如此,并且可能无法正确重新加载文件。

语句的 export_options 部分的语法包含与 LOAD DATA 语句一起使用的相同 FIELDSLINES 子句。有关 FIELDSLINES 子句的信息(包括它们的默认值和允许的值),请参阅 第 15.2.9 节“LOAD DATA 语句”

FIELDS ESCAPED BY 控制如何写入特殊字符。如果 FIELDS ESCAPED BY 字符不为空,则在必要时将其用作前缀,以便在输出中位于以下字符之前。

  • FIELDS ESCAPED BY 字符

  • FIELDS [OPTIONALLY] ENCLOSED BY 字符

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

  • ASCII NUL(值为零的字节;实际上在转义字符之后写入的是 ASCII 0,而不是值为零的字节)

FIELDS TERMINATED BYENCLOSED BYESCAPED BYLINES TERMINATED BY 字符 必须转义,以便您可以可靠地读回文件。转义 ASCII NUL 是为了便于使用某些分页器查看。

结果文件不必符合 SQL 语法,因此无需转义其他任何内容。

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

INTO OUTFILE 也可以与 TABLE 语句一起使用,如果您希望将表的全部列转储到文本文件中。在这种情况下,可以使用 ORDER BYLIMIT 控制行的排序和数量;这些子句必须位于 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 OUTFILEVALUES 语句一起使用,将值直接写入文件。以下示例展示了这一点:

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 table_alias [LIMIT 1] 一起使用。请参阅 第 15.2.19 节“VALUES 语句”

注意

INTO OUTFILEINTO DUMPFILE 创建的任何文件都归运行 mysqld 的操作系统用户所有。(出于这个以及其他原因,您 绝不应root 用户身份运行 mysqld。)文件创建的 umask 为 0640;您必须拥有足够的访问权限才能操作文件内容。

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

在事件调度程序执行的事件的一部分中出现的 SELECT ... INTO 语句的上下文中,诊断消息(不仅是错误,还有警告)将写入错误日志,以及(在 Windows 上)应用程序事件日志。有关更多信息,请参阅 第 27.5.5 节“事件调度程序状态”

提供对由 SELECT INTO OUTFILESELECT INTO DUMPFILE 写入的输出文件进行定期同步的支持,这可以通过设置该版本中引入的 select_into_disk_sync 服务器系统变量来启用。可以使用 select_into_buffer_sizeselect_into_disk_sync_delay 分别设置输出缓冲区大小和可选延迟。有关更多信息,请参阅这些系统变量的描述。