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 ;
时间: 2024-10-12 21:32:42

mysql之——存储过程 + 游标 + 事务的相关文章

mysql中存储过程游标使用

mysql游标的使用能够循环获取结果级进行操作 定义游标 DECLARE id int; DECLARE name varchar(30); DECLARE cursor_name CURSOR FOR select c_id,c_name from tables (把select查询到的数据赋给游标cursor_name ) OPEN cursor_name (打开游标) FETCH cursor_name INTO id,name; (打开游标去取一条值如果该值存在,并把游标前进该行) CL

mysql存储过程之事务篇

mysql存储过程之事务篇 事务的四大特征: ACID:Atomic(原子性).Consistent(一致性).Isolated(独立性).Durable (持久性) MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关: sql代码  1. MyISAM:不支持事务,用于只读程序提高性能 2. InnoDB:支持ACID事务.行级锁.并发 3. Berkeley DB:支持事务 事务隔离级别标准: ANSI(美国国家标准学会)标准定义了4个隔离级别,MySQL的InnoDB都

Mysql存储过程包含事务,且传入sql数据执行

有一个需求是:在一个图片按钮上点击,在按钮的上方弹出一个弹框,根据弹框的内容页面做不同的显示.这个其实没什么难的,主要是要控制好弹框的显示位置,让弹框显示在图片的正上方的中间. 一开始是用的Popupwindow,但是Popupwindow不能给弹窗之外的页面加一个半透明的蒙层,当然可以在页面上加一个专门的作为蒙层的View,但是很显然,这么做会代码变得很恶心,于是又换成了Dialog,因为Dialog弹出的时候会自动加一个蒙层的,但是这个时候,弹框显示位置的Y坐标不对了,后来一顿查,原来Dia

Mysql之视图 触发器 事务 存储过程 函数

视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的临时表摘出来,用视图去实现,这样以后再想操作该临时表的数据时就无需重写复杂的sql了,直接去视图中查找即可,但视图有明显地效率问题,并且视图是存放在数据库中的,如果我们程序中使用的sql过分依赖数据库中的视图,即强耦合,那就意味着扩展sql极为不便,因此并不推荐使用 #两张有关系的表 mysql> se

mysql基础教程(四)-----事务、视图、存储过程和函数、流程控制

事务 概念 事务由单独单元的一个或多个SQL语句组成,在这 个单元中,每个MySQL语句是相互依赖的.而整个单独单 元作为一个不可分割的整体,如果单元中某条SQL语句一 旦执行失败或产生错误,整个单元将会回滚.所有受到影 响的数据将返回到事物开始以前的状态:如果单元中的所 有SQL语句均执行成功,则事物被顺利执行. 存储引擎 概念 在mysql中的数据用各种不同的技术存储 在文件(或内存)中. 查看 通过 show engines: 来查看mysql支持的存储引擎. 常见引擎 在mysql中用的

MySQL拓展 视图,触发器,事务,存储过程,内置函数,流程控制,索引,慢查询优化

视图: 1.什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次直接使用即可 2.为什么要用视图 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何使用视图 create view teacher2course as select * from teacher inner join course on teacher.tid = course.teacher_id; 强调: (1)在硬盘中,视图只有表结构文件,没有表结构数据 (2)视图通常是用于查询,尽量不要修改视图中的数据 dro

mysql写存储过程/PHP写和调用存储过程

PHP调用MYSQL存储过程实例 来源: http://blog.csdn.net/ewing333/article/details/5906887 实例一:无参的存储过程 $conn = mysql_connect('localhost','root','root') or die ("数据连接错误!!!"); mysql_select_db('test',$conn); $sql = " create procedure myproce() begin INSERT IN

知识点:Mysql 基本用法之事务

事务 事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性. 事务实例: create table user( id int primary key auto_increment, name char(32), balance int ); insert into user(name,balance) values ('大木木',1000), ('二木木',1000), ('三木木',1000); #原子操作 start transa

一次使用存储过程游标遇到的坑

一次使用存储过程游标遇到的坑 有这样一个需求:统计某省某市某区前6个月的数据,直接sql查询效率很低,于是打算做定时任务,用定时器执行存储过程的方式在每月初统计上月的相关数据. 使用存储过程就要用到游标了,之前很少写存储过程,对游标也不是熟悉,咋办呢,现学现用啦. 创建存储过程 1 CREATE 2 [DEFINER = { user | CURRENT_USER }] 3 PROCEDURE sp_name ([proc_parameter[,...]]) 4 [characteristic