当前位置: 澳门新濠3559 > 数据库 > 正文

可以认为局部变量也是用户变量【但有所不同,

时间:2019-11-09 00:17来源:数据库
说明:现在市面上定义变量的教程和书籍基本都放在存储过程上说明,但是存储过程上变量只能作用于begin...end块中,而普通的变量定义和使用都说的比较少,针对此类问题只能在官方

说明:现在市面上定义变量的教程和书籍基本都放在存储过程上说明,但是存储过程上变量只能作用于begin...end块中,而普通的变量定义和使用都说的比较少,针对此类问题只能在官方文档中才能找到讲解。

在mysql变量中分为局部变量@与全局变量@@他们都不分大小并,但两种变量用法稍有区别了,下面我来介绍产的用法。

 

本文内容:

 

系统变量

用户变量

  • 局部变量

 

首发日期:2018-04-18

 


前言

共同点:不区分大小写,都是变量

set语句的学习:

系统变量:

  • 系统变量就是系统已经提前定义好了的变量
  • 系统变量一般都有其特殊意义。比如某些变量代表字符集、某些变量代表某些mysql文件位置
  • 系统变量中包括会话级变量(当次会话连接生效的变量,如names),以及全局变量(一直生效的变量) 【系统变量中全局变量和会话变量其实是使用一套变量,不同的是会话变量仅当次会话生效。】
    • 会话变量的赋值:set 变量名 = 值;  【比如常用的set names ="utf8";】或者set @@变量名=值
    • 全局变量的赋值:set global 变量名 = 值;

 

MySQL存储过程中,定义变量有两种方式: 

不同点:全局变量是系统中只读的,可以在配置文件中进行修改

 

查看系统变量:

  • show variables;

1、使用set或select直接赋值,变量名以@开头

mysql变量的术语分类:

使用select定义用户变量的实践

系统变量的调用:

  • select @@变量名;

 


例如:

1.用户变量:以"@"开始,形式为"@变量名"
用户变量跟mysql客户端是绑定的,设置的变量,只对当前用户使用的客户端生效
2.全局变量:定义时,以如下两种形式出现,set GLOBAL 变量名  或者  set @@global.变量名
对所有客户端生效。只有具有super权限才可以设置全局变量

将如下语句改成select的形式:

用户变量:

 

  • 用户变量就是用户自己定义的变量。
  • 系统为了区别系统变量跟自定义变量,规定用户自定义变量必须使用一个@符号
  • 变量的定义方式:
    • set @变量名=1
    • select @变量名:=值;
    • select 值 into @变量名;
  • 用户变量可以不声明定义,就可以直接使用,不过默认是null值
  • 用户变量都是会话级的变量,仅在当次连接中生效。

 

set @var=1; 

3.会话变量:只对连接的客户端有效。

 set @VAR=(select sum(amount) from penalties);

局部变量:

由于局部变量是用户自定义的,可以认为局部变量也是用户变量【但有所不同,局部中不需要使用@】

局部变量一般用在sql语句块中,比如存储过程块、触发器块等

局部变量的定义方法:

先使用declare声明局部变量,其中可选项default后面可以跟一个付给变量的默认值:【非常重要的一步,不然会设置成用户变量】【注意:变量声明语句要在其他语句如select语句之前】

  • 示例:declare myq int;
  • 示例:declare myq int default 666;

设置变量的值:

  • set 变量名= 值;

获取变量的值:

  • select 变量名;

    create procedure myset() begin

    declare mya int;
    declare myq int default 777;
    select mya,myq;
    set myq=6;
    set mya=666;
    select mya,myq;
    

    end;

    call myset();

 

 

可以在一个会话的任何地方声明,作用域是整个会话,称为用户变量。

4.局部变量:作用范围在begin到end语句块之间。在该语句块里设置的变量
declare语句专门用于定义局部变量。set语句是设置不同类型的变量,包括会话变量和全局变量

我的修改:

补充:

  • 有些人可能会发现直接set 变量名=值;也可以定义“用户变量”;但这是一种不好的行为【这种行为忽略了各自变量的功能】,因为你不知道会不会跟系统变量冲突,所以最好用户变量加上@
  • 因为 = ,有很多地方都用来判断是否等于,为了避免歧义,也可以使用:=来赋值澳门新濠3559 1
  • 上面虽然给了一些其他的赋值方法,但好像有一些是不通用的,比如:=只用于用户变量,所以要审慎使用】。

 


2、以declare关键字声明的变量,只能在存储过程中使用,称为存储过程变量,例如: 

通俗理解术语之间的区别:

 select @VAR:=(select sum(amount) from penalties);

