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

MySQL 9.0 参考手册  /  ...  /  用于变量赋值的 SET 语法

15.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 用于变量赋值的语法允许您为影响服务器或客户端操作的不同类型的变量赋值

将变量值分配的 SET 语句不会写入二进制日志,因此在复制场景中,它只会影响执行该语句的主机。要影响所有复制主机,请在每个主机上执行该语句。

以下部分介绍用于设置变量的SET语法。它们使用=赋值运算符,但:=赋值运算符也可用于此目的。

用户定义变量赋值

用户定义变量是在会话中本地创建的,并且只在该会话的上下文中存在;参见第 11.4 节,“用户定义变量”

用户定义变量写为@var_name,并被分配一个表达式值,如下所示

SET @var_name = expr;

示例

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

正如这些语句所演示的那样,expr 的范围可以从简单(字面量值)到更复杂(标量子查询返回的值)。

Performance Schema user_variables_by_thread 表包含有关用户定义变量的信息。参见第 29.12.10 节,“Performance Schema 用户定义变量表”

参数和局部变量赋值

SET 应用于存储对象定义中参数和局部变量的上下文。以下过程使用increment 过程参数和counter 局部变量

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 语句在运行时更改,以影响当前服务器实例的操作。 SET 也可用于将某些系统变量持久化到数据目录中的mysqld-auto.cnf 文件中,以影响后续启动时的服务器操作。

如果为敏感的系统变量发出SET 语句,则查询将被重写为将值替换为<redacted>,然后再将其记录到通用日志和审计日志中。即使服务器实例上没有通过密钥环组件提供安全存储,也会发生这种情况。

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

如果您更改了全局系统变量,则该值将被记住并用于初始化新会话的会话值,直到您将变量更改为其他值或服务器退出。该更改对访问全局值的任何客户端都是可见的。但是,该更改只影响在更改后连接的客户端的相应会话值。全局变量更改不会影响任何当前客户端会话(即使是在其中发生全局值更改的会话)的会话值。

要使全局系统变量设置永久生效,使其在服务器重启时生效,您可以将其持久化到数据目录中的mysqld-auto.cnf 文件中。也可以通过手动修改my.cnf 选项文件来进行持久配置更改,但这更麻烦,并且手动输入的设置中的错误可能要到很久以后才会被发现。 SET 语句用于持久化系统变量更加方便,并且可以避免语法错误设置的可能性,因为具有语法错误的设置不会成功,也不会更改服务器配置。有关持久化系统变量和mysqld-auto.cnf 文件的更多信息,请参见第 7.1.9.3 节,“持久化系统变量”

注意

设置或持久化全局系统变量值始终需要特殊权限。设置会话系统变量值通常不需要特殊权限,任何用户都可以执行,但也有例外。有关更多信息,请参见第 7.1.9.1 节,“系统变量权限”

以下讨论介绍了设置和持久化系统变量的语法选项

  • 要为全局系统变量分配值,请在变量名前面加上GLOBAL 关键字或@@GLOBAL. 限定符

    SET GLOBAL max_connections = 1000;
    SET @@GLOBAL.max_connections = 1000;
  • 要为会话系统变量分配值,请在变量名前面加上SESSIONLOCAL 关键字、@@SESSION.@@LOCAL.@@ 限定符,或者不加任何关键字或修饰符

    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 选项文件中,请在变量名前面加上PERSIST 关键字或@@PERSIST. 限定符

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

    SET 语法使您能够在运行时进行配置更改,这些更改也将在服务器重启时持久化。与SET GLOBAL 类似,SET PERSIST 设置全局变量运行时值,但也将变量设置写入mysqld-auto.cnf 文件(如果存在,则替换任何现有的变量设置)。

  • 要将全局系统变量持久化到mysqld-auto.cnf 文件中,而不设置全局变量运行时值,请在变量名前面加上PERSIST_ONLY 关键字或@@PERSIST_ONLY. 限定符

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

    PERSIST 类似,PERSIST_ONLY 将变量设置写入mysqld-auto.cnf。但是,与PERSIST 不同,PERSIST_ONLY 不会修改全局变量运行时值。这使得PERSIST_ONLY 适合配置只能在服务器启动时设置的只读系统变量。

