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

mysql的存储过程、游标 、事务实例详解 下面是自己曾经编写过的mysql数据库存储过程,留作存档,以后用到的时候拿来参考。 其中,涉及到了存储过程、游标(双层循环)、事务。 【

                        <p>mysql的存储过程、游标 、事务实例详解</p>

下面是自己曾经编写过的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的存储过程、游标 、事务的讲解,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!