declare var1 int default 0; 

用户定义的变量就叫用户变量。这样理解的话,会话变量和全局变量都可以是用户定义的变量。只是他们是对当前客户端生效还是对所有客户端生效的区别了。所以,用户变量包括了会话变量和全局变量

 

主要用在存储过程中,或者是给存储传参数中。

局部变量与用户变量的区分在于两点:1.用户变量是以"@"开头的。局部变量没有这个符号。2.定义变量不同。用户变量使用set语句,局部变量使用declare语句定义 3.作用范围。局部变量只在begin-end语句块之间有效。在begin-end语句块运行完之后,局部变量就消失了。

我这样改,虽然是可以的。但是,对比的书中的答案,发现这样的方式太蹩脚了。说明没有很好地理解select定义变量的本质。

两者的区别是: 

所以,最后它们之间的层次关系是:变量包括局部变量和用户变量。用户变量包括会话变量和全局变量。

在select中,发现有一个用户变量,如果没有定义,那么就会初始化。

在调用存储过程时,以declare声明的变量都会被初始化为null。而会话变量(即@开头的变量)则不会被再初始化,在一个会话内,只须初始化一次,之后在会话内都是对上一次计算的结果,就相当于在是这个会话内的全局变量。

使用备忘,set @var 若没有指定GLOBAL 或SESSION ,那么默认将会定义用户变量
两种方式定义用户变量:

select子句原来的方式根本不受到影响。只是增加了用户变量。所以,还是按照原来的方式使用select子句。那么像:select sum(amount) from penalties。增加变量就成

主体内容

1."=",如 set @a =3,@a:=5

 

  • 局部变量 
  • 用户变量 
  • 会话变量 
  • 全局变量 

2.":="。select常常这样使用
总结:使用select 和set设置变量的区别,set可以使用以上两种形式设置变量。而select只能使用":="的形式设置变量
实践积累:用户变量在mysql客户端退出后,会自动消失。之后我打开客户端,使用"select @a;" 显示变了的值为null。说明,未定义的变量初始化是null

了:select  @VAR:=sum(amount) from penalties。

会话变量和全局变量叫系统变量。

实际中的问题

 

一、局部变量,只在当前begin/end代码块中有效

设置常量对group_concat()的配置影响:
SET @@GROUP_CONCAT_MAX_LEN=4
手册中提到设置的语法是这样的:
SET [SESSION | GLOBAL] group_concat_max_len = val;

将sum(amount)的结果赋给变量@VAR:。变量前面有select,那用户么就是显示该变量了。

局部变量一般用在sql语句块中,比如存储过程的begin/end。其作用域仅限于该语句块,在该语句块执行完毕后,局部变量就消失了。declare语句专门用于定义局部变量,可以使用default来说明默认值。set语句是设置不同类型的变量,包括会话变量和全局变量。 
局部变量定义语法形式

 

 

declare var_name [, var_name]... data_type [ DEFAULT value ];

可以show variables;进行查看

 

例如在begin/end语句块中添加如下一段语句,接受函数传进来的a/b变量然后相加,通过set语句赋值给c变量。 

mysql> show variables;

笔记部分:mysql变量的术语分类:

set语句语法形式set var_name=expr [, var_name=expr]...; set语句既可以用于局部变量的赋值,也可以用于用户变量的申明并赋值。

看看全局变量的值:

1.用户变量:以"@"开始,形式为"@变量名"

declare c int default 0;
set c=a+b;
select c as C;

mysql> select @@version;
+-----------+
| @@version |
+-----------+
| 5.5.14    |
+-----------+
1 row in set (0.00 sec)

用户变量跟mysql客户端是绑定的,设置的变量,只对当前用户使用的客户端生效

或者用select …. into…形式赋值

局部变量赋值

2.全局变量:定义时,以如下两种形式出现,set GLOBAL 变量名  或者  set @@global.变量名

select into 语句句式:select col_name[,...] into var_name[,...] table_expr [where...];

方法一:

对所有客户端生效。只有具有super权限才可以设置全局变量

例子:

 代码如下

 

declare v_employee_name varchar(100);
declare v_employee_salary decimal(8,4);

select employee_name, employee_salary
into v_employee_name, v_employee_salary
from employees
where employee_id=1;

复制代码

3.会话变量:只对连接的客户端有效。

二、用户变量,在客户端链接到数据库实例整个过程中用户变量都是有效的。

mysql> set @name="zhouyinghou";

 

MySQL中用户变量不用事前申明,在用的时候直接用“@变量名”使用就可以了。 

Query OK, 0 rows affected (0.00 sec)

