#### 13.2.10.1 SELECT ... INTO 语句

[](<>)[](<>)

这[`选择...进入`](select-into.html)的形式[`选择`](select.html)使查询结果能够存储在变量中或写入文件：

-   `选择 ... 进入 *`var_list`*`选择列值并将它们存储到变量中。

-   `选择...进入文件`将选定的行写入文件。可以指定列和行终止符以产生特定的输出格式。

-   `选择...进入转储文件`将单行写入文件而不进行任何格式化。

    给定的[`选择`](select.html)语句最多可以包含一个`进入`子句，尽管如[`选择`](select.html)语法描述（见[第 13.2.10 节，“SELECT 语句”](select.html)）， 这`进入`可以出现在不同的位置：

-   前`从`.例子：

    ```
    SELECT * INTO @myvar FROM t1;
    ```

-   在尾随锁定子句之前。例子：

    ```
    SELECT * FROM t1 INTO @myvar FOR UPDATE;
    ```

-   在结束时[`选择`](select.html).例子：

    ```
    SELECT * FROM t1 FOR UPDATE INTO @myvar;
    ```

    这`进入`从 MySQL 8.0.20 开始支持语句末尾的位置，并且是首选位置。自 MySQL 8.0.20 起，不推荐使用锁定子句之前的位置；期望在 MySQL 的未来版本中删除对它的支持。换一种说法，`进入`后`从`但不是在结束时[`选择`](select.html)产生警告。

    一个`进入`子句不应在嵌套中使用[`选择`](select.html)因为这样一个[`选择`](select.html)必须将其结果返回到外部上下文。使用也有限制`进入`之内[`联盟`](union.html)陈述；看[第 13.2.10.3 节，“联合条款”](union.html).

    为了`进入 *`var_list`*`变体：

-   *`var_list`*命名一个或多个变量的列表，每个变量可以是用户定义的变量、存储过程或函数参数或存储程序局部变量。（在准备好的`选择 ... 进入 *`var_list`*`语句，只允许用户定义的变量；看[第 13.6.4.2 节，“局部变量范围和解析”](local-variable-scope.html).)

-   选定的值被分配给变量。变量数必须与列数匹配。查询应返回单行。如果查询未返回任何行，则会出现错误代码为 1329 的警告 (`没有数据`)，变量值保持不变。如果查询返回多行，则会出现错误 1172 (`结果包含多于一行`）。如果该语句可能检索多行，您可以使用`限制 1`将结果集限制为单行。

    ```
    SELECT id, data INTO @x, @y FROM test.t1 LIMIT 1;
    ```

[](<>)[](<>)

`进入 *`var_list`*`也可以与[`桌子`](table.html)声明，受以下限制：

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

-   如果表包含多于一行，则必须使用`限制 1`将结果集限制为单行。`限制 1`必须先于`进入`关键词。

    此处显示了此类语句的示例：


```
TABLE employees ORDER BY lname DESC LIMIT 1
    INTO @id, @fname, @lname, @hired, @separated, @job_code, @store_id;
```

[](<>)[](<>)

您还可以从[`价值观`](values.html)将单行生成到一组用户变量中的语句。在这种情况下，您必须使用表别名，并且必须将值列表中的每个值分配给一个变量。这里显示的两个语句中的每一个都等效于[`设置@x=2，@y=4，@z=8`](set-variable.html)：

```
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 节，“用户定义的变量”](user-variables.html).

[](<>)[](<>)

这[`选择 ... 进入 OUTFILE '*`文件名`*'`](select-into.html)的形式[`选择`](select.html)将选定的行写入文件。该文件是在服务器主机上创建的，因此您必须拥有[`文件`](privileges-provided.html#priv_file)使用此语法的特权。*`文件名`*不能是现有文件，除其他外，这会阻止文件，例如`/etc/passwd`和数据库表被修改。这[`字符集文件系统`](server-system-variables.html#sysvar_character_set_filesystem)系统变量控制文件名的解释。

这[`选择...进入文件`](select-into.html)语句旨在启用将表转储到服务器主机上的文本文件。要在其他主机上创建结果文件，[`选择...进入文件`](select-into.html)通常是不合适的，因为没有办法写入相对于服务器主机文件系统的文件路径，除非可以使用服务器主机文件系统上的网络映射路径访问远程主机上文件的位置。

或者，如果远程主机上安装了 MySQL 客户端软件，您可以使用客户端命令，例如`mysql -e "选择..." > *`文件名`*`在该主机上生成文件。

[`选择...进入文件`](select-into.html)是的补码[`加载数据`](load-data.html).列值写入转换为指定的字符集`字符集`条款。如果不存在这样的子句，则使用`二进制`字符集。实际上，没有字符集转换。如果结果集包含多个字符集中的列，则输出数据文件也是如此，并且可能无法正确重新加载文件。

的语法*`出口选项`*该语句的一部分由相同的`领域`和`线`与[`加载数据`](load-data.html)陈述。有关信息`领域`和`线`子句，包括它们的默认值和允许值，请参阅[第 13.2.7 节，“加载数据语句”](load-data.html).

`逃脱的领域`控制如何写入特殊字符。如果`逃脱的领域`字符不为空，在需​​要避免歧义时使用它作为输出中以下字符之前的前缀：

-   这`逃离的田地`性格

-   这个`字段[可选]由`性格

-   第一个字符`以结尾的字段`和`终止于`价值观

-   ASCII码`努尔`（零值字节；转义字符后面实际写的是ASCII。）`0`，而不是零值字节）

    这个`以结尾的字段`,`附上`,`逃过`或`终止于`人物*必须*进行转义，以便可靠地读回文件。ASCII码`努尔`是转义的，以便于使用某些寻呼机查看。

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

    如果`逃离的田地`字符为空，不转义任何字符，并且`无效的`输出为`无效的`不`\N`。指定空转义字符可能不是一个好主意，尤其是当数据中的字段值包含刚刚给出的列表中的任何字符时。

[](<>)

`到外边去`也可以与[`桌子`](table.html)语句将表的所有列转储到文本文件中。在这种情况下，可以使用`订购人`和`限度`; 这些条款必须放在前面`到外边去`. `桌子到外边去`支持同样的观点*`导出选项`*我也是`选择到外边去`，并在写入文件系统时受到相同的限制。以下是此类声明的一个示例：

```
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';
```

你也可以使用`选择到外边去`用一个[`价值观`](values.html)语句将值直接写入文件。此处显示了一个示例：

```
SELECT * FROM (VALUES ROW(1,2,3),ROW(4,5,6),ROW(7,8,9)) AS t
    INTO OUTFILE '/tmp/select-values.txt';
```

必须使用表别名；还支持列别名，并且可以选择仅从所需列写入值。您还可以使用支持的任何或所有导出选项`选择到外边去`将输出格式化为文件。

[](<>)[](<>)

下面是一个示例，它以许多程序使用的逗号分隔值（CSV）格式生成文件：

```
SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM test_table;
```

[](<>)

如果你使用`放入转储文件`而不是`到外边去`，MySQL只向文件中写入一行，没有任何列或行终止，也没有执行任何转义处理。这有助于选择[`斑点`](blob.html)并将其存储在文件中。

[`桌子`](table.html)也支持`放入转储文件`。如果表格包含多行，则还必须使用`限制1`将输出限制为一行。`放入转储文件`也可以用于`从（值行（）[，…]）中选择*作为*`表2-1别名`*[限制1]`看见[第13.2.14节“价值声明”](values.html).

笔记

创建的任何文件`到外边去`或`放入转储文件`由其帐户下的操作系统用户拥有[**mysqld**](mysqld.html)跑。（你应该*从不*跑[**mysqld**](mysqld.html)像`根`由于这个和其他原因。）从MySQL 8.0.17开始，文件创建的umask是0640；您必须有足够的访问权限来操作文件内容。在MySQL 8.0.17之前，umask是0666，该文件可由服务器主机上的所有用户写入。

如果[`安全文件`](server-system-variables.html#sysvar_secure_file_priv)如果系统变量设置为非空目录名，则要写入的文件必须位于该目录中。

在[`选择进入`](select-into.html)作为事件计划程序执行的事件的一部分出现的语句、诊断消息（不仅是错误，还有警告）会写入错误日志，在Windows上还会写入应用程序事件日志。有关更多信息，请参阅[第25.4.5节，“事件调度器状态”](events-status-info.html).

从MySQL 8.0.22开始，支持定期同步用户写入的输出文件`选择输出文件`和`选择到转储文件中`，通过设置[`选择_进入_磁盘_同步`](server-system-variables.html#sysvar_select_into_disk_sync)该版本中引入的服务器系统变量。输出缓冲区大小和可选延迟可分别使用，[`在缓冲区大小中选择`](server-system-variables.html#sysvar_select_into_buffer_size)和[`选择进入磁盘同步延迟`](server-system-variables.html#sysvar_select_into_disk_sync_delay).有关更多信息，请参阅这些系统变量的说明。
