变量学习
在MySQL使用过程中,我们经常会使用到一些变量,这些变量可能是系统变量或者用户自定义变量。如当查询或者修改系统配置的时候,可以查询和修改系统变量。当然在进行批处理脚本的时候,用户可以自定义变量,来实现数据的重复使用。
本文主要介绍系统变量和用户自定义变量的详细使用。需要说明的是,本篇文章代码中被[]
包含的内容表示可选的,而被|
分隔的内容表示可选其一。
系统变量
前面也说了变量分为系统变量和用户自定义变量,那么接下来就分别介绍这两个变量。
系统变量是指系统定义的变量,它是mysql服务器层面的。
系统变量分类
系统变量分为全局变量和会话变量。
(1)查看系统中所有变量的语法如下所示:
1 | shwo [global | session] variables; |
(2)查看全局变量的语法如下所示:
1 | show global variables; |
(3)查看会话变量的语法如下所示:
1 | show session variables; |
(4)如果想查询满足指定条件的系统变量,可以使用like关键字来实现模糊匹配:
1 | shwo [global | session] like '%变量名%'; |
(5)查看指定的系统变量的语法如下所示:
1 | select @@[global.|session.]系统变量名称; |
请注意global
和session
关键字后面有一个.
点号;
(6)开发者可以使用如下命令来给对应的变量赋值:
1 | //方式1 |
在上面给变量赋值的时候请注意,当变量是全局变量则需要添加global
关键字;是会话变量则需要添加session
关键字,如果开发者不写,那么默认将是session级别的变量。另外可以发现在上面的例子中,全局变量里面使用了@@
符号,注意用户自定义变量中只有一个@
符号。
全局变量
全局变量作用域
MySQL服务每次启动时都会为所有的系统变量设置初始值。
当然开发者可以为系统变量赋值,然后针对所有会话(连接)有效,注意它可以跨连接,但是不能跨重启,当用户将系统重启后,那么MySQL服务器会再次为所有的系统变量设置初始值。
全局变量演示
接下来将通过一些例子来演示全局变量的相关操作。
(1)查看所有的全局变量:
1 | show global variables; |
(2)查看包含’tx’字符的变量:
1 | mysql> show global variables like '%tx%'; |
(3)查看指定名称的系统变量的值,如查看事务默认自动提交设置:
1 | mysql> select @@global.autocommit; |
(4)为某个变量赋值:
1 | mysql> set global autocommit=1; |
会话变量
会话变量作用域
会话变量只对当前会话(连接)有效,注意它不能跨连接使用。会话变量是在连接创建时,由MySQL自动给当前会话设置的变量。
会话变量演示
接下来将通过一些例子来演示会话变量的相关操作。
(1)查看所有的会话变量:
1 | show session variables; |
(2)查看包含’char’字符的会话变量:
1 | show session variables like '%char%'; |
(3)查看指定名称的会话变量的值:
1 | -- 查看事务默认自动提交的设置 |
set @@session.tx_isolation=’read-uncommitted’;
set @@tx_isolation=’read-committed’;
set session tx_isolation=’read-committed’;
set tx_isolation=’read-committed’;
1 | # 用户自定义变量 |
– 方法1
set @变量名=值;
– 方法2
set @变量名:=值;
– 方法3
select @变量名:=值;
1 | 前面在介绍全局变量的时候就说过,全局变量使用了两个`@`符号,而此处的用户变量则使用一个`@`符号,同时set中=号前面的冒号是可选的,而select中=号前面的冒号是必须的,不能缺少。 |
–方式1:方式同用户变量使用
set @变量名=值;
set @变量名:=值;
select @变量名:=值;
–方式2:使用select into语句
select 字段 into @变量名 from 表;
1 | ##### 用户变量演示 |
set @username = ‘envy’;
1 | (2)使用select into方式来创建变量并初始化: |
select ‘hellobook’ into @hello;
select count(*) into @empcount from employees;
1 | (3)使用`select :=`方式来创建变量: |
select @first_name:=’envy’,@email:=‘envybook@qq.com‘;
1 | (4)使用变量: |
insert into employees(first_name,email)values(@first_name,@email);
1 | ### 局部变量 |
declare 变量名 变量类型;
declare 变量名 变量类型 [default 默认值];
1 |
|
/方式1/
set 局部变量名=值;
set 局部变量名:=值;
select 局部变量名:=值;
/方式2:使用select into语句/
select 字段 into 局部变量名 from 表;
1 | 可以看到,局部变量前面是没有`@`符号的。 |
select 局部变量名;
1 | ##### 局部变量演示 |
drop table if exists book1;
create table book1(a int primary key,b int);
1 | (2)声明一个脚本,请注意声明脚本的结束符为`$$`: |
delimiter $$
drop procedure if exists proc1;
create procedure proc1()
begin
/声明一个局部变量/
declare v_a int;
select ifnull(max(a),0)+1 into v_a from book1;
select @v_b:=v_a*2;
insert into book1(a,b) select v_a,@v_b;
end $$
/声明脚本的结束符为;/
delimiter;
/调用存储过程/
call proc1();
/查看结果/
select * from book1;
1 | 可以上面使用到了存储过程,关于存储过程会在后续文章中进行学习。 |
delimiter 分隔符
1 | 接下来就将局部变量演示这个例子进行执行,执行结果如下所示: |
mysql> drop table if exists book1;
Query OK, 0 rows affected (0.01 sec)
mysql> create table book1(a int primary key,b int);
Query OK, 0 rows affected (0.01 sec)
mysql> delimiter $$
mysql> drop procedure if exists proc1;
-> create procedure proc1()
-> begin
-> declare v_a int;
->
-> select ifnull(max(a),0)+1 into v_a from book1;
-> select @v_b:=v_a*2;
-> insert into book1(a,b) select v_a,@v_b;
-> end $$
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter;
mysql>
mysql> call proc1();
+————-+
| @v_b:=v_a*2 |
+————-+
| 2 |
+————-+
1 row in set (0.00 sec)
Query OK, 1 row affected (0.01 sec)
mysql> select * from book1;
+—+——+
| a | b |
+—+——+
| 1 | 2 |
+—+——+
1 row in set (0.00 sec)
```
用户变量和局部变量对比
接下来对前面所介绍的2种变量进行对比和总结
变量类型 | 作用域 | 定义位置 | 语法 |
---|---|---|---|
用户变量 | 当前会话 | 会话的任意位置 | 添加@ 符号,不用指定类型 |
局部变量 | 定义在它的begin和end之间 | begin end中的第一句话 | 不加@ 符号,但是必须指定类型 |
文章总结
本篇文章学习了系统变量和用户自定义变量,其中系统变量又可以分为全局变量和会话变量;用户自定义变量分为用户变量和局部变量。
系统变量可以设置系统的一些配置信息,数据库重启之后配置信息将会被还原;会话变量可以设置当前会话的一些配置信息,这些配置信息仅对当前会话起效;开发者可以使用declare来创建局部变量,局部变量常用于存储过程和函数的创建中。
全局变量对整个系统有效、会话变量作用于当前会话、用户变量作用于当前会话、局部变量作用于begin and之间。同时全局变量使用了@@
,用户变量使用了@
,而局部变量没有@
符号。开发者还可以使用delimiter关键字来声明脚本的结束符,这个在某些场合下还是非常有用的。