4.局部变量:作用范围在begin到end语句块之间。在该语句块里设置的变量

第一种用法:set @num=1; 或set @num:=1; //这里要使用set语句创建并初始化变量,直接使用@num变量 

 查看局部变量的值

declare语句专门用于定义局部变量。set语句是设置不同类型的变量,包括会话变量和全局变量

第二种用法:select @num:=1; 或 select @num:=字段名 from 表名 where ……, 

mysql> select @name;
+-------------+
| @name       |
+-------------+
| zhouyinghou |
+-------------+
1 row in set (0.00 sec)

 

select语句一般用来输出用户变量,比如select @变量名,用于输出数据源不是表格的数据。

方法二:

通俗理解术语之间的区别:

注意上面两种赋值符号,使用set时可以用“=”或“:=”,但是使用select时必须用“:=赋值”

还可以用select赋值并且将其输出

用户定义的变量就叫用户变量。这样理解的话,会话变量和全局变量都可以是用户定义的变量。只是他们是对当前客户端生效还是对所有客户端生效的区别了。所以,用户变量包括了会话变量和全局变量

用户变量与数据库连接有关,在连接中声明的变量,在存储过程中创建了用户变量后一直到数据库实例接断开的时候,变量就会消失。

 代码如下

局部变量与用户变量的区分在于两点:1.用户变量是以"@"开头的。局部变量没有这个符号。2.定义变量不同。用户变量使用set语句,局部变量使用declare语句定义3.作用范围。局部变量只在begin-end语句块之间有效。在begin-end语句块运行完之后,局部变量就消失了。

在此连接中声明的变量无法在另一连接中使用。

复制代码

所以,最后它们之间的层次关系是:变量包括局部变量和用户变量。用户变量包括会话变量和全局变量。

用户变量的变量名的形式为@varname的形式。

mysql> select @sex:="male";
+--------------+
| @sex:="male" |
+--------------+
| male         |
+--------------+
1 row in set (0.00 sec)

 

名字必须以@开头。

方法三:

 

声明变量的时候需要使用set语句,比如下面的语句声明了一个名为@a的变量。

select还可以从一张表中提取

使用备忘,set @var 若没有指定GLOBAL 或SESSION ,那么默认将会定义用户变量

set @a = 1;

 代码如下

两种方式定义用户变量:

声明一个名为@a的变量,并将它赋值为1,MySQL里面的变量是不严格限制数据类型的,它的数据类型根据你赋给它的值而随时变化 。(SQL SERVER中使用declare语句声明变量,且严格限制数据类型。) 

复制代码

1."=",如set @a =3,@a:=5

我们还可以使用select语句为变量赋值 。 

mysql> drop table zyh;
Query OK, 0 rows affected (0.09 sec)

2.":="。select常常这样使用

比如:

mysql> create table zyh(id int,name char(20));
Query OK, 0 rows affected (0.19 sec)

总结:使用select 和set设置变量的区别,set可以使用以上两种形式设置变量。而select只能使用":="的形式设置变量

set @name = '';
select @name:=password from user limit 0,1;
#从数据表中获取一条记录password字段的值给@name变量。在执行后输出到查询结果集上面。

mysql> insert into zyh values(1,'zhouyinghou');
Query OK, 1 row affected (0.09 sec)

实践积累:用户变量在mysql客户端退出后,会自动消失。之后我打开客户端,使用"select @a;" 显示变了的值为null。说明,未定义的变量初始化是null

(注意等于号前面有一个冒号,后面的limit 0,1是用来限制返回结果的,表示可以是0或1个。相当于SQL SERVER里面的top 1) 

mysql> select @name:=name from zyh;
+-------------+
| @name:=name |
+-------------+
| zhouyinghou |
+-------------+
1 row in set (0.00 sec)

实际中的问题

如果直接写:select @name:=password from user;

方法四:

设置常量对group_concat()的配置影响:

如果这个查询返回多个值的话,那@name变量的值就是最后一条记录的password字段的值 。 

这个语句还可以这样写:

SET @@GROUP_CONCAT_MAX_LEN=4

用户变量可以作用于当前整个连接,但当当前连接断开后,其所定义的用户变量都会消失。 

 代码如下

手册中提到设置的语法是这样的:

用户变量使用如下(我们无须使用declare关键字对用户变量进行定义,可以直接这样使用)定义,变量名必须以@开始:

复制代码

SET [SESSION | GLOBAL] group_concat_max_len = val;

#定义
select @变量名  或者 select @变量名:= 字段名 from 表名 where 过滤语句;
set @变量名;
#赋值 @num为变量名,value为值
set @num=value;或select @num:=value;

