MySQL-8 存储过程和函数 流程控制结构

变量

  • 分类
    • 系统变量:系统提供的
      • 全局变量
      • 会话变量
    • 自定义变量
      • 用户变量
      • 局部变量

系统变量

  • 说明:变量由系统提供,不是用户定义,属于服务器层面.
  • 注意:如果是全局级别,则需要加global,如果是会话级别,则需要加session,如果不写,则默认session.
  • 使用的语法:
    • 查看所有的系统变量:show session/global variables;session可省略
    • 查看满足条件的部分系统变量:show global/session variables like ‘%char%’;
    • 查看指定的某个系统变量的值:select @@global/session.系统变量名;
    • 为某个系统变量赋值:set global/session 系统变量名 = 值; 或 set @@global/session.系统变量名=值;

全局变量

  • 作用域:服务器每次启动将为所有的全局变量赋初始值,针对于所有的会话(连接)有效,但不能跨域重启.
    演示全局变量
# 查看所有的全局变量
show global variables;
# 查看部分的全局变量
show global variables like '%char%';
# 查看指定的全局变量的值
select @@global.autocommit;
select @@global.tx_isolation;
# 为某个指定的全局变量赋值
set @@global.autocommit=0;

会话变量

会话变量的演示

  • 作用域:仅针对于当前会话(连接)有效
# 查看所有的会话变量
show session variables;#session可以省略
# 查看部分的会话变量
show variables like '%char%';
show session variables like '%char%';
# 查看指定的某个会话变量
select @@tx_isolation;
select @@session.tx_isolation;
# 为某个会话变量赋值
# 方式一:
set @@session.tx_isolation='read-uncommitted';
# 方式二:
set session tx_isolation ='read-committed';

自定义变量

自定义用户变量

  • 说明:变量是用户自定义的,不是由系统
  • 使用步骤:声明,赋值,使用(查看,比较,运算等)

用户变量

  • 作用域:针对于当前会话(连接) 有效,同于系统变量中会话变量的作用域
  • 应用在任何地方,也就是begin end里面或begin end外面
# 赋值的操作符: =或:=
# 声明并初始化 
set @用户变量名=;
set @用户变量名:=;
select @用户变量名:=;
# 赋值(更新用户变量的值
# 方式一:通过set或select
set @用户变量名=;
set @用户变量名:=;
select @用户变量名:=;
set @name='john';
set @name=100;
set @count=1;
# 方式二:通过select into
select 字段 into @变量名 from;
select count(*) into @count from;

# 使用(查看用户变量的值)
select @用户变量名;
select @count;
)

局部变量

局部变量

  • 作用域:仅仅在定义它的begin end中有效
  • 应用在begin end中的第一句话.
# 声明
declare 变量名 类型;
declare 变量名 类型 default;
# 赋值
# 方式一:通过set或select
set 局部变量名=;
set 局部变量名:=;
select @局部变量名:=;
# 方式二:通过select into
select 字段 into 局部变量名 from;

# 使用
select 局部变量名;

对比用户变量和局部变量

  • 作用域:用户变量(针对当前会话),局部变量(begin end中的)
  • 定义和使用的位置:用户变量(会话中的任何地方),局部变量(只能在begin end中,且为第一句话)
  • 语法:用户变量(需要加上@符号,不用限定类型),局部变量(一般不用加@符号,需要限定类型)
# 声明两个变量并赋初始值,求和,并打印
# 用户变量
set @m=1;
set @n=2;
set @sum=@m+@n;
select @sum; 
# 局部变量(报错,没有在begin end中)
declare m int default 1;
declare n int default 2;
declare sum int;
set sum=m+n;
select sum;

存储过程

  • 存储过程:含义:一组预先编译好的sql语句的集合,理解成批处理语句
  • 好处:(简单,安全,性能更高)
    1. 提高了代码的重用性
    2. 简化操作
    3. 减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率.
  • 编写存储过程需要有很强大的经验.

创建语法

create procedure 存储过程名(参数列表)
begin
存储过程体(一组合法的sql语句)
end
  • 注意:
    • 参数列表包含三部分:参数模式 参数名 参数类型
    • 参数模式:
      • in:进,该参数可以作为输入,也就是说该参数需要调用方传入值
      • out:出,该参数可以作为输出,也就是该参数可以作为返回值
      • inout:进出,该参数既可以作为输入又可以作为输出,也就是该参数既需要传入值,又可以返回值.
    • 如果存储过程体仅仅只有一句话,begin end可以省略
    • 存储过程体中的每条sql语句的结尾要求必须加分号.
    • 存储过程的结尾可以使用delimiter重新设置
