MySQL中的变量定义与赋值

2022-12-16 0 677

表明:那时市售表述表达式的讲义和书刊基本上都放到储存操作过程上表明,但储存操作过程上表达式根本无法促进作用作begin…end块中,而通常的表达式表述和采用都说的较为少,特别针对这类难题根本无法在非官方文件格式中就可以找出传授。

序言

MySQL储存操作过程中,表述表达式有三种形式:

1、采用set或select间接表达式,表达式名以@结尾

比如说:
set @var=1;

能在两个程序标识符的任何人地方性新闻稿,返回值是整座程序标识符,称作使用者表达式。

2、以declareURL新闻稿的表达式,根本无法在储存操作过程中采用,称作储存操作过程表达式,比如说:
declare var1 int default 0;

主要就用在储存操作过程中,或是是给储存传模块中。

二者的差别是:

在初始化储存操作过程时,以declare新闻稿的表达式单厢被初始化为null。而程序标识符表达式(即@结尾的表达式)则不能被再初始化,在两个程序标识符内,须要初始化一场,后在程序标识符内都是对上一场排序的结论,就相等于在是那个程序标识符内的全局表达式。

市场主体文本

局部表达式使用者表达式程序标识符表达式全局表达式程序标识符表达式和全局表达式叫控制系统表达式。

一、局部表达式,只在现阶段begin/end标识符块中有效率

局部表达式通常用在sql句子块中,比如说储存操作过程的begin/end。其返回值仅指该句子块,在该句子块继续执行完后,局部表达式就消亡了。declare句子专门针对用作表述局部表达式,能采用default来表明缺省。set句子是增设相同类别的表达式,主要就包括程序标识符表达式和全局表达式。

局部表达式表述句法形式
declare var_name [, var_name]… data_type [ DEFAULT value ];

比如说在begin/end句子块中添加如下一段句子,接受函数传进来的a/b表达式然后相加,通过set句子赋值给c表达式。

set句子句法形式set var_name=expr [, var_name=expr]…; set句子既能用作局部表达式的表达式,也能用作使用者表达式的申明并表达式。
declare c int default 0; set c=a+b; select c as C;

或是用select …. into…形式表达式

select into 句子句式:select col_name[,…] into var_name[,…] table_expr [where…]; 例子:

例子:

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;

二、使用者表达式,在客户端链接到数据库实例整座操作过程中使用者表达式都是有效率的。

MySQL中使用者表达式不用事前申明,在用的时候间接用“@表达式名”采用就能了。

第一种用法:set @num=1; 或set @num:=1; //这里要采用set句子创建并初始化表达式,间接采用@num表达式

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

select句子通常用来输出使用者表达式,比如说select @表达式名,用作输出数据源不是表格的数据。

注意上面三种表达式符号,采用set时能用“=”或“:=”,但采用select时必须用“:=表达式”

使用者表达式与数据库连接有关,在连接中新闻稿的表达式,在储存操作过程中创建了使用者表达式后一直到数据库实例接断开的时候,表达式就会消亡。

在此连接中新闻稿的表达式无法在另一连接中采用。

使用者表达式的表达式名的形式为@varname的形式。

名字必须以@结尾。

新闻稿表达式的时候需要采用set句子,比如说下面的句子新闻稿了两个名为@a的表达式。

set @a = 1;

新闻稿两个名为@a的表达式,并将它表达式为1,MySQL里面的表达式是不严格限制数据类别的,它的数据类别根据你赋给它的值而随时变化 。(SQL SERVER中采用declare句子新闻稿表达式,且严格限制数据类别。)

我们还能采用select句子为表达式表达式 。

比如说:

set @name = ; select @name:=password from user limit 0,1;

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

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

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

使用者表达式能促进作用作现阶段整座连接,但当现阶段连接断开后,其所表述的使用者表达式单厢消亡。

使用者表达式采用如下(我们无须采用declareURL对用户表达式进行表述,能间接这样采用)表述,表达式名必须以@开始:
#表述 select @表达式名 或是 select @表达式名:= 字段名 from 表名 where 过滤句子; set @表达式名; #表达式 @num为表达式名,value为值set @num=value;select @num:=value;

对使用者表达式表达式有三种形式,一种是间接用”=”号,另一种是用”:=”号。其差别在于采用set命令对使用者表达式进行表达式时,三种形式都能采用;当采用select句子对使用者表达式进行表达式时,根本无法采用”:=”形式,因为在select句子中,”=”号declare句子专门针对用作表述局部表达式。set句子是增设相同类别的表达式,主要就包括程序标识符表达式和全局表达式。