mysql> select name from zyh into @name;
Query OK, 1 row affected (0.00 sec)

 

对用户变量赋值有两种方式,一种是直接用”=”号,另一种是用”:=”号。其区别在于使用set命令对用户变量进行赋值时,两种方式都可以使用;当使用select语句对用户变量进行赋值时,只能使用”:=”方式,因为在select语句中,”=”号declare语句专门用于定义局部变量。set语句是设置不同类型的变量,包括会话变量和全局变量。

 1 row affected说明了数据已经别更新了

以下两种形式都能达到达到同样的效果,但是有什么区别?

例如:

 代码如下

 

begin
#Routine body goes here...
#select c as c;
declare c int default 0;
set @var1=143;  #定义一个用户变量,并初始化为143
set @var2=34;
set c=a+b;
set @d=c;
select @sum:=(@var1+@var2) as sum, @dif:=(@var1-@var2) as dif, @d as C;#使用用户变量。@var1表示变量名

set c=100;
select c as CA;
end

#在查询中执行下面语句段
call `order`(12,13);  #执行上面定义的存储过程
select @var1;  #看定义的用户变量在存储过程执行完后,是否还可以输出,结果是可以输出用户变量@var1,@var2两个变量的。
select @var2;

复制代码

SET @@global.GROUP_CONCAT_MAX_LEN=4;

在执行完order存储过程后,在存储过程中新建的var1,var2用户变量还是可以用select语句输出的,但是存储过程里面定义的局部变量c不能识别。

mysql> select @name
    -> ;
+-------------+
| @name       |
+-------------+
| zhouyinghou |
+-------------+
1 row in set (0.00 sec)

global可以省略,那么就变成了:SET @@GROUP_CONCAT_MAX_LEN=4;

系统变量:

 还得注意:@name:=name

2011.2.25

系统变量又分为全局变量与会话变量。

和  into @name

之前的理解不怎么准确。现在对加深理解后的地方进行总结。

全局变量在MySQL启动的时候由服务器自动将它们初始化为默认值,这些默认值可以通过更改my.ini这个文件来更改。

into @name只能接受一行值

mysql中变量的层次关系是:大体包括用户变量和系统变量。系统变量包括系统会话变量和系统全局变量。

会话变量在每次建立一个新的连接的时候,由MySQL来初始化。MySQL会将当前所有全局变量的值复制一份。来做为会话变量。

 代码如下

我是这样理解相互之间的区别:

(也就是说,如果在建立会话以后,没有手动更改过会话变量与全局变量的值,那所有这些变量的值都是一样的。)

复制代码

因为用户变量就是用户定义的变量,系统变量就是mysql定义和维护的变量。所以,用户变量与系统变量的区别在于,是谁在管理这些变量。mysql一启动的时候就会读取系统变量(这样做目的是可以确定mysql的以何种机制或模式运行)。 系统会话变量与用户变量都是在当前客户端退出后消失。他们之间的区别可以这样理解,虽然常常看到"set @@varible"的形式去改变系统变量的值,但是并不涉及到定义系统变量。用户变量是可以自己定义(初始化)。系统变量按照只是在改变值。

全局变量与会话变量的区别就在于,对全局变量的修改会影响到整个服务器,但是对会话变量的修改,只会影响到当前的会话(也就是当前的数据库连接)。

mysql> select name from zyh into @name;
ERROR 1172 (42000): Result consisted of more than one row

局部变量只在begin-end语句块中定义并有效。执行到该语句块之后就消失了。定义的方式有明显的特点,使用declare语句。

我们可以利用

mysql> select @name:=name from zyh;
+-------------+
| @name:=name |
+-------------+
| zhouyinghou |
| zhouhuan    |
+-------------+
2 rows in set (0.00 sec)

为什么看到使用系统变量以"@@变量名"和"变量名"的形式出现,怎么理解两者形式的区别?

show session variables;

mysql> select @name
    -> ;
+----------+
| @name    |
+----------+
| zhouhuan |
+----------+
1 row in set (0.00 sec)

使用系统变量理论上是可以使用两种形式:1.前面带有符号"@@" 2.符号省略。比如我会看的如下形式:CURRENT_USER。但是,约定系统变量要使用"@@变量名"的形式,就是在前面加上符号"@@"。

语句将所有的会话变量输出(可以简写为show variables,没有指定是输出全局变量还是会话变量的话,默认就输出会话变量。)如果想输出所有全局变量:

举例:

为什么会出现CURRENT_USER这样没有符号的情况?看书籍《SQL For MySQL Developers A Comprehensive Tutorial and Reference》大致说明的原因,这样做是为了与其他的SQL产品保持一致。

