欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

mysql的存储过程、游标 、事务实例详解

程序员文章站 2022-06-29 14:45:39
mysql的存储过程、游标 、事务实例详解 下面是自己曾经编写过的mysql数据库存储过程,留作存档,以后用到的时候拿来参考。 其中,涉及到了存储过程、游标(双层循环)...

mysql的存储过程、游标 、事务实例详解

下面是自己曾经编写过的mysql数据库存储过程,留作存档,以后用到的时候拿来参考。

其中,涉及到了存储过程、游标(双层循环)、事务。

【说明】:代码中的注释只针对当时业务而言,无须理会。

代码如下:

delimiter $$
drop procedure if exists `transferemailtempdata`$$

create procedure transferemailtempdata(in jobid varchar(24))
begin
  declare idval varchar(24) default '';
  declare taskidval varchar(24) default '';
  declare groupidval varchar(24) default '';
  declare emailval varchar(50) default '';
  
  /*标识正式表是否存在一条相同数据,即:groupid、email相同*/
  declare infoid varchar(24) default '';
  
  /*标识事务错误*/
  declare err int default 0;
  
  /*达到一定数量就进行提交,计数器*/
  declare counts int default 0;
  
  /*标识是否回滚过*/
  declare isrollback int default 0;
  
  /*游标遍历时,作为判断是否遍历完全部记录的标记*/
  declare done integer default 0;
  
  /*获取临时表该任务的数据*/
  declare cur cursor for select id,taskid,groupid,email from `t_email_data_temp` where taskid=jobid;
  
  /*根据群组id、email查询是否存在相同记录*/
  declare cur2 cursor for select id from `t_email_info` e where e.`group_id` = groupidval and e.`email_address` = emailval; 
  
  /* 出现错误,设置为1,只要发生异常就回滚*/
  declare continue handler for sqlexception set err=1;
  
  /*声明当游标遍历完全部记录后将标志变量置成某个值*/
  declare continue handler for not found
  set done=1;
  
  /*开启事务*/
  start transaction;
  
  /*打开游标*/
  open cur;
  
  /*使用loop循环遍历*/
  out_loop:loop
  
    /*将每一条结果对应的字段值赋值给变量*/
    fetch cur into idval,taskidval,groupidval,emailval;
    if done = 1 then
      leave out_loop;
    end if;
    
    /*打开第二个游标*/
    open cur2;
      set done = 0;
      fetch cur2 into infoid;
      
      /*如果正式表不存在相同groupid and email记录,添加到正式表*/
      if done = 1 then
      
        /*插入正式表*/
        insert into `t_email_info` values(idval,emailval,groupidval,0,'',now(),'admin',now(),'admin');
        
        /*删除临时数据*/
        delete from `t_email_data_temp` where id = idval;
        
        /*计数器,每1000条才提交*/
        set counts = counts + 1;
        
        /*发生异常,回滚*/
        if err=1 then
          set isrollback=1;
          rollback;
        else
          if counts = 1000 then
            commit;
            /*达到1000条提交后,重置计数器*/
            set counts=0;
          end if;
        end if;
      else
        /*已经存在相同记录,则删除该记录*/
        if done=0 then
          delete from `t_email_data_temp` where id = idval;
        end if;
      end if;
      fetch cur2 into infoid;
    close cur2;
    
    /*控制外部的循环,该步骤不能缺少,否则只循环一次就结束了*/
    set done=0;
    
  end loop out_loop;
  close cur;
  
  /*如果没有发生过回滚事件,则更新task状态*/
  /*如果回滚过,不更新task状态,下次执行任务的时候,会再次将剩余没有提交的数据进行添加到正式表*/
  if isrollback=0 then
    update `t_email_task` t set t.`if_finish` = 1 where t.`id`=jobid;
  end if;
  
  end$$

delimiter ;

以上就是mysql的存储过程、游标 、事务的讲解,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!