13.7.4.1 SET 变量分配的语法

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

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

SET变量分配的语法使您可以将值分配给影响服务器或 Client 端操作的不同类型的变量:

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

以下各节介绍了用于设置变量的SET语法。他们使用=赋值运算符,但为此也允许:=赋值运算符。

用户定义的变量分配

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

用户定义的变量写为@var_name,并分配了一个 table 达式值,如下所示:

SET @var_name = expr;

Examples:

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

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

性能架构user_variables_by_threadtable 包含有关用户定义的变量的信息。参见第 25.12.10 节,“性能模式用户定义的变量 table”

参数和局部变量的分配

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语句进行更改以影响当前服务器实例的操作。 (要使全局系统变量设置永久生效,以便将其应用于服务器重启时,还应该在选项文件中进行设置.)

如果更改会话系统变量,则该值将在会话内保持有效,直到将变量更改为其他值或会话结束为止。该更改对其他会话没有影响。

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

Note

设置全局系统变量值始终需要特殊特权。设置会话系统变量值通常不需要特殊特权,并且任何用户都可以完成,尽管有 exception。有关更多信息,请参见第 5.1.8.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';

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

要将全局系统变量值设置为嵌入式 MySQL 默认值,或者将会话系统变量设置为当前对应的全局值,请将变量设置为值DEFAULT。例如,以下两个语句在将会话值max_join_size设置为当前全局值时是相同的:

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

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

SET 错误处理

如果SET语句中的任何变量分配失败,则整个语句都会失败,并且不会更改任何变量。

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

  • 使用SET(任何变体)来设置只读变量:
mysql> SET GLOBAL version = 'abc';
ERROR 1238 (HY000): Variable 'version' is a read only variable
  • 使用GLOBAL来设置仅具有会话值的变量:
mysql> SET GLOBAL sql_log_bin = ON;
ERROR 1231 (42000): Variable 'sql_log_bin' can't be
set to the value of 'ON'
  • 使用SESSION来设置仅具有全局值的变量:
mysql> SET SESSION max_connections = 1000;
ERROR 1229 (HY000): Variable 'max_connections' is a
GLOBAL variable and should be set with SET GLOBAL
  • 省略GLOBAL来设置仅具有全局值的变量:
mysql> SET max_connections = 1000;
ERROR 1229 (HY000): Variable 'max_connections' is a
GLOBAL variable and should be set with SET GLOBAL
  • @@GLOBAL.@@SESSION.@@修饰符仅适用于系统变量。尝试将其应用于用户定义的变量,存储过程或函数参数或存储的程序局部变量时发生错误。

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

  • 尝试将DEFAULT分配给用户定义的变量,存储过程或函数参数或存储程序局部变量时发生错误。

多变量分配

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

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

如果在单个语句中设置多个系统变量,则该语句中最新的GLOBALSESSION关键字用于以下未指定关键字的分配。

多变量分配的示例:

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.@@SESSION.@@修饰符仅适用于紧随其后的系统变量,不适用于任何剩余的系统变量。该语句将sort_buffer_size全局值设置为 50000,并将会话值设置为 1000000:

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

要在 table 达式中引用系统变量的值,请使用@@-修饰符之一。例如,您可以像这样在SELECT语句中检索系统变量值:

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

Note

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