在mysql数据库中,变量分为系统变量以及用户自定义变量。
系统变量由系统定义,属于服务器层面。启动mysql服务,生成mysql服务实例期间,mysql将为mysql服务器内存中的系统变量赋值。这些系统变量要么时编译mysql时参数的默认值,那么是配置文件中的参数值。可以通过网址https://dev.mysql.com/doc/refman/8.0/server-system-variables.html查看mysql文档的系统变量。
系统变量分为全局系统变量(需要添加global关键字)和会话系统变量(需要添加session关键字)。
全局系统变量又叫全局变量,会话系统变量又叫local变量。如果不写,默认会话级别。
静态变量(在mysql服务实例运行期间不能使用set动态修改)属于特殊的全局变量。
show global variables; // 查看全局系统变量
show session variables; // 查看会话系统变量
show variables; // 默认查询会话系统变量
show variables like '' // 查看部分系统变量
在mysql中系统变量以@@
开头,其中@@global
用来标记全局系统变量,@@session
用来标记会话系统变量,@@
首先标记会话系统变量,如果会话变量不存在则标记全局变量。
select @@global.变量名;
select @@session.变量名;
select @@变量名;
方式1:修改mysql的配置文件
方式2:在服务运行期间,使用set命令重新设置系统变量的值
set @@global.变量名 = 变量值
或者
set global 变量名 = 变量值
用户变量是用户自己定义的,根据作用范围不同,又分为会话用户变量和局部变量。
定义会话用户变量
方式一:set中使用 = 或 :=
set @用户变量 = 值;
set @用户变量 := 值;
方式二:select中使用 := 或into关键字
select @用户变量 := 表达式 from ...
select 表达式 into @用户变量 from ...
查看会话用户变量
select @变量名
定义局部变量
局部变量必须使用declare声明,必须在begin…end中,必须在首行的位置。
declare 变量名 类型[default 值]; // 如果没有default子句,初始值为null
定义条件
是实现定义程序执行过程中可能遇到的问题,处理程序
定义了在遇到问题时应当采取的处理方式。保证存储过程和函数在遇到警告或错误时能继续执行。
当存储过程中执行sql语句报错时,mysql数据库会抛出错误,并退出当前sql逻辑,不再向下执行。
定义条件就是给mysql中的错误命名,有助于错误更清晰。它将一个错误名字和指定的错误条件关联起来,这个名字可以再随后定义处理程序的declare handler
语句中。
declare 错误名 condition for 错误码(或错误条件)
mysql_error_code
是数值类型错误代码。sqlstate_value
是长度为5的字符串类型错误代码。例如ERROR 1418(HY000)中,1414是mysql_error_code,HY000是sqlstate_value。
可以为sql执行过程中发生的某种类型的错误定义特殊的处理程序。定义处理程序时,使用declare语句的语法如下:
declare 处理方式 handler for 错误类型 处理语句
在mysql数据库中,全局变量可以通过set global语句来设置。但是数据库重启后,服务器又会从mysql配置文件中读取变量的默认值。mysql8.0版本新增了set persist命令。
set persist max_connections = 1000;
mysql会将该命令的配置保存到数据目录下的mysqld-auto.cnf文件中,下次启动会读取该文件,用其中的配置来覆盖默认的配置文件。
解决复杂问题不可能只通过一个sql语句完成,我们需要执行多个sql操作。流程控制语句的作用就是控制存储过程中sql语句的执行顺序。
流程分为三大类:
针对mysql流程控制语句主要有3类:
if语句
if 表达式1 then 操作1
[elseif 表达式2 then 操作2]
[else 操作n]
end if
case语句
case 表达式
when 值1 then 结果1(如果是语句,需要加分号)
when 值2 then 结果2(如果是语句,需要加分号)
...
else 结果n或语句n
end [case] (如果是在begin end中需要加上case,如果放在select后面不需要)
case
when 条件1 then 结果1(如果是语句,需要加分号)
when 条件2 then 结果2(如果是语句,需要加分号)
...
else 结果n或语句n
end [case] (如果是在begin end中需要加上case,如果放在select后面不需要)
loop循环语句用来重复执行某些语句。loop内的语句一直重复执行直到循环被退出(遇到leave子句),跳出循环。
[loop_label:] Loop
循环执行的语句
end loop [loop_label]
[while_label:] while 循环条件 do
循环执行的语句
end while [while_label]
[repeat_label:] repeat
循环执行的语句;
until 循环语句结束条件表达式 end repeat [repeat_label]
loop一般用于实现简单”死循环“;while先判断后执行;repeat先执行后判断,无条件至少执行一次;
leave 标记名
可以跳出循环或者跳出程序体,相当于break;
iterate 标记名
跳过当前循环,相当于continue;
游标可以在结果集中像指针一样,向前定位一条记录,向后一条记录或者随意定位一条记录。
在mysql中,使用declare关键字来声明游标,其语法基本形式如下:
declare cursor_name CURSOR FOR select_statement;
这个语法适用于mysql,sqlserver,db2和mariaDB。如果是用Oracle或者postgresql,需要写成:
declare cursor_name CURSOR IS select_statement;
打开游标的时候select语句的查询结果集就会送到游标的工作区,为后面游标的逐条读取结果集中的记录做准备。
open cursor_name;
语法如下:
FETCH cursor_name into 变量名,...
注意,游标的查询结果集中的字段数,必须跟into后面的变量数一致。变量必须在声明游标前就定义好。
游标用完后必须关闭游标,应为游标会占用系统资源。如果不及时关闭,游标会一直保存到存储过程结束,影响系统运行的效率。关闭之后,就不能检索查询结果中的数据行,如果需要检索只能再次打开游标。
close cursor_name
游标一般在循环体中使用,应为每调一次fetch都会将光标指向下一条记录。