比如说:
begin #Routine body goes here… #select c as c; declare c int default 0; set @var1=143; #表述两个使用者表达式,并初始化为143set @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;

在继续执行完order储存操作过程后,在储存操作过程中新建的var1,var2使用者表达式还是能用select句子输出的,但储存操作过程里面表述的局部表达式c不能识别。

控制系统表达式:

控制系统表达式又分为全局表达式与程序标识符表达式。

全局表达式在MySQL启动的时候由服务器自动将它们初始化为缺省,这些缺省能通过更改my.ini那个文件来更改。

程序标识符表达式在每次建立两个新的连接的时候,由MySQL来初始化。MySQL会将现阶段所有全局表达式的值复制一份。来做为程序标识符表达式。

(也就是说,如果在建立程序标识符以后,没有手动更改过程序标识符表达式与全局表达式的值,那所有这些表达式的值都是一样的。)

全局表达式与程序标识符表达式的差别就在于,对全局表达式的修改会影响到整座服务器,但对程序标识符表达式的修改,只会影响到现阶段的程序标识符(也就是现阶段的数据库连接)。

我们能利用
show session variables;

句子将所有的程序标识符表达式输出(能简写为show variables,没有指定是输出全局表达式还是程序标识符表达式的话,默认就输出程序标识符表达式。)如果想输出所有全局表达式:

show global variables

有些控制系统表达式的值是能利用句子来动态进行更改的,但有些控制系统表达式的值却是只读的。

对于那些能更改的控制系统表达式,我们能利用set句子进行更改。

控制系统表达式在表达式名前面有两个@;

如果想要更改程序标识符表达式的值,利用句子:
set session varname = value; 或是 set @@session.varname = value;

比如说:

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;

不过要想更改全局表达式的值,需要拥有super权限 。

(注意,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那个URL来代替。

比如说:
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; #缺省sessionURL默认认为是session 查看所有的会话表达式 show session variables;

查看两个程序标识符表达式也有如下三种形式:

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

凡是上面提到的session,都能用local那个URL来代替。

比如说:
select @@local.sort_buffer_size local是session的近义词

四、全局表达式

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

要增设两个全局表达式,有如下三种形式:
set global var_name = value; //注意:此处的global不能省略。根据手册,set命令增设表达式时若不指定GLOBALSESSION或是LOCAL,默认采用SESSION set @@global.var_name = value; //同上

查看所有的全局表达式

show global variables;

要想查看两个全局表达式,有如下三种形式:

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

关于mysql中下标的难题limit 是从0开始的,substring是从1开始的

转自原文:

MySQL中的表达式表述与表达式(干货)_sunwenxu的博客-CSDN博客_mysql 表达式表达式blog.csdn.net/qq_35495339/article/details/89160610MySQL中的变量定义与赋值

使用者表达式

SET 形式

# 三种形式都能 SET @variable = expr SET @variable := expr

SELECT 形式

# 必须 := SELECT @variable := expr

示例

我们来两个简单的示例,实现两个序号的功能,表和数据如下:

CREATE TABLE employee ( id int primary key, salary int not null ); INSERT INTO employee VALUES(1, 100); INSERT INTO employee VALUES(2, 200); INSERT INTO employee VALUES(3, 300);

根据之前学习的文本,我们能很快的写出如下 SQL:

SELECT salary, (@rowno := @rowno + 1) AS rowno FROM employee, (SELECT @rowno := 0) r; +——–+——-+ | salary | rowno | +——–+——-+ | 100 | 1 | | 200 | 2 | | 300 | 3 | +——–+——-+

没有难题,一切都和预期一样,然后我们加两个 WHERE 条件试试:

SELECT salary, (@rowno := @rowno + 1) AS rowno FROM employee, (SELECT @rowno := 0) r WHERE @rowno = 0; +——–+——-+ | salary | rowno | +——–+——-+ | 100 | 1 | +——–+——-+

理论上来说,这是不应该返回数据的,但它还就是返回了一条数据,就是 id 为 1 的那条。

为什么呢? WHERE 条件采用的 @rowno 一直都是同两个值 0 ,它不能因为 SELECT 上修改了就实时响应 。要实现 WHERE 的功能需要改写成如下:

SELECT salary, rowno FROM ( SELECT salary, (@rowno := @rowno + 1) AS rowno FROM employee, (SELECT @rowno := 0) r ) m WHERE rowno = 2; +——–+——-+ | salary | rowno | +——–+——-+ | 200 | 2 | +——–+——-+

实际上在 SELECT 的 WHERE 、 GROUP BY 和 ORDER BY 中使用者表达式都不能按预期操作,它采用的是旧值,不会实时修改

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务