mysql procedure 嵌套循环并分页处理数据

背景


公司存证产品升级,随着数据量的增加,存证产品线按业务分表,导致以往的存证关联数据需要做数据同步更新。版本发布前,通过当前存储过程解决数据升级问题,当前存储过程主要通过查询osv_service_evidence表中的存证记录总数,通过对数据做分页查询,更新evi_doc_refs表中的docEid 即osv_service_evidence表的eid。

名词解释


存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。

示例1


#创建存证文档关联情况下更新所用存储过程
CREATE PROCEDURE evi_doc_refs_eid_deal()
begin
declare pageNum int default 0;
declare totalSize int default 0;
declare pageSize int default 5;
declare totalPage int DEFAULT 0;
declare startIndex int default 0;
select count(*) into totalSize from osv_service_evidence where type != 11 and type !=12 and type !=50  ;
set totalPage = totalSize/pageSize;        
    while ( pageNum<totalPage-1) do 
            #对分页的起始下标计算,以便分页查询时使用
            set startIndex = pageNum *pageSize;
            #开启事务
           START TRANSACTION;
            #嵌套内部分页查询,通过游标处理分页查询结果记录
            begin 
           #声明变量
               declare eviId varchar(50);
               declare evidenceEid varchar(50);
               declare done int default 0;
               declare mark varchar(2);
               declare eid_value varchar(50);
               declare type_value int default 0;
               declare eid_mark varchar(50);
               declare num int DEFAULT 0;
            #定义分页查询结果的游标
               declare i_cur cursor for select id from osv_service_evidence where type !=11 and type !=12 and type !=50 limit startIndex,pageSize;
               declare continue handler for sqlstate '09000' set done = 1;

               open i_cur; 
                   fetch next from i_cur into eviId;
        
                   WHILE (done = 0 ) do
                      #判断每页中处理数据的下标index
                      set num = num+1;
                      select type into type_value  from osv_service_evidence where id = eviId;      
                      select e.eid into eid_value from osv_service_evidence e where id = eviId;
                            
                      if(0 =type_value|null = eid_value) then fetch next from i_cur into eviId;
                      end if;
              
                    #数据处理
                        if     type_value =40 then set mark = 'O'; set eid_mark=concat(mark,eid_value);update evi_doc_refs set docEid = eid_mark where docEviId = eviId;
                        elseif type_value =11 then set mark = 'S'; set eid_mark=concat(mark,eid_value);update evi_doc_refs set docEid = eid_mark where docEviId = eviId;set done = 0;
                        end if;
                                    
                   #如果当前页处理的数据已达页记录数值,通过done退出内部循环,进入外部循环
                    IF num = pageSize THEN set done = 1;
                    #否则继续当前循环
                   ELSEIF num !=pageSize THEN set done =0;
                        fetch next from i_cur into eviId;
                    END IF;
                   END WHILE;
            #关闭游标
               close i_cur;
            end ;
    COMMIT;
  #更新下一次处理的页码,+1
    set pageNum = pageNum+1;
end while;
    END;

    call evi_doc_refs_eid_deal();

示例2

    create procedure evi_order_refs_eid_deal()
    begin
    declare original_eviId varchar(50);
    declare evidenceEid varchar(50);
    declare done int default 0;
    declare mark varchar(2);
    declare eid_value varchar(50);
    declare type_value int default 0;
    declare eid_mark varchar(50);
    # declare existence boolean ;

    declare cur cursor for select eviId  from evi_order_refs where evidenceEid is null order by         createTime desc;
    ##异常处理(触发sql语句失败,执行结束)
    declare continue handler for sqlstate '09000' set done = 1;
    open cur;
        ##取出游标值至变量中
        fetch next from cur into original_eviId;
        repeat
        if not done then 
   
                select type into type_value  from osv_service_evidence where id = original_eviId;
                #逻辑判断,如果eviId确实在存证表中无记录,直接忽略该条出证记录
                
                select e.eid into eid_value from osv_service_evidence e where id = original_eviId;
                #逻辑判断,如果eviId确实在存证表中无记录,直接忽略该条出证记录
                if(0 =type_value|null = eid_value) then fetch next from cur into original_eviId;
                end if;
                    
                if     type_value =40 then set mark = 'O';set eid_mark=concat(mark,eid_value);update evi_order_refs set evidenceEid = eid_mark where eviId = original_eviId;
                elseif type_value =11 then set mark = 'S';set eid_mark=concat(mark,eid_value);update evi_order_refs set evidenceEid = eid_mark where eviId = original_eviId;else  set done = 0;
          end if;
       end if;
    #if(done = 1) then leave cur;
    
    ##重新抓取数据进入循环
    fetch next from cur into original_eviId;
    ##结束循环
    until done end repeat;
    ##关闭游标
    close cur;
    end ;

或许你在其他博客、文摘中没有找到你想到的答案。即便是从本文中获取到一丝灵感,还是希望您能点赞一次。你的支持是我最大的分享动力。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容