【问题标题】:insert from one table to another table use procedure从一个表插入到另一个表使用过程
【发布时间】:2017-02-04 09:00:56
【问题描述】:

我想从一个表插入到另一个表,并对值进行一些编辑。源表有 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;

【问题讨论】:

  • 更好地描述“它不起作用”对每个人都有帮助。您能否复制在plsql 中执行此过程时发生的情况?
  • 20,000,000 行并不是真的那么多。目标表上有多少个索引,在复制数据时可以暂时删除它们吗?另外 - 您的光标将您限制为查询返回的前 200 行 (rownum &lt; 200)。 ???
  • @BobJarvis limit
  • 嗯,这些索引就是数据复制缓慢的原因。祝你好运。

标签: oracle stored-procedures insert cursor


【解决方案1】:

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表示它已被复制。

【讨论】:

  • 使用基于集合的方法、直接路径和一些并行性可能是一种更好更快的方法。 2000 万行并不多。
  • @BobC 请解释更多。你的解决方案是什么?
【解决方案2】:

在您的示例中,您正在执行 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;

【讨论】:

    猜你喜欢
    • 2018-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    • 2014-07-29
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多