循环调用修正sic86

  

create or replace procedure rebuild_sic86_wyl(pi_aac001 in number,

                                              po_fhz    out varchar2,

                                              po_msg    out varchar2) is

  --1.根据账户类型来判断是本地的还是转入的,

  --2.如果是本地的,

  --    写一个游标存放sic86.截止上年末缴费月数jzsnm,本年度缴费月数bn,本年累计缴费月数bnnj,

  --    从最小的年份开始,清空最小年费的下一年jzsnm,bnlj

  --    update sic86 set jzsnm = null ,bnlj = null where aae001 >min(aae001)

  --    update 最小年费下一年的 jzsnm = 最小年份bn+bnlj

  v_count      number(4);

  v_zhlx       sic86.zhlx%type;

  v_aae001_min sic86.aae001%type;

  v_aae001_max sic86.aae001%type;

  v_nf         sic86.aae001%type;

  v_bn         sic86.bn%type;

  v_bnlj       sic86.bnlj%type;

  v_jzsnm      sic86.jzsnm%type;

  cursor c_zhlx_list is

    select zhlx from sic86 where aac001 = pi_aac001;

begin

  po_fhz := '1';

  po_msg := '修正成功';

  for rec_zhlx in c_zhlx_list loop

    --选取最小年份和最小年份

    select min(aae001)

      into v_aae001_min

      from sic86

     where aac001 = pi_aac001;

    select min(aae001)

      into v_aae001_max

      from sic86

     where aac001 = pi_aac001;

    if rec_zhlx.zhlx = '0' then

      for nf in v_aae001_min .. v_aae001_max loop

      --去最小年份的本年缴费月数

        select bn

          into v_bn

          from sic86

         where aac001 = pi_aac001

           and aae001 = nf; 

      --取最小年份的本年累计月数

        select bnlj

          into v_bnlj

          from sic86

         where aac001 = pi_aac001

           and aae001 = nf; 

      --最小年份下一年 v_nf

        v_nf := nf + 1; 

      

        -- 修正1 最小年份下一年的的  jzsnm = 最小年度bn+最小年度bnlj

        update sic86

           set jzsnm =

               (v_bn + v_bnlj)

         where aac001 = pi_aac001

           and aae001 = v_nf;

      --取最小年份下一年的的截至上年末月数

        select jzsnm

          into v_jzsnm 

          from sic86

         where aac001 = pi_aac001

           and aae001 = v_nf;

        -- po_msg :=v_nf||'年份的jzsnm='||v_jzsnm;

        --return;         --调试用,正式用的时候注释掉

        --去最小年份下一年的本年缴费月数   

        select bn

          into v_bn

          from sic86

         where aac001 = pi_aac001

           and aae001 = v_nf; 

      

        --清空最小年份下一年的 截至上年末月数 和 本年累计(其实清空不情况无所谓,不影响)

        /*

          update sic86

            set jzsnm = null, bnlj = null

          where aac001 = pi_aac001

            and aae001 = v_nf;

        */

      

        -- 修正2 最小年份下一年的 本年累计月数 bnlj = 本年的jzsnm+本年的bn

        update sic86

           set bnlj =

               (v_jzsnm + v_bn)

         where aac001 = pi_aac001

           and aae001 = v_nf;

      end loop;

      po_fhz := '1';

      po_msg := '循环修正成功';

    elsif rec_zhlx.zhlx = '1' then

      po_fhz := '-1';

      po_msg := '转入的暂不处理';

      return;

    end if;

  end loop;

end;

  以上只能修正最小年度的下一年。

以下是建表语句:

-- Create table

create table SIC86

(

  jzsnm  NUMBER(4),

  bn     NUMBER(4),

  bnlj   NUMBER(4),

  zhlx   VARCHAR2(2),

  aac001 NUMBER(10),

  aae001 NUMBER(4)

)

tablespace USERS

  pctfree 10

  initrans 1

  maxtrans 255

  storage

  (

    initial 64K

    next 1M

    minextents 1

    maxextents unlimited

  );

-- Add comments to the table 

comment on table SIC86

  is '模拟养老年度账户';

-- Add comments to the columns 

comment on column SIC86.jzsnm

  is '截至上年末缴费月数';

comment on column SIC86.bn

  is '本年缴费月数';

comment on column SIC86.bnlj

  is '截止本年累计月数';

comment on column SIC86.zhlx

  is '账户类型,0:本地; 1:转入生成';

comment on column SIC86.aac001

  is '个人编号';

  最终的修正程序:

可以正常使用,要分两段,第一:最小年份的要单独更新 本年累计bnlj = 截至上年末 jzsnm+本年bn ;

            第二:最大年份的时候同上。