# 举例
in stuname varchar(20)

delimiter 结束标记
delimiter $

调用语法

call 存储过程名(实参列表);

存储过程的创建与调用

# 1.空参列表
# 插入到admin表中五条记录(一般插入上万条)
select * from admin;
delimiter $
create procedure myp1()
begin
insert into admin(username,'password') values('john1','0000'),('joly','0000'),('joer','0000'),('jack','0000'),('tom','0000');
end $
# 调用
call myp1()$

# 2.创建带in模式参数的存储过程
# 创建存储过程实现:根据女生名,查询对应的男生信息
delimiter $
create procedure myp2(in beautyname varchar(20))
begin
select bo.* from boys bo right join beauty b on bo.id=b.id where b.name=beautyname;
end $
# 调用
call myp2('团子')$
# 创建存储过程,实现用户是否登录成功
delimiter $
create procedure myp3(in username varchar(20),in password varchar(20))
begin
declare result int default 0;# 声明并初始化变量
select count(*) into result # 赋值
from admin 
where admin.username=username and admin.password=password;
select if(result>0,'成功','失败');# 使用
end $
# 调用
call myp3('张飞','8888')$ 

# 3.创建带out模式的存储过程
# 单个返回举例:根据女生名,返回对应的男生名
create procedure myp5(in beautyname varchar(20),out boyname varchar(20))
begin
select bo.name into boyname from boys bo inner join beauty b on bo.id=b.id where b.name=beautyname;
end$
# 调用
set @bname$
call myp5('小昭',@bname)$
select @bname$
# 返回多个:根据女生名,返回对应的男生名和魅力值
create procedure myp6(in beautyname varchar(20),out boyname varchar(20),out userCP int)
begin
select bo.name,bo.userCP into boyname,userCP from boys bo inner join beauty b on bo.id=b.id where b.name=beautyname;
end$
# 调用
call myp6('小昭',@bname,@userCP)$
select @bname,@userCP$

# 4.创建带inout模式参数的存储过程
# 传入a和b两个值,最终a和b都翻倍并返回
create procedure myp8(inout a int,inout b int)
begin
set a=a*2;
set b=b*2;
end$
# 调用
# 定义两个用户变量
set @m=10$
set @n=20$
call myp8(@m,@n)$
select @m,@n$

存储过程的练习

练习题

存储过程的删除

  • 一次只能删除一个.
  • 语法:
drop procedure 存储过程名

存储过程的查看

  • 查看存储过程的信息,结构
show create procedure 存储过程名;

存储过程的练习案例

练习案例

函数

  • 含义:一组预先编译好的sql语句的集合,理解成批处理语句
  • 好处:(简单,安全,性能更高)
    1. 提高了代码的重用性
    2. 简化操作
    3. 减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率.

函数和存储过程的区别

  • 存储过程:可以有0个返回,也可以有多个返回,适合做批量插入,批量更新
  • 函数:有且仅有1个返回,适合做处理数据后返回一个结果

函数创建和调用的语法

  • 创建语法
create function 函数名(参数列表) returns 返回类型
begin
函数体
end	 

# 注意:	参数列表包含两部分:参数名 参数类型
# 		函数体:肯定会有return语句,如果没有会报错,
#		如果return语句没有放在函数体的最后也不报错,但不建议
return;
#		函数体中仅有一句话时,则可以省略begin end
#		使用delimiter语句设置结束标记
  • 调用语法
select 函数名(参数列表);
  • 练习
# 无参有返回
# 返回公司的员工个数
create function myf1() returns int
begin
declare c int default 0;#定义变量
select count(*) into c#给变量赋值
from 表名;	
return c;
end$
select myf1()$

# 有参有返回
# 根据员工名,返回他的工资
create function myf2(empname varchar(20)) returns double
begin
set @sal=0;#定义用户变量
select salary into @sal#赋值
from 表名
where last_name=empname;
return @sal;
end$
select myf2('k_ing')$
#根据部门名,返回该部门的平均工资
create function myf3(deptname varchar(20)) returns double
begin
declare sal double;
select avg(salary) into sal
from employees e 
inner join departments d on e.id=d.id
where d.dname=deptname;
return sal;
end$
select myf3('IT')$

查看函数

show create function myf3;

删除函数

drop function myf3;

练习函数的使用

# 创建函数,实现传入两个float,返回二者之和
create function test_fun1(num1 float,num2 float) returns float
begin
declare sum float default 0;
set sum=num1+sum2;
return sum;
end$

select test_fun1(1,2)$

流程控制结构

  1. 顺序结构:程序从上往下依次执行
  2. 分支结构:程序从两条或多条路径中选择一条去执行
  3. 循环结构:程序在满足一定条件的基础上,重复执行一段代码

分支结构

  1. if函数
  • 功能:实现简单的双分支
  • 语法:
    if(表达式1,表达式2,表达式3)
    执行顺序,如果表达式1成立,则if函数返回表达式2的值,否则返回表达式3的值.
  • 应用:任何地方
  1. case结构
  • 情况1 :类似于java中的switch语句,一般用于实现等值判断

  • 语法:
    case 变量/表达式/字段
    when 要判断的值 then 返回的值1或语句1 ;
    when 要判断的值 then 返回的值2或语句2;

    else 要返回的值n或语句n;
    end case;

  • 情况2: 类似于java中的多重if语句,一般用于实现区间判断

  • 语法:
    case
    when 要判断的条件1 then 返回的值1或语句1;
    when 要判断的条件2 then 返回的值2或语句2;

    else 要返回的值n或语句n;
    end case;

  • case结构特点:

    1. 可以做为表达式,嵌套在其他语句中使用,可以放在任何地方,begin end 中或begin end 的外面
    2. 可以作为独立的语句去使用,只能放在begin end中
    3. 如果when中的值满足或条件成立,则执行对应的then后面的语句,并且结束case
    4. 如果不满足,则执行else中的语句或值
    5. else可以省略,如果else省略了,并且所有then条件都不满足,则返回null
  • case结构作为表达式
    在这里插入图片描述

  • case结构作为独立的语句
    在这里插入图片描述

  • 练习case结构

# 创建存储过程,根据传入的成绩,来显示等级,比如传入的成绩:90-100显示A,80-90显示B,60-80显示C,否则显示D
delimiter $
create procedure test_case(in score int)
begin
case
when score>=90 and score <=100 then select 'A';
when score>=80 then select 'B';
when score>=60 then select 'C';
else select 'D';
end case;
end$
call test_case(95)$

if结构

  • 功能:实现多重分支
  • 语法:
if 条件1 then 语句1;
elseif 条件2 then 语句2;
...
else 语句n;#最后这句可以省略
end if;
  • 应用场合:应用在begin end中
# 案例
# 创建存储过程,根据传入的成绩,来显示等级,比如传入的成绩:90-100返回A,80-90返回B,60-80返回C,否则返回D
delimiter $
create function test_if(score int) returns char
begin
if score>=90 and score<=100 then return 'A';
elseif score>=80 then return 'B';
elseif score>=60 then return 'C';
else return 'D';
end if;
end $

循环结构

  • 分类:while,loop,repeat
  • 循环控制:
    • iterate类似于 continue,继续,结束本次循环,继续下一次
    • leave类似于break,跳出,结束当前所在的循环

while

  • 语法:
标签:while 循环条件 do
循环体
end while 标签;
  • loop语法:
标签:loop
循环体;
end loop 标签;
# 可以用来模拟简单的死循环,要跳出需要搭配leave
  • repeat语法:
标签:repeat
循环体;
until 结束循环的条件
end repeat 标签;
# 类似于dowhile,先执行一次

循环结构的演示

# 没有添加循环控制语句
# 批量插入,根据次数插入到admin表中多条记录
create procedure pro_while1(in insertCount int)
begin
	declare i int default 1;
	while i<=insertCount do
		insert into admin(username,`password`)values(count('rose',i),'666');
		set i=i+1;
		end while;
end $
call pro_while1(100)$

# 添加leave语句
# 批量插入,根据次数插入到admin表中多条记录,如果次数>20则停止.
truncate table admin$
drop procedure test_while1$
create procedure test_while1(in insertCount int)
begin
	declare i int default 1;
	a:while i<=insertCount do
		insert into admin(username,`password`)values(count('xiaoli',i),0000);
		if i>=20 then leave a;
		end if;
		set i=i+1;
	end while a;
end$
call test_while1(100)$

# 添加iterate语句
# 批量插入,根据次数插入到admin表中多条记录,只插入偶数次
truncate table admin$
drop procedure test_while1$
create procedure test_while1(in insertCount int)
begin
	declare i int default 0;
	a:while i<=insertCount do
		set i=i+1;
		if mod(i,2)!=0 then iterate a;
		end if;
		insert into admin(username,`password`)values(count('xiaoli',i),0000);
		end while a;
end$
call test_while1(100)$

循环结构总结

总结:while,repeat,loop
在这里插入图片描述

流程控制经典案例

流程控制经典案例讲解

复习变量,存储过程和函数,流程控制结构(分支结构,循环结构)

复习变量,存储过程,函数,流程控制结构(分支结构,循环结构)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悠哉悠哉'游仙儿

您的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值