记一次mysql数据库存储过程递归调用的开发


mysql不允许函数递归调用,所以创建的是存储过程。

整个功能由两个存储过程A和B实现,A调用B,然后B递归调用自己。

业务逻辑就不描述了,本文主要记录语法,包括变量的定义和赋值,游标的开启和关闭,以及存储过程之间的调用。

存储过程A:

 1 CREATE PROCEDURE `get_vip_top_agency`()
 2 BEGIN
 3   declare done int default 0;
 4   declare uid bigint;
 5   declare parent_type int;
 6   declare parent_id bigint;
 7 
 8   declare bz_cursor cursor for (
 9     select um.uid, um.parent_type, um.parent_id from user_member um where um.level=2 and um.parent_id is not null and um.agency_id is null order by um.id
10   );
11 
12   declare continue handler for not found set done=1;
13 
14   open bz_cursor;
15 
16   repeat
17     fetch bz_cursor into uid, parent_type, parent_id;
18     if done=0 then
19       call vip_top_tid(uid, @top_tid); #此处调用存储过程B
20       if @top_tid is not null and @top_tid!=0 then
21         select atri.aid into @top_aid from agency_terminal_relevancy_info atri where atri.tid=@top_tid limit 1;
22         if @top_aid is not null then
23           update user_member um set um.terminal_id=@top_tid, um.agency_id=@top_aid where um.uid=uid;
24         end if;
25       end if;
26     end if;
27   until done end repeat;
28 
29   close bz_cursor;
30 END

存储过程B:

 1 CREATE PROCEDURE `vip_top_tid`(IN `uid` bigint,OUT `top_tid` bigint)
 2 BEGIN
 3   select um.parent_type, um.parent_id into @ptype, @pid from user_member um where um.uid=uid;
 4   if @pid is null then
 5     set top_tid=0;
 6   elseif @ptype=2 then
 7     set top_tid=@pid;
 8   elseif @ptype=1 then
 9     call vip_top_tid(@pid, @tt); #此处B存储过程递归调用自己
10     set top_tid=@tt;
11   else
12     set top_tid=0;
13   end if;
14 END

最终使用时,手动执行存储过程A即可。

set global log_bin_trust_function_creators=1; #创建存储过程时可能需要将创建者设置为信任
set max_sp_recursion_depth=10; #设置递归调用深度
call get_vip_top_agency(); #手动调用存储过程A