CREATE OR REPLACE PROCEDURE REBUILD_SIC86_WYL(PI_AAC001 IN NUMBER,

                                              PO_FHZ    OUT VARCHAR2,

                                              PO_MSG    OUT VARCHAR2) IS

  --1.根据账户类型来判断是本地的还是转入的,

  --2.如果是本地的,

  --    写一个游标存放sic86.截止上年末缴费月数jzsnm,本年度缴费月数bn,本年累计缴费月数bnnj,

  --    从最小的年份开始,清空最小年费的下一年jzsnm,bnlj

  --    update sic86 set jzsnm = null ,bnlj = null where aae001 >min(aae001)

  --    update 最小年费下一年的 jzsnm = 最小年份bn+bnlj

  V_ZHLX       SIC86.ZHLX%TYPE;

  V_AAE001_MIN SIC86.AAE001%TYPE;

  V_AAE001_MAX SIC86.AAE001%TYPE;

  V_NF         SIC86.AAE001%TYPE;

  V_BN         SIC86.BN%TYPE;

  V_BNLJ       SIC86.BNLJ%TYPE;

  V_JZSNM      SIC86.JZSNM%TYPE;

  CURSOR C_ZHLX_LIST IS

    SELECT ZHLX FROM SIC86 WHERE AAC001 = PI_AAC001;

BEGIN

  PO_FHZ := '1';

  PO_MSG := '修正成功';



  FOR REC_ZHLX IN C_ZHLX_LIST LOOP

    --选取最小年份和最小年份

    SELECT MIN(AAE001)

      INTO V_AAE001_MIN

      FROM SIC86

     WHERE AAC001 = PI_AAC001;

    SELECT MAX(AAE001)

      INTO V_AAE001_MAX

      FROM SIC86

     WHERE AAC001 = PI_AAC001;

  

    FOR NF IN V_AAE001_MIN .. V_AAE001_MAX LOOP

        --修正01  最小年份的本年累计,只修正最小年份,只修正一次

        IF (NF = V_AAE001_MIN) THEN

          --取最小年份的截止上年末月数,这个只用一次 

          UPDATE SIC86

             SET BNLJ =

                 (NVL(JZSNM, 0) + NVL(BN, 0))

           WHERE AAC001 = PI_AAC001

             AND AAE001 = NF;

        ELSE

          NULL;

        END IF;

      

        --去最小年份的本年缴费月数

        SELECT BN

          INTO V_BN

          FROM SIC86

         WHERE AAC001 = PI_AAC001

           AND AAE001 = NF;

        --取最小年份的本年累计月数

        SELECT BNLJ

          INTO V_BNLJ

          FROM SIC86

         WHERE AAC001 = PI_AAC001

           AND AAE001 = NF;

      

        --最小年份下一年 v_nf

        V_NF := NF + 1;

      

        -- 修正1 最小年份下一年的的  jzsnm = 最小年度bnlj

        UPDATE SIC86

           SET JZSNM = V_BNLJ

         WHERE AAC001 = PI_AAC001

           AND AAE001 = V_NF;

        --加入判断截至上年末下一年v_nf是否为最后一年,如果直接退出 

        IF V_NF = V_AAE001_MAX THEN

          --取最小年份的截止上年末月数,这个只用一次 

          UPDATE SIC86

             SET BNLJ =

                 (NVL(JZSNM, 0) + NVL(BN, 0))

           WHERE AAC001 = PI_AAC001

             AND AAE001 = V_NF;

          PO_FHZ := '1';

          PO_MSG := '修复成功';

          RETURN;

        END IF;

        --取最小年份下一年的的截至上年末月数

        SELECT JZSNM

          INTO V_JZSNM

          FROM SIC86

         WHERE AAC001 = PI_AAC001

           AND AAE001 = V_NF;

        -- po_msg :=v_nf||'年份的jzsnm='||v_jzsnm;

        --return;         --调试用,正式用的时候注释掉

        --去最小年份下一年的本年缴费月数

        SELECT BN

          INTO V_BN

          FROM SIC86

         WHERE AAC001 = PI_AAC001

           AND AAE001 = V_NF;

      

        -- 修正2 最小年份下一年的 本年累计月数 bnlj = 本年的jzsnm+本年的bn

        UPDATE SIC86

           SET BNLJ =

               (V_JZSNM + V_BN)

         WHERE AAC001 = PI_AAC001

           AND AAE001 = V_NF;

      END LOOP;

      PO_FHZ := '1';

      PO_MSG := '循环修正成功';

  END LOOP;

END;

  

你可能感兴趣的:(循环)