show global variables

查询zhouhuan相邻的两个人的名字

 

有些系统变量的值是可以利用语句来动态进行更改的,但是有些系统变量的值却是只读的。

如果按照oracle的写法中可以:

作者 hj714886063

对于那些可以更改的系统变量,我们可以利用set语句进行更改。

 代码如下

使用select定义用户变量的实践 将如下语句改成select的形式: set @VAR=(select sum(amount) from penalties); 我的修改: select @VAR:=(se...

系统变量在变量名前面有两个@;澳门新濠3559, 

复制代码

如果想要更改会话变量的值,利用语句:

mysql> select name from zyh where id in(select id-1,id+1 from zyh where name='zhouhuan');
ERROR 1241 (21000): Operand should contain 1 column(s)

set session varname = value;
或者
set @@session.varname = value;

mysql中可以用变量赋值进行查询:

比如:

mysql> select id from zyh where name='zhouhuan' into @id;
Query OK, 1 row affected (0.00 sec)

mysql> set session sort_buffer_size = 40000;
Query OK, 0 rows affected(0.00 sec)
用select @@sort_buffer_size;输出看更改后的值是什么。
如果想要更改全局变量的值,将session改成global:
set global sort_buffer_size = 40000;
set @@global.sort_buffer_size = 40000;

mysql> select @id;
+------+
| @id  |
+------+
|    2 |
+------+
1 row in set (0.00 sec)

不过要想更改全局变量的值,需要拥有super权限 。

mysql> select name from zyh where [email protected] or [email protected]+1;
+-------------+
| name        |
+-------------+
| zhouyinghou |
| kaka        |
+-------------+
2 rows in set (0.00 sec)

(注意,root只是一个内置的账号,而不是一种权限 ,这个账号拥有了MySQL数据库里的所有权限。任何账号只要它拥有了名为super的这个权限,就可以更改全局变量的值,正如任何用户只要拥有file权限就可以调用load_file或者into outfile,into dumpfile,load data infile一样。)

共同点:不区分大小写...

利用select语句我们可以查询单个会话变量或者全局变量的值:

select @@session.sort_buffer_size
select @@global.sort_buffer_size
select @@global.tmpdir

凡是上面提到的session,都可以用local这个关键字来代替。

比如:  

select @@local.sort_buffer_size
local是session的近义词。

无论是在设置系统变量还是查询系统变量值的时候,只要没有指定到底是全局变量还是会话变量。都当做会话变量来处理。 

比如: 

set @@sort_buffer_size = 50000; 
select @@sort_buffer_size; 

上面都没有指定是blobal还是session,所以全部当做session处理。

三、会话变量

服务器为每个连接的客户端维护一系列会话变量。在客户端连接数据库实例时,使用相应全局变量的当前值对客户端的会话变量进行初始化。设置会话变量不需要特殊权限,但客户端只能更改自己的会话变量,而不能更改其它客户端的会话变量。会话变量的作用域与用户变量一样,仅限于当前连接。当当前连接断开后,其设置的所有会话变量均失效。

设置会话变量有如下三种方式更改会话变量的值:

set session var_name = value;
set @@session.var_name = value;
set var_name = value;  #缺省session关键字默认认为是session

查看所有的会话变量
show session variables;

查看一个会话变量也有如下三种方式:

select @@var_name;
select @@session.var_name;
show session variables like "%var%";

凡是上面提到的session,都可以用local这个关键字来代替。 

比如: 

select @@local.sort_buffer_size 
local是session的近义词。

四、全局变量

全局变量影响服务器整体操作。当服务器启动时,它将所有全局变量初始化为默认值。这些默认值可以在选项文件中或在命令行中指定的选项进行更改。要想更改全局变量,必须具有super权限。全局变量作用于server的整个生命周期,但是不能跨重启。即重启后所有设置的全局变量均失效。要想让全局变量重启后继续生效,需要更改相应的配置文件。

要设置一个全局变量,有如下两种方式:

set global var_name = value; //注意:此处的global不能省略。根据手册,set命令设置变量时若不指定GLOBAL、SESSION或者LOCAL,默认使用SESSION
set @@global.var_name = value; //同上

查看所有的全局变量 

show global variables; 

要想查看一个全局变量,有如下两种方式:

select @@global.var_name;
show global variables like “%var%”;

 

参考:

(以上内容转自此篇文章)

 

 

http://blog.163.com/longsu2010@yeah/blog/static/173612348201162595425697/ 

编辑:数据库 本文来源:可以认为局部变量也是用户变量【但有所不同,

关键词: