关于游标的应用实例

    在最近的开发过程中,底层数据库的逻辑稍微有些复杂,在这个过程中涉及到了游标的使用,结合项目的逻辑我简单描述一下游标的使用,如果能对您有一点点的帮助,我将非常高兴,有不合理之处,欢迎大神随时指出。

    首先,简述一下开发环境,我们的数据库是Oracle,IDE是PL/SQL Developer,游标是在存储过程中使用的。

   我们总览一下代码:

create or replace procedure P_CRM_HGQD_MX(v_id varchar2,v_comp_code varchar2)

  /*
      v_id         供应商清单主表id          1111111111
      v_comp_code  要进行统计的组织机构代码  21101
  */
as
    CURSOR CUR_TABLE_LIST IS
        SELECT id,corp_code,crm_minf_id FROM CRM_HGQD_MX  WHERE main_id = v_id;
   v_mxid varchar2(40);
   v_corp_code varchar2(40);
  -- v_yxq varchar2(1000);
   v_syxmdm varchar2(2000);
   v_syxmmc varchar2(2000);
   v_zgyxq varchar2(2000);
   v_zbjb varchar2(2000);
   v_crm_minf_id varchar2(2000);
   
begin
   --1如果存在主表对应的明细数据时,进行删除,程序界面应该进行提示用户
    delete CRM_HGQD_MX WHERE main_id = v_id;
   
   ---2插入数据
   insert into CRM_HGQD_MX (ID, MAIN_ID,corp_code,GYS_NAME,
         gys_identity ,invoice_type ,tax_rate ,phone, server_area,
         approve_time,describe,CRM_MINF_ID)
    select v_id || rownum,v_id,a.corp_code,a.corp_name,
    (case when a.taxpayeridentity='1' then '一般纳税人'
          when a.taxpayeridentity='2' then '小规模纳税人'
            else '' end ) as nsrsf,
    (case when a.fplx ='1' then '增值税普通发票' 
          when a.fplx ='2' then '增值税专业发票' 
          when a.fplx ='3' then '通用发票'  
           else '' end ) as fplx, 
    (case when a.sl =1 then '2%' 
          when a.sl =2 then '3%' 
          when a.sl =3 then '5%' 
          when a.sl =4 then '6%' 
          when a.sl =5 then '11%' 
          when a.sl =6 then '13%' 
          when a.sl =7 then '17%' 
           else '' end ) as sl
             ,a.lxr||'/'||a.sj as lxfs,
             a.business_scope,a.reg_date,a.remarks,b.id      
    from pub_cssc_inf a ,srm_crm_minf b where a.corp_type='供应商' and a.pub_cs_inf_id='GYS1_SCS' 
    and a.id = b.pub_cssc_inf_id;
    
    --3循环    
    OPEN CUR_TABLE_LIST;

    LOOP
        --
        FETCH CUR_TABLE_LIST INTO v_mxid,v_corp_code,v_crm_minf_id;
        EXIT WHEN CUR_TABLE_LIST%NOTFOUND;        
        --4查询业务表相关数据。
        ---获取适用项目
        select to_char(wm_concat(b.comp_code)),to_char(wm_concat(c.org_name)) 
        into v_syxmdm,v_syxmmc
        from srm_crm_minf b,auth_org_info c 
        where b.comp_code = c.org_code 
        and b.corp_code = v_corp_code; 
        
        --获取资格有效期
        select  wm_concat(to_char(b.yx_end_date,'yyyy-MM-dd'))  into v_zgyxq  from srm_crm_minf b 
        where b.corp_code = v_corp_code;
           
        
        --获取质保级别
      
  
        select to_char(wm_concat( (case when d.qa_class ='QA1' then '质保一级'
                     when d.qa_class ='QA2' then '质保二级'
                     when d.qa_class ='QA3' then '质保三级'
                     when d.qa_class ='QA4' then '质保四级'
            else '' end ))) into v_zbjb from Srm_Review_Plan d
         where d.corp_code  = v_crm_minf_id;
        
        --更新明细表相关字段
        update CRM_HGQD_MX set fit_project = v_syxmmc,quality_level =v_zbjb,SYXMDM = v_syxmdm,validity_period = v_zgyxq 
        where id= v_mxid;
        
        commit;
       
    END LOOP;

end P_CRM_HGQD_MX;
    

    我们可以看出来,这个存储过程的逻辑还是比较清楚的,只是在有些地方我们不是很熟悉,在写这个存储过程时,我自己也是这种感觉,有些细节的东西只有在自己写的过程中才能有一个自己的体会。看这个整体的代码,只要有一个整体上的认识就可以了,如整个存储过程是干什么的等,具体的内容,我下面还会说。

   其实需求说简单点就是,我们需要从其他几张有数据的表中查出数据,更新到一张新的表。可是问题在哪呢?问题就在于整个新表中的字段,有些字段是可以从其他的表中查出开直接插入的,可是有些字段却不能字段却不能直接插入,需要逐条进行处理后再插入新表,这就用到了我们的游标,还有就是有些字段的一个位置,查出来可能会对应好几条数据,这时候我们就要用函数将一列中的几个值,放到一行中的一个位置。


    具体是如何实现的呢?我们再来看一张图片

关于游标的应用实例_第1张图片
    在这个存储过程中有两个参数;在创建游标处
CUR_TABLE_LIST 是游标名,游标中保存的是id,corp_code,crm_minf_id,大家可以这样理解,我们把这三个字段找出来放到一张临时表中;接下来时begin,注意程序是从begin处开始资执行的;在2插入数据处insert---select这种写法是可以一次性插入查出的全部数据的,在查出的数据中还有一个转换,如果在旧表中查出的数据是3,则存入新表的数据是通用发票;打开游标开始循环,在创建游标时,可以这样理解我们把数据存入了一个有三个字段的临时表,现在我们要把这张临时表中的数据拿出来,利用循环一条条进行处理,我们把游标中的数据一条条赋值给变量,这样在第一次循环时,变量中就是游标中的第一天记录,第二次循环时,变量中就是游标中的第二条记录;下面是判断条件当游标中所有记录都经过遍历时退出循环;游标和循环结合在一起实现了逐条处理数据。最后不要忘记关闭游标。


    其实这种方式(循环)是非常影响效率的,但是有时为了实现功能,这种做法于是必须的,只要我们能找到一个平衡点就可以了,不要一味的追求效率,但在任何情况下,都不能影响用户的使用。感谢您花费宝贵的时间来看我的博客。

    

你可能感兴趣的:(●,数据库篇)