从一个表插入另一个表使用过程

时间:2017-02-04 09:00:57

标签: oracle stored-procedures insert cursor

我想从一个表插入到其他表中,并在值中进行一些编辑。源表有20,000,000条记录,插入并提交它们是不可能的。所以我写一个过程来循环提交每个1000插入。但它不起作用。有什么问题?

CREATE OR REPLACE PROCEDURE CONVERT_INTO_K2 IS

  batch_size number;
   row_num number;

  CURSOR trans IS

    select rownum,KWP_Trns_Utils.Get_Acnt_From_TRACNTID(t.TRPAN),
           t.TRPRRN, t.TRSIDE,t.switchcode,t.kcb_switchcode,
           t.TERMID, t.TRTERMID,t.TRPOSCCOD,t.TRCAID,
           t.TRMTI,t.TRPRCOD,t.TR87RSPCOD,t.TRMSGRSN,
           t.TRREVFLG,t.TRSETTMD,t.TRCURCOD,t.TRAMNT,
           t.TRORGAMNT,t.TRCHBLCUR,t.TRFEEAMNT,t.TRCHBLAMNT,
           t.TRFRWIIC,t.TRACQIIC,t.TRRECIIC,t.PTRTRCNO,
           t.BTRRN, t.TRTRACEDT, t.TRRSPDT, t.TRLDATE,
           t.TRLTIME, t.BAID, t.BADATE,t.TRACNTID1,
           KWP_Trns_Utils.Get_Acnt_From_TRACNTID(t.TRACNTID2),
           t.ATJHNO,t.ATJHDAT, t.TRORGDTELM,t.TRADDATA,
           KWP_Trns_Utils.Get_Acnt_From_TRACNTID(t.TRACNTID2),
           Trn_ID.Nextval, Trn_diag.Nextval,
           1, 1, 1, 1, 1, 1, 1, 1, 1
      from P912.KCTRNS t

     where t.trprcod != 47
       and rownum < 200;