要将全局系统变量值设置为编译后的 MySQL 默认值,或将会话系统变量设置为当前对应的全局值,请将变量设置为值DEFAULT。例如,以下两个语句在将max_join_size 的会话值设置为当前全局值方面是相同的

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

使用SET 将全局系统变量持久化为DEFAULT 值或其字面量默认值,将为变量分配其默认值,并将该变量的设置添加到mysqld-auto.cnf 中。要从文件中删除变量,请使用RESET PERSIST

某些系统变量不能持久化,或者受到持久化限制。参见第 7.1.9.4 节,“不可持久化和持久化受限的系统变量”

由插件实现的系统变量可以持久化,前提是在执行SET 语句时安装了该插件。持久化插件变量的分配将在后续服务器重启时生效,前提是插件仍然安装。如果插件不再安装,则服务器读取mysqld-auto.cnf 文件时,插件变量将不再存在。在这种情况下,服务器会将警告写入错误日志并继续

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

要显示系统变量名称和值

SET 错误处理

如果SET 语句中的任何变量赋值失败,则整个语句都将失败,并且不会更改任何变量,也不会更改mysqld-auto.cnf 文件。

SET 在此处描述的情况下会产生错误。大多数示例显示使用关键字语法的SET 语句(例如,GLOBALSESSION),但这些原则也适用于使用相应修饰符的语句(例如,@@GLOBAL.@@SESSION.)。

  • 使用SET(任何变体)设置只读变量

    mysql> SET GLOBAL version = 'abc';
    ERROR 1238 (HY000): Variable 'version' is a read only variable
  • 使用GLOBALPERSISTPERSIST_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
  • 使用SESSION 设置只具有全局值的变量

    mysql> SET SESSION max_connections = 1000;
    ERROR 1229 (HY000): Variable 'max_connections' is a
    GLOBAL variable and should be set with SET GLOBAL
  • 省略GLOBALPERSISTPERSIST_ONLY 设置只具有全局值的变量

    mysql> SET max_connections = 1000;
    ERROR 1229 (HY000): Variable 'max_connections' is a
    GLOBAL variable and should be set with SET GLOBAL
  • 使用PERSISTPERSIST_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
  • @@GLOBAL.@@PERSIST.@@PERSIST_ONLY.@@SESSION.@@ 修饰符仅适用于系统变量。尝试将它们应用于用户定义变量、存储过程或函数参数或存储程序局部变量会导致错误。

  • 并非所有系统变量都可以设置为DEFAULT。在这种情况下,将DEFAULT 分配给变量会导致错误。

  • 尝试将DEFAULT 分配给用户定义变量、存储过程或函数参数或存储程序局部变量会导致错误。

多个变量赋值

SET 语句可以包含多个变量赋值,用逗号分隔。此语句为用户定义变量和系统变量分配值

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

如果在一个语句中设置多个系统变量,则语句中最新的 GLOBALPERSISTPERSIST_ONLYSESSION 关键字将用于以下未指定关键字的赋值。

多变量赋值的示例

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;

@@GLOBAL.@@PERSIST.@@PERSIST_ONLY.@@SESSION.@@ 修饰符仅应用于紧随其后的系统变量,不应用于任何剩余的系统变量。此语句将 sort_buffer_size 全局值设置为 50000,会话值设置为 1000000

SET @@GLOBAL.sort_buffer_size = 50000, sort_buffer_size = 1000000;
表达式中的系统变量引用

要在表达式中引用系统变量的值,请使用其中一个 @@ 修饰符(除了 @@PERSIST.@@PERSIST_ONLY.,它们不允许在表达式中使用)。例如,您可以在 SELECT 语句中检索系统变量值,如下所示

SELECT @@GLOBAL.sql_mode, @@SESSION.sql_mode, @@sql_mode;
注意

在表达式中对系统变量的引用,例如 @@var_name(使用 @@ 而不是 @@GLOBAL.@@SESSION.),如果存在则返回会话值,否则返回全局值。这与 SET @@var_name = expr 不同,后者始终引用会话值。