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 端操作的不同类型的变量:
-
用户定义的变量。参见第 9.4 节“用户定义的变量”。
-
存储过程和函数参数,以及存储程序局部变量。参见第 13.6.4 节“存储程序中的变量”。
-
系统变量。参见第 5.1.7 节“服务器系统变量”。也可以在服务器启动时设置系统变量,如第 5.1.8 节“使用系统变量”中所述。
分配变量值的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;
- 要将值分配给会话系统变量,请在变量名称前加上
SESSION
或LOCAL
关键字,@@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;
要显示系统变量名称和值:
-
几个性能模式 table 提供了系统变量信息。参见第 25.12.13 节,“性能架构系统变量 table”。
SET 错误处理
如果SET语句中的任何变量分配失败,则整个语句都会失败,并且不会更改任何变量。
SET在此处描述的情况下会产生错误。大多数示例显示使用关键字语法的SET语句(例如GLOBAL
或SESSION
),但是对于使用相应修饰符的语句(例如@@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 = '';
如果在单个语句中设置多个系统变量,则该语句中最新的GLOBAL
或SESSION
关键字用于以下未指定关键字的分配。
多变量分配的示例:
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
,后者始终引用会话值。