Skip to content

17.4 变量

用户自定义变量:@var_name。可以由字母、数字、点、下划线、$组成,大小写不敏感。

存储在session中,只在当前客户端中起作用,退出时清除所有自定义变量。

1. 定义变量

/* 1.SET语法赋值 */
SET @var_name {= | :=} expr [, @var_name = expr] ...
/* 2.通过查询将结果赋给变量,这要求查询返回的结果必须只有一行 */
SELECT col_name[,...] INTO @var_name[,...] table_expr
/* 3.通过游标赋值 */
FETCH [[NEXT] FROM] cursor_name INTO var_name [, var_name] ...

/* 表达式举例 */
/* 表达式的结果只能是单一字段,并且只能有一个值 */
MariaDB [MYISAM_TEST]> SET @V2=(SELECT COUNT(ID) FROM PARENT);
MariaDB [MYISAM_TEST]> SELECT ID INTO @RESULT FROM CHILD WHERE ID=1;

值的类型有以下几种:

  • 整数
  • 定点数
  • 浮点数
  • 二进制或非二进制字符串。如果赋予了非二进制(character)的字符串,就和字符串具有相同的字符集与排序规则。十六进制和比特类型的值被认为是二进制字符串,也可以通过转换使用它的数字形式。
  • NULL
mysql> SET @v1 = X'41';
mysql> SET @v2 = X'41'+0;
mysql> SET @v3 = CAST(X'41' AS UNSIGNED);
mysql> SELECT @v1, @v2, @v3;
+------+------+------+
| @v1  | @v2  | @v3  |
+------+------+------+
| A    |   65 |   65 |
+------+------+------+
mysql> SET @v1 = b'1000001';
mysql> SET @v2 = b'1000001'+0;
mysql> SET @v3 = CAST(b'1000001' AS UNSIGNED);
mysql> SELECT @v1, @v2, @v3;
+------+------+------+
| @v1  | @v2  | @v3  |
+------+------+------+
| A    |   65 |   65 |
+------+------+------+

也可以通过其他方式定义变量:

mysql> SET @t1=1, @t2=2, @t3:=4;
mysql> SELECT @t1, @t2, @t3, @t4 := @t1+@t2+@t3;
+------+------+------+--------------------+
| @t1  | @t2  | @t3  | @t4 := @t1+@t2+@t3 |
+------+------+------+--------------------+
|    1 |    2 |    4 |                  7 |
+------+------+------+--------------------+

2. 使用限制

如果在结果集中选择了用户变量的值,则会将其作为字符串返回给客户端。???

规定:除了在SET语句中,不要在同一条语句中对变量赋值并读取。

在SELECT语句中,仅在发送到客户端时评估每个select表达式,这意味着在HAVING, GROUP BY, or ORDER BY中引用变量不会返回正常的结果。

变量不能直接用作SQL语句中的标识符或标识符的一部分,加了引号也没用。例如SELECT语句中的表名。一个例外是,当构造一个字符串以用作稍后执行的预准备语句时。

mysql> SET @c = "c1";
Query OK, 0 rows affected (0.00 sec)

mysql> SET @s = CONCAT("SELECT ", @c, " FROM t");
Query OK, 0 rows affected (0.00 sec)

mysql> PREPARE stmt FROM @s;
Query OK, 0 rows affected (0.04 sec)
Statement prepared

mysql> EXECUTE stmt;
+----+
| c1 |
+----+
|  0 |
+----+
|  1 |
+----+
2 rows in set (0.00 sec)

mysql> DEALLOCATE PREPARE stmt;
Query OK, 0 rows affected (0.00 sec)

3. 局部变量

存储程序使用DECLARE声明局部变量,在BEGIN...END语句或嵌套的块中使用。

DECLARE var_name [, var_name] ... type [DEFAULT value]
  • 如果有默认值的话必须是常量,没有的话初始值是NULL
  • 变量声明必须在处理器和游标声明之前。
  • 大小写不敏感。
  • 可以在嵌套的程序块中使用变量,除了嵌套的块中声明了同名的变量。
  • 只作用于存储过程或函数的运行期间,不允许在存储程序的预准备语句中引用(预准备语句的作用域是当前客户端的session)。

例子:

MariaDB [MYISAM_TEST]> delimiter //
MariaDB [MYISAM_TEST]> CREATE FUNCTION get_date() RETURNS CHAR(10) 
> BEGIN DECLARE RESULT CHAR(10);
> SELECT DATE_FORMAT(CURRENT_DATE, '%Y-%m-%d') INTO RESULT;
> RETURN RESULT;
> END //
MariaDB [MYISAM_TEST]> delimiter ;

MariaDB [MYISAM_TEST]> SET @RE=get_date();
Query OK, 0 rows affected (0.00 sec)

MariaDB [MYISAM_TEST]> SELECT @RE;
+------------+
| @RE        |
+------------+
| 2019-05-13 |
+------------+