关于游标的应用实例

来源:互联网 发布:阿里云怎么备案 编辑:程序博客网 时间:2024/05/21 06:55

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

    首先,简述一下开发环境,我们的数据库是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;
    

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

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


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


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


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

    

1 0
原创粉丝点击