BEGIN

  batch_size := 0;
   row_num:=0;
  FOR rec IN trans LOOP
    batch_size := batch_size + 1;
     row_num := row_num + 1;

    if  MOD( row_num, 1000 ) != 0 then
       insert into P912.KCTRNS2
      (srcpan,rfrnnum, trnsid,swchcod, prswchcod,intrtrmid,
       xtrntrmid,trmcod, aptrid,msgtypidnt,trntyp,
       rspcod, msqrsn,rvrsflg,sttlsts,currcod,
       amt,origamt,crdhldrcurrcod,feeamt,
       crdhldrdiscamt, isurcrdinstid,acqrcrdinstid,
       rcvrcrdinstid,trcnum,intrrfrnnum,
       rcvdt,rspdt, prrcvdtsctn,prrcvtmsctn,
       btchid, btchiopendt,firsacctnum,
       scndacctnum,docnum,docdt, origdtelmt,
       dditdat,dstpan, id, diag, mngcod,
       funccod, sttlcod,trnres, custno,
       crdlesstrcno,accttyp1,accttyp2,chnltyp)

    Values
      (KWP_Trns_Utils.Get_Acnt_From_TRACNTID(t.TRPAN),
           t.TRPRRN, t.TRSIDE,t.switchcode,t.kcb_switchcode,
           t.TERMID, t.TRTERMID,t.TRPOSCCOD,t.TRCAID,
           t.TRMTI,t.TRPRCOD,t.TR87RSPCOD,t.TRMSGRSN,
           t.TRREVFLG,t.TRSETTMD,t.TRCURCOD,t.TRAMNT,
           t.TRORGAMNT,t.TRCHBLCUR,t.TRFEEAMNT,t.TRCHBLAMNT,
           t.TRFRWIIC,t.TRACQIIC,t.TRRECIIC,t.PTRTRCNO,
           t.BTRRN, t.TRTRACEDT, t.TRRSPDT, t.TRLDATE,
           t.TRLTIME, t.BAID, t.BADATE,t.TRACNTID1,
           KWP_Trns_Utils.Get_Acnt_From_TRACNTID(t.TRACNTID2),
           t.ATJHNO,t.ATJHDAT, t.TRORGDTELM,t.TRADDATA,
           KWP_Trns_Utils.Get_Acnt_From_TRACNTID(t.TRACNTID2),
           Trn_ID.Nextval, Trn_diag.Nextval,
           1, 1, 0, 1, 1, 1, 1, 1, 1);



  else 

    insert into P912.KCTRNS2
      (srcpan,rfrnnum, trnsid,swchcod, prswchcod,intrtrmid,
       xtrntrmid,trmcod, aptrid,msgtypidnt,trntyp,
       rspcod, msqrsn,rvrsflg,sttlsts,currcod,
       amt,origamt,crdhldrcurrcod,feeamt,
       crdhldrdiscamt, isurcrdinstid,acqrcrdinstid,
       rcvrcrdinstid,trcnum,intrrfrnnum,
       rcvdt,rspdt, prrcvdtsctn,prrcvtmsctn,
       btchid, btchiopendt,firsacctnum,
       scndacctnum,docnum,docdt, origdtelmt,
       dditdat,dstpan, id, diag, mngcod,
       funccod, sttlcod,trnres, custno,
       crdlesstrcno,accttyp1,accttyp2,chnltyp)

    Values
      (KWP_Trns_Utils.Get_Acnt_From_TRACNTID(t.TRPAN),
           t.TRPRRN, t.TRSIDE,t.switchcode,t.kcb_switchcode,
           t.TERMID, t.TRTERMID,t.TRPOSCCOD,t.TRCAID,
           t.TRMTI,t.TRPRCOD,t.TR87RSPCOD,t.TRMSGRSN,
           t.TRREVFLG,t.TRSETTMD,t.TRCURCOD,t.TRAMNT,
           t.TRORGAMNT,t.TRCHBLCUR,t.TRFEEAMNT,t.TRCHBLAMNT,
           t.TRFRWIIC,t.TRACQIIC,t.TRRECIIC,t.PTRTRCNO,
           t.BTRRN, t.TRTRACEDT, t.TRRSPDT, t.TRLDATE,
           t.TRLTIME, t.BAID, t.BADATE,t.TRACNTID1,
           KWP_Trns_Utils.Get_Acnt_From_TRACNTID(t.TRACNTID2),
           t.ATJHNO,t.ATJHDAT, t.TRORGDTELM,t.TRADDATA,
           KWP_Trns_Utils.Get_Acnt_From_TRACNTID(t.TRACNTID2),
           Trn_ID.Nextval, Trn_diag.Nextval,
           1, 1, sttl_cod.Nextval, 1, 1, 1, 1, 1, 1);
           end if;


    IF batch_size = 10 THEN
      begin
        COMMIT;
      end;
      batch_size := 0;
    end if;

  END loop;

EXCEPTION
  WHEN others THEN
    ROLLBACK;

END CONVERT_INTO_K2;

2 个答案:

答案 0 :(得分:0)

Values表达式引用t而不是rec光标记录的实际名称。尝试将t(仅Values表达式中的那些,而不是 select中的那些)更改为rec

同时为KWP_Trns_Utils.Get_Acnt_From_TRACNTID(t.TRPAN)制作别名会更容易。否则,您必须在"子句中使用双引号(Values)和大写字母名称。

最后,最重要的是乍一看,使用insert into … from (select …)语法可以更好地满足您的需求。这不起作用吗?

认为,一种更强大的方法是将某种形式的状态列添加到源(PSAM952.KCTRNS)表中,该表将指示该条目已插入目标(PSAM961.KCTRNS2)表。说0代表默认值,1表示它将成为下一批的一部分,2表示它已被复制。

答案 1 :(得分:0)

在您的示例中,您正在执行row_num的mod()以提供一些条件逻辑。但是您没有光标上的order-by,因此应用row_num的行不具有确定性。当然,您申请和订购,然后您需要重新考虑rownum,因为这是在订单之前应用的。所以你真的需要重新评估你想要做的事情的逻辑。

话虽如此,您可以在插入过程中执行条件逻辑,如下所示。

insert /*+ APPEND */ into PSAM961.KCTRNS2
select KWP_Trns_Utils.Get_Acnt_From_TRACNTID(t.TRPAN)
      , t.TRPRRN
      ,etc
      ...
      case when xxx=0 then stt1_cod.nextval else 0 end
      ,1
      ,1
      ,etc 
from PSAM952.KCTRNS t
     where t.trprcod != 47
       and rownum < 200;