MySQL存储过程中使用临时表、游标以及调试存储过程

tech2023-08-21  90

1、使用临时表和嵌套游标的存储过程

       最近因为业务需求原因,需要用存储过程来实现一些数据库操作,在网上看了一些大佬的相关内容

,最后写出了这个嵌套了三重游标的存储过程,不容易啊,在这里记录一下,存储过程如下:

CREATE DEFINER = 'root'@'%' PROCEDURE ddent.QUERY_FAULT(IN class_name VARCHAR(255), IN fault VARCHAR(255)) BEGIN -- 定义结束标识 由于嵌套了多层游标所有定义了多个标识 DECLARE done INT DEFAULT FALSE; DECLARE edone INT DEFAULT FALSE; DECLARE fdone INT DEFAULT FALSE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;-- 绑定当前游标的结束标识,这里需要注意的是,多个游标的绑定不能写在一起,需要在每个游标的begin end之间绑定 -- 创建临时表 create temporary table if not exists tb1 (id integer, name varchar(100), type varchar(10),f integer); -- 创建好先清空临时表 truncate TABLE tb1; BEGIN -- 定义游标遍历行的变量 declare c1_id int; declare c1_name varchar(100); declare c1_type varchar(10); declare c1_f int; declare out_id int; declare out_title VARCHAR(300); declare out_f int; -- 定义游标1以及结束标识 -- 查询知识库分类,故障分类,故障子类,取相似度最高的前十条 DECLARE cur1 CURSOR FOR ( select id,name,type,similarity(class_name,name) f from ( select id,name,'t1' type from t_know where deleted=0 and isopen=3200 and similarity(class_name,name)>=10 union all select id,name,'t2' type from t_ify where deleted=0 and similarity(class_name,name)>=10 union all select id,name,'t3' type from t_item where deleted=0 and similarity(class_name,name)>=10 ) t order by f desc limit 10 ); -- 打开游标 OPEN cur1; -- 开始循环 loop_1: LOOP # 为当循环取个别名 -- 游标每一行对应的变量,需要注意的是不能与sql中的列名一样 FETCH cur1 INTO c1_id,c1_name,c1_type,c1_f; # 使用定义好的变量对应查询语句的列 IF done THEN LEAVE loop_1;#跳出循环 ELSE set edone = false; -- 重置标识 -- 通过分类递归查询他的所有子类 if c1_type='t1' THEN #分支内容 begin declare c2_id int; # 使用定义好的变量对应查询语句的列 declare cur2 cursor for select id from t_know where FIND_IN_SET(id,fn_getKnowtypeChildids(c1_id));#通过第一条语句的结果c1_id当做条件查询,这里递归单独写了一个函数fn_getKnowtypeChildids DECLARE CONTINUE HANDLER FOR NOT FOUND SET edone = true;-- 绑定当前游标的结束标识 OPEN cur2; loop_2: LOOP fetch cur2 INTO c2_id; if edone then LEAVE loop_2; else set fdone = FALSE; begin -- 通过第二条语句返回的结果c2_id当做条件查询 -- 通过分类查询内容,将知识标题相似度大于等于10的插入到临时表中 declare cur3 cursor for select id,title,similarity(fault,title) f from t_content where deleted=0 and status=201001 and similarity(fault,title)>=10 and typeid=c2_id; DECLARE CONTINUE HANDLER FOR NOT FOUND SET fdone = true;-- 结束标识 open cur3; loop_3: loop fetch cur3 into out_id,out_title,out_f; if fdone then leave loop_3; else insert into tb1(id,name,type,f) values(out_id,out_title,'t1',out_f); #将最终需要的结果放入临时表中 end if; end LOOP loop_3; #第三层循环结束 close cur3; end; end if; end LOOP loop_2; #第二层循环结束 CLOSE cur2; #关闭第二个游标 END; elseif c1_type='t2' THEN begin -- 略 END; elseif c1_type='t3' then begin -- 略 end; end if; END IF; END LOOP loop_1; #整个大循环结束 CLOSE cur1; #关闭游标 select id, name, type, f from tb1 order by f DESC; # 返回临时表的内容 END; END

2、使用dbForge Studio for MySQL调试存储过程

下载安装

      首先推荐在官网下载:点这里,可以试用30天,不过下载速度很慢,等不了的同学可以选择其他途径,下载后直接安装即可

使用

首先连接数据库,点击 new connection 。

找到要调试的存储过程,先debug编译一下

编译后会弹出一个提示框,如果成功那就双击存储过程,会打开代码界面,在代码上打断点,然后点击step into或者按f11进入调试

 

问题

至此整个调试过程就结束了,但是当你用navicat 或者其他工具打开你的过程的时候,你会看到代码里多了一堆不是你写的代码

类似这样的

这个时候调用还是没问题的,但是这样看着也太难受了,其实只要在dbForge Studio for MySQL中再编译一下就行了,我还是用上面那种图,只要选择第一项编译(红框上面的那一项),成功后就会去掉那些代码了

到这里整个过程就结束了,第一次写这么长的博客,如果有那里有问题欢迎指正ヾ(o◕∀◕)ノヾ

最新回复(0)