2017-02-04 1 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 행은 그다지 그다지 많지 않습니다. 목표 테이블에 몇 개의 인덱스가 있으며, 데이터를 복사하는 동안 임시로 h 제할 수 있습니까? 더하기 - 커서는 쿼리에서 반환 한 처음 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

집합 기반 접근법을 사용하면 직접 경로와 일부 병렬 처리가 훨씬 더 빠르고 훨씬 빠른 접근 방식이 될 것입니다. 2 천만 행 정도되지 않습니다. – BobC

+0

@BobC 더 자세히 설명해주세요. 당신의 해결책은 무엇입니까? –

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; 
관련 문제