#### 13.7.6.1 变量赋值的 SET 语法

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

```
SET variable = expr [, variable = expr] ...

variable: {
    user_var_name
  | param_name
  | local_var_name
  | {GLOBAL | @@GLOBAL.} system_var_name
  | {PERSIST | @@PERSIST.} system_var_name
  | {PERSIST_ONLY | @@PERSIST_ONLY.} system_var_name
  | [SESSION | @@SESSION. | @@] system_var_name
}
```

[`放`](set-variable.html)变量赋值语法使您可以将值分配给影响服务器或客户端操作的不同类型的变量：

-   用户定义的变量。看[第 9.4 节，“用户定义的变量”](user-variables.html).

-   存储过程和函数参数，以及存储的程序局部变量。看[第 13.6.4 节，“存储程序中的变量”](stored-program-variables.html).

-   系统变量。看[第 5.1.8 节，“服务器系统变量”](server-system-variables.html).系统变量也可以在服务器启动时设置，如中所述[第 5.1.9 节，“使用系统变量”](using-system-variables.html).

    一种[`放`](set-variable.html)分配变量值的语句不会写入二进制日志，因此在复制方案中它只影响执行它的主机。要影响所有复制主机，请在每个主机上执行该语句。

    以下部分描述[`放`](set-variable.html)设置变量的语法。他们使用[`=`](assignment-operators.html#operator_assign-equal)赋值运算符，但[`:=`](assignment-operators.html#operator_assign-value)为此也允许赋值运算符。

-   [用户定义的变量赋值](set-variable.html#set-variable-user-variables)

-   [参数和局部变量赋值](set-variable.html#set-variable-parameters-local-variables)

-   [系统变量赋值](set-variable.html#set-variable-system-variables)

-   [SET 错误处理](set-variable.html#set-variable-error-handling)

-   [多变量赋值](set-variable.html#set-variable-multiple-assignments)

-   [表达式中的系统变量引用](set-variable.html#variable-references-in-expressions)

##### 用户定义的变量赋值

用户定义的变量在会话中本地创建，并且仅存在于该会话的上下文中；看[第 9.4 节，“用户定义的变量”](user-variables.html).

用户定义的变量写为`@*`变量名`*`并被分配如下表达式值：

```
SET @var_name = expr;
```

例子：

```
SET @name = 43;
SET @total_tax = (SELECT SUM(tax) FROM taxable_transactions);
```

正如这些陈述所表明的，*`表达式`*范围可以从简单（文字值）到更复杂（标量子查询返回的值）。

性能模式[`user_variables_by_thread`](performance-schema-user-variable-tables.html)表包含有关用户定义变量的信息。看[第 27.12.10 节，“性能模式用户定义的变量表”](performance-schema-user-variable-tables.html).

##### 参数和局部变量赋值

[`放`](set-variable.html)适用于定义它们的存储对象的上下文中的参数和局部变量。以下过程使用`增量`过程参数和`柜台`局部变量：

```
CREATE PROCEDURE p(increment INT)
BEGIN
  DECLARE counter INT DEFAULT 0;
  WHILE counter < 10 DO
    -- ... do work ...
    SET counter = counter + increment;
  END WHILE;
END;
```

##### 系统变量赋值

MySQL 服务器维护配置其操作的系统变量。系统变量可以具有影响整个服务器操作的全局值、影响当前会话的会话值，或两者兼而有之。许多系统变量是动态的，可以在运行时使用[`放`](set-variable.html)语句来影响当前服务器实例的操作。[`放`](set-variable.html)也可用于将某些系统变量持久化到`mysqld-auto.cnf`数据目录中的文件，以影响后续启动的服务器操作。

如果您更改会话系统变量，则该值在您的会话中保持有效，直到您将变量更改为不同的值或会话结束。更改对其他会话没有影响。

如果您更改全局系统变量，该值将被记住并用于初始化新会话的会话值，直到您将变量更改为不同的值或服务器退出。访问全局值的任何客户端都可以看到更改。但是，更改仅影响更改后连接的客户端的相应会话值。全局变量更改不会影响任何当前客户端会话的会话值（甚至不会影响发生全局值更改的会话）。

要使全局系统变量设置永久化以便它在服务器重新启动时应用，您可以将其持久化到`mysqld-auto.cnf`数据目录中的文件。也可以通过手动修改`我的.cnf`选项文件，但这更麻烦，而且手动输入的设置中的错误可能要到很久以后才会发现。[`放`](set-variable.html)持久化系统变量的语句更方便，并且避免了错误设置的可能性，因为带有语法错误的设置不会成功并且不会更改服务器配置。有关持久化系统变量和`mysqld-auto.cnf`文件，见[第 5.1.9.3 节，“持久系统变量”](persisted-system-variables.html).

笔记

设置或保留全局系统变量值始终需要特殊权限。设置会话系统变量值通常不需要特殊权限，任何用户都可以完成，但也有例外。有关详细信息，请参阅[第 5.1.9.1 节，“系统变量权限”](system-variable-privileges.html).

以下讨论描述了用于设置和持久化系统变量的语法选项：

-   要将值分配给全局系统变量，请在变量名称前加上`全球的`关键字或`@@全球的。`限定词：

    ```
    SET GLOBAL max_connections = 1000;
    SET @@GLOBAL.max_connections = 1000;
    ```

-   要将值分配给会话系统变量，请在变量名称前加上`会议`要么`当地的`关键字，由`@@会议。`,`@@当地的。`， 要么`@@`限定符，或者根本没有关键字或没有修饰符：

    ```
    SET SESSION sql_mode = 'TRADITIONAL';
    SET LOCAL sql_mode = 'TRADITIONAL';
    SET @@SESSION.sql_mode = 'TRADITIONAL';
    SET @@LOCAL.sql_mode = 'TRADITIONAL';
    SET @@sql_mode = 'TRADITIONAL';
    SET sql_mode = 'TRADITIONAL';
    ```

    客户端可以更改自己的会话变量，但不能更改任何其他客户端的会话变量。

-   将全局系统变量持久化到`mysqld-auto.cnf`数据目录中的选项文件，变量名前加`坚持`关键字或`@@坚持。`限定词：

    ```
    SET PERSIST max_connections = 1000;
    SET @@PERSIST.max_connections = 1000;
    ```

    这[`放`](set-variable.html)语法使您能够在运行时进行配置更改，这些更改也会在服务器重新启动时保持不变。喜欢[`设置全球`](set-variable.html),[`设置坚持`](set-variable.html)设置全局变量运行时值，但也将变量设置写入`mysqld-auto.cnf`文件（如果有，则替换任何现有的变量设置）。

-   将全局系统变量持久化到`mysqld-auto.cnf`没有设置全局变量运行时值的文件，在变量名前面加上`PERSIST_ONLY`关键字或`@@PERSIST_ONLY。`限定词：

    ```
    SET PERSIST_ONLY back_log = 100;
    SET @@PERSIST_ONLY.back_log = 100;
    ```

    喜欢`坚持`,`PERSIST_ONLY`将变量设置写入`mysqld-auto.cnf`.然而，不同于`坚持`,`PERSIST_ONLY`不修改全局变量运行时值。这使得`PERSIST_ONLY`适用于配置只能在服务器启动时设置的只读系统变量。

    要将全局系统变量值设置为已编译的 MySQL 默认值或将会话系统变量设置为当前对应的全局值，请将变量设置为该值`默认`.例如下面两条语句在设置会话值时是相同的[`max_join_size`](server-system-variables.html#sysvar_max_join_size)到当前的全局值：


```
SET @@SESSION.max_join_size = DEFAULT;
SET @@SESSION.max_join_size = @@GLOBAL.max_join_size;
```

使用[`放`](set-variable.html)将全局系统变量持久化为`默认`或为其文字默认值分配其默认值，并将变量的设置添加到`mysqld-auto.cnf`.要从文件中删除变量，请使用[`重置坚持`](reset-persist.html).

一些系统变量不能被持久化或被持久化限制。看[第 5.1.9.4 节，“不可持久和受限的系统变量”](nonpersistible-system-variables.html).

插件实现的系统变量如果在[`放`](set-variable.html)语句被执行。如果插件仍然安装，则持久化插件变量的分配将在后续服务器重新启动时生效。如果不再安装插件，则服务器读取插件时插件变量不再存在`mysqld-auto.cnf`文件。在这种情况下，服务器将警告写入错误日志并继续：

```
currently unknown variable 'var_name'
was read from the persisted config file
```

要显示系统变量名称和值：

-   使用[`显示变量`](show-variables.html)陈述;看[第 13.7.7.41 节，“显示变量语句”](show-variables.html).

-   几个性能模式表提供系统变量信息。看[第 27.12.14 节，“性能模式系统变量表”](performance-schema-system-variable-tables.html).

-   性能模式[`变量信息`](performance-schema-variables-info-table.html)表包含显示每个系统变量最近设置的时间和用户的信息。看[第 27.12.14.2 节，“性能模式变量\_信息表”](performance-schema-variables-info-table.html).

-   性能模式[`持久变量`](performance-schema-persisted-variables-table.html)表提供了一个 SQL 接口`mysqld-auto.cnf`文件，使其内容能够在运行时使用[`选择`](select.html)陈述。看[第 27.12.14.1 节，“性能模式持续存在\_变量表”](performance-schema-persisted-variables-table.html).

##### SET 错误处理

如果一个变量赋值[`放`](set-variable.html)语句失败，整个语句失败并且没有变量被改变，也不是`mysqld-auto.cnf`文件已更改。

[`放`](set-variable.html)在此处描述的情况下会产生错误。大多数例子显示[`放`](set-variable.html)使用关键字语法的语句（例如，`全球的`要么`会议`)，但这些原则也适用于使用相应修饰符的语句（例如，`@@全球的。`要么`@@会议。`）。

-   用于[`放`](set-variable.html)（任何变体）设置只读变量：

    ```
    mysql> SET GLOBAL version = 'abc';
    ERROR 1238 (HY000): Variable 'version' is a read only variable
    ```

-   用于`全球的`,`坚持`， 要么`PERSIST_ONLY`设置一个只有会话值的变量：

    ```
    mysql> SET GLOBAL sql_log_bin = ON;
    ERROR 1228 (HY000): Variable 'sql_log_bin' is a SESSION
    variable and can't be used with SET GLOBAL
    ```

-   用于`会议`设置一个只有全局值的变量：

    ```
    mysql> SET SESSION max_connections = 1000;
    ERROR 1229 (HY000): Variable 'max_connections' is a
    GLOBAL variable and should be set with SET GLOBAL
    ```

-   遗漏`全球的`,`坚持`， 要么`PERSIST_ONLY`设置一个只有全局值的变量：

    ```
    mysql> SET max_connections = 1000;
    ERROR 1229 (HY000): Variable 'max_connections' is a
    GLOBAL variable and should be set with SET GLOBAL
    ```

-   用于`坚持`要么`PERSIST_ONLY`设置一个不能持久化的变量：

    ```
    mysql> SET PERSIST port = 3307;
    ERROR 1238 (HY000): Variable 'port' is a read only variable
    mysql> SET PERSIST_ONLY port = 3307;
    ERROR 1238 (HY000): Variable 'port' is a non persistent read only variable
    ```

-   这`@@全球的。`,`@@坚持。`,`@@PERSIST_ONLY。`,`@@会议。`， 和`@@`修饰符仅适用于系统变量。尝试将它们应用于用户定义的变量、存储过程或函数参数或存储的程序局部变量时会发生错误。

-   并非所有系统变量都可以设置为`默认`.在这种情况下，分配`默认`导致错误。

-   尝试分配时发生错误`默认`到用户定义的变量、存储过程或函数参数或存储程序局部变量。

##### 多变量赋值

一种[`放`](set-variable.html)语句可以包含多个变量赋值，用逗号分隔。此语句将值分配给用户定义的变量和系统变量：

```
SET @x = 1, SESSION sql_mode = '';
```

如果在单个语句中设置多个系统变量，则最近的`全球的`,`坚持`,`PERSIST_ONLY`， 要么`会议`语句中的关键字用于以下未指定关键字的赋值。

多变量赋值的例子：

```
SET GLOBAL sort_buffer_size = 1000000, SESSION sort_buffer_size = 1000000;
SET @@GLOBAL.sort_buffer_size = 1000000, @@LOCAL.sort_buffer_size = 1000000;
SET GLOBAL max_connections = 1000, sort_buffer_size = 1000000;
```

这`@@全球的。`,`@@坚持。`,`@@PERSIST_ONLY。`,`@@会议。`， 和`@@`修饰符仅适用于紧随其后的系统变量，而不适用于任何剩余的系统变量。该语句设置[`排序缓冲区大小`](server-system-variables.html#sysvar_sort_buffer_size)全局值为 50000，会话值为 1000000：

```
SET @@GLOBAL.sort_buffer_size = 50000, sort_buffer_size = 1000000;
```

##### 表达式中的系统变量引用

要在表达式中引用系统变量的值，请使用以下之一`@@`-修饰符（除了`@@坚持。`和`@@PERSIST_ONLY。`，在表达式中是不允许的）。例如，您可以检索系统变量值[`选择`](select.html)像这样的声明：

```
SELECT @@GLOBAL.sql_mode, @@SESSION.sql_mode, @@sql_mode;
```

笔记

在表达式中对系统变量的引用为`@@*`变量名`*`（和`@@`而不是`@@全球的。`要么`@@会议。`) 如果存在则返回会话值，否则返回全局值。这不同于`放 @@*`变量名`* = *`表达式`*`，它总是指会话值。
