2017-02-04 5 views
0

Я хочу вставить из одной таблицы в другую с некоторыми изменениями в значениях. исходная таблица содержит 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; 
+0

Лучшее описание того, как «оно не работает», поможет всем. Можете ли вы сделать копию того, что происходит при выполнении этой процедуры в 'plsql'? – kmkaplan

+0

20 000 000 строк на самом деле не так уж много. Сколько индексов существует в целевой таблице, и можете ли вы временно их удалить во время копирования данных? Плюс - ваш курсор ограничивает вас до первых 200 строк, возвращаемых запросом ('rownum <200'). ??? –

+0

@BobJarvis limit <200 - только для теста, 17 индексов, 90% из них - составной индекс 3,4 столбца. Нет, индексы не могут быть потеряны в источнике –

ответ

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, чтобы сказать, что оно было скопировано.

+0

Использование подхода, основанного на наборе, с прямым путем и, возможно, с некоторым параллелизмом будет намного лучше и намного быстрее. 20 миллионов строк не так много. – BobC

+0

@BobC поясните пожалуйста. Каково ваше решение? –

0

В вашем примере вы выполняете mod() для row_num, чтобы обеспечить некоторую условную логику. Но у вас нет указателя на курсор, поэтому строка, к которой применяется 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;