♥️作者:小刘在C站 ♥️个人主页: 小刘主页 ♥️努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生! ♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏:云计算技术 ♥️小刘私信可以随便问,只要会
♥️作者:小刘在C站
♥️个人主页: 小刘主页
♥️努力不一定有回报,但一定会有收获加油!一起努力,共赴美好人生!
♥️学习两年总结出的运维经验,以及思科模拟器全套网络实验教程。专栏:云计算技术
♥️小刘私信可以随便问,只要会绝不吝啬,感谢CSDN让你我相遇!
前言
上章讲到MySQL-SQL存储过程/触发器详解(上)本章继续
目录
IF 条件1 THEN.....ELSEIF 条件2 THEN -- 可选.....ELSE -- 可选.....END IF;
在 if 条件判断的结构中, ELSE IF 结构可以有多个,也可以没有。 ELSE 结构可以有,也可以没有。 create procedure p3()begindeclare score int default 58;declare result varchar(10);if score >= 85 thenset result := '优秀';elseif score >= 60 thenset result := '及格';elseset result := '不及格';end if;select result;end;call p3();
上述的需求我们虽然已经实现了,但是也存在一些问题,比如: score 分数我们是在存储过程中定义死的,而且最终计算出来的分数等级,我们也仅仅是最终查询展示出来而已。 那么我们能不能,把 score 分数动态的传递进来,计算出来的分数等级是否可以作为返回值返回呢?答案是肯定的,我们可以通过接下来所讲解的 参数 来解决上述的问题。 、 CREATE PROCEDURE 存储过程名称 ([ IN/OUT/INOUT 参数名 参数类型 ])BEGIN-- sql语句END ;
create procedure p4(in score int, out result varchar(10))beginif score >= 85 thenset result := '优秀';elseif score >= 60 thenset result := '及格';elseset result := '不及格';end if;end;-- 定义用户变量 @result来接收返回的数据, 用户变量可以不用声明call p4(18, @result);select @result;
将传入的200分制的分数,进行换算,换算成百分制,然后返回。
create procedure p5(inout score double)beginset score := score * 0.5;end;set @score = 198;call p5(@score);select @score;
-- 含义: 当case_value的值为 when_value1时,执行statement_list1,当值为 when_value2时,执行statement_list2, 否则就执行 statement_listCASE case_valueWHEN when_value1 THEN statement_list1[ WHEN when_value2 THEN statement_list2] ...[ ELSE statement_list ]END CASE;
-- 含义: 当条件search_condition1成立时,执行statement_list1,当条件search_condition2成立时,执行statement_list2, 否则就执行 statement_listCASEWHEN search_condition1 THEN statement_list1[WHEN search_condition2 THEN statement_list2] ...[ELSE statement_list]END CASE;
create procedure p6(in month int)begindeclare result varchar(10);casewhen month >= 1 and month <= 3 thenset result := '第一季度';when month >= 4 and month <= 6 thenset result := '第二季度';when month >= 7 and month <= 9 thenset result := '第三季度'; when month >= 10 and month <= 12 thenset result := '第四季度';elseset result := '非法参数';end case ;select concat('您输入的月份为: ',month, ', 所属的季度为: ',result);end;call p6(16);
如果判定条件有多个,多个条件之间,可以使用 and 或 or 进行连接。 -- 先判定条件,如果条件为true,则执行逻辑,否则,不执行逻辑WHILE 条件 DOSQL逻辑...END WHILE;
-- A. 定义局部变量, 记录累加之后的值;-- B. 每循环一次, 就会对n进行减1 , 如果n减到0, 则退出循环create procedure p7(in n int)begindeclare total int default 0;while n>0 doset total := total + n;set n := n - 1;end while;select total;end;call p7(100);
-- 先执行一次逻辑,然后判定UNTIL条件是否满足,如果满足,则退出。如果不满足,则继续下一次循环REPEATSQL逻辑...UNTIL 条件END REPEAT;
-- A. 定义局部变量, 记录累加之后的值;-- B. 每循环一次, 就会对n进行-1 , 如果n减到0, 则退出循环create procedure p8(in n int)begindeclare total int default 0;repeatset total := total + n;set n := n - 1;until n <= 0end repeat;select total;end;call p8(10);call p8(100);
[begin_label:] LOOPSQL逻辑...END LOOP [end_label];
LEAVE label; -- 退出指定标记的循环体ITERATE label; -- 直接进入下一次循环
上述语法中出现的 begin_label , end_label , label 指的都是我们所自定义的标记。 -- A. 定义局部变量, 记录累加之后的值;-- B. 每循环一次, 就会对n进行-1 , 如果n减到0, 则退出循环 ----> leave xxcreate procedure p9(in n int)begindeclare total int default 0;sum:loopif n<=0 thenleave sum;end if;set total := total + n;set n := n - 1;end loop sum;select total;end;call p9(100);
-- A. 定义局部变量, 记录累加之后的值;-- B. 每循环一次, 就会对n进行-1 , 如果n减到0, 则退出循环 ----> leave xx-- C. 如果当次累加的数据是奇数, 则直接进入下一次循环. --------> iterate xxcreate procedure p10(in n int)begindeclare total int default 0;sum:loopif n<=0 thenleave sum;end if;if n%2 = 1 thenset n := n - 1;iterate sum;end if;set total := total + n;set n := n - 1;end loop sum;select total;end;call p10(100);
DECLARE 游标名称 CURSOR FOR 查询语句 ;
OPEN 游标名称 ;
FETCH 游标名称 INTO 变量 [, 变量 ] ;
CLOSE 游标名称 ;
-- 逻辑:-- A. 声明游标, 存储查询结果集-- B. 准备: 创建表结构-- C. 开启游标-- D. 获取游标中的记录-- E. 插入数据到新表中-- F. 关闭游标create procedure p11(in uage int)begindeclare uname varchar(100);declare upro varchar(100);declare u_cursor cursor for select name,profession from tb_user where age <=uage;drop table if exists tb_user_pro;create table if not exists tb_user_pro(id int primary key auto_increment,name varchar(100),profession varchar(100));open u_cursor;while true dofetch u_cursor into uname,upro;insert into tb_user_pro values (null, uname, upro);end while;close u_cursor;end;call p11(30);
上述的存储过程,最终我们在调用的过程中,会报错,之所以报错是因为上面的 while 循环中,并没有退出条件。当游标的数据集获取完毕之后,再次获取数据,就会报错,从而终止了程序的执行。 但是此时, tb_user_pro 表结构及其数据都已经插入成功了,我们可以直接刷新表结构,检查表结构中的数据。
上述的功能,虽然我们实现了,但是逻辑并不完善,而且程序执行完毕,获取不到数据,数据库还报错。 接下来,我们就需要来完成这个存储过程,并且解决这个问题。 要想解决这个问题,就需要通过 Mysql 中提供的 条件处理程序 Handler 来解决。
DECLARE handler_action HANDLER FOR condition_value [, condition_value]... statement ;handler_action 的取值:CONTINUE: 继续执行当前程序EXIT: 终止执行当前程序condition_value 的取值:SQLSTATE sqlstate_value: 状态码,如 02000SQLWARNING: 所有以01开头的SQLSTATE代码的简写NOT FOUND: 所有以02开头的SQLSTATE代码的简写SQLEXCEPTION: 所有没有被SQLWARNING 或 NOT FOUND捕获的SQLSTATE代码的简写
-- 逻辑:-- A. 声明游标, 存储查询结果集-- B. 准备: 创建表结构-- C. 开启游标-- D. 获取游标中的记录-- E. 插入数据到新表中-- F. 关闭游标create procedure p11(in uage int)begindeclare uname varchar(100);declare upro varchar(100);declare u_cursor cursor for select name,profession from tb_user where age <=uage;-- 声明条件处理程序 : 当SQL语句执行抛出的状态码为02000时,将关闭游标u_cursor,并退出declare exit handler for SQLSTATE '02000' close u_cursor;drop table if exists tb_user_pro;create table if not exists tb_user_pro(id int primary key auto_increment,name varchar(100),profession varchar(100));open u_cursor;while true dofetch u_cursor into uname,upro;insert into tb_user_pro values (null, uname, upro);end while;close u_cursor;end;call p11(30);
B. 通过 SQLSTATE 的代码简写方式 NOT FOUND 02 开头的状态码,代码简写为 NOT FOUND create procedure p12(in uage int)begindeclare uname varchar(100);declare upro varchar(100);declare u_cursor cursor for select name,profession from tb_user where age <=uage;-- 声明条件处理程序 : 当SQL语句执行抛出的状态码为02开头时,将关闭游标u_cursor,并退出declare exit handler for not found close u_cursor;drop table if exists tb_user_pro;create table if not exists tb_user_pro(id int primary key auto_increment,name varchar(100),profession varchar(100));open u_cursor;while true dofetch u_cursor into uname,upro;insert into tb_user_pro values (null, uname, upro);end while;close u_cursor;end;call p12(30);
♥️关注,就是我创作的动力
♥️点赞,就是对我最大的认可
♥️这里是小刘,励志用心做好每一篇文章,谢谢大家
来源地址:https://blog.csdn.net/lzl10211345/article/details/131353327
--结束END--
本文标题: MySQL-SQL存储过程/触发器详解(下)
本文链接: https://www.lsjlt.com/news/387685.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-05-21
2024-05-21
2024-05-21
2024-05-21
2024-05-21
2024-05-21
2024-05-21
2024-05-21
2024-05-21
2024-05-21
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0