2012-02-19 3 views
1

DUT라는 테이블이 있습니다.이 테이블은 꽤 많이 Static입니다 (데이터가 삽입되면 변경되지 않습니다). DUD에서 데이터를 쿼리하고 매일 Webmethods가 폴링하는 준비 테이블 CAR을 채 웁니다.커서 루프에 삽입 및 예외 처리 - Oracle

일반적으로 거래마다은 의 10 개 레코드입니다. 하루에 2 건의 거래가 있습니다.

저는 이것을 수행하기 위해 커서를 작성했으며 논리에 만족합니다. 정말로 저와 질문을 우려하는 것은

TRANSID A B C cnt 
------ --- --- -- --- 
A123  JIM NY ACT 1 
A123  BOB CA ACT 2 
A123  PIN GA ACT 3 
-------------------------- 
A124  MIK CA ACT 1 
A124  JON MA ACT 2 
A124  CON MY ACT 3 
A124  JIB CA ACT 4 

: 루프의 삽입이 실패

  1. 경우,이 트랜잭션 (transaction)에서의 모든 삽입을 롤백해야

    출력은 모양을 그리고 거래에 대해 부분적으로 삽입 된 레코드 또는 고아 레코드로 끝나지 마십시오. 루프가 완료된 후에 만 ​​예외가 발생했습니다.

  2. 예외가 발생하면 삽입하지 못한 레코드를 알고 싶습니다. 이 예외를 catch하고 예외 처리기에서이 정보를 오류 테이블에 삽입하여 추가 조사를 수행 할 함수를 호출하기를 바랍니다.

  3. DB에서 자동 커밋을 사용할 수 없습니다. 그러나 oracle은 루프를 통해 모든 삽입을 하나의 트랜잭션 또는 독립 트랜잭션으로 간주하고 즉시 삽입 할 것입니까? 만 롤백 후 커밋 이후

코드 것은

DECLARE TYPE message_info 
    IS 
    RECORD 
    ( 
     message_code INTEGER, 
     message  VARCHAR2(500)); 
    msg MESSAGE_INFO; 
    tranid NUMBER; 
    p_error EXCEPTION; 
    CURSOR b1 IS 
     SELECT * 
     FROM dud 
     WHERE dud.DATE = SYSDATE 
     AND dud.status='ACTIVE'; 

    BEGIN 
    IF *CHECK SOME condition* 
     BEGIN 
     tranid = seq_transid.NEXTVAL; 
     --- Transaction id is unique per transaction. 
     --- All 10 records will have same transaction id. 
     FOR b1 IN c1 
     LOOP 
      i=b1%rowcount; 
      INSERT INTO car 
         ( 
            transid, 
            a, 
            b, 
            c, 
            cnt 
        ) 
         VALUES 
         ( 
            tranid, 
            b1.a, 
            b1.b, 
            b1.c, 
            i 
        ); 

     END LOOP; 
     EXCEPTION 
     WHEN OTHERS THEN 
     ROLLBACK; 
     msg.message := 'Unable to insert into CAR Table'; 
     RAISE p_error; 
     END; 
     COMMIT; 
    EXCEPTION 
    WHEN p_error THEN 
     error.post_msg (msg.message, SQLCODE,SQLERRM,USER); 
    END IF; 
    END; 

답변

1

당신은 ..

당신은 커서를 사용하고 루프에서 당신은 테이블에 삽입하는 ....이 상황에서도 FORALL 문을 사용할 수 있습니다. 이것은 코드의 퍼포먼스를 증가시킬 것이고 이것은 또한 모든 트랜잭션이 삽입되었거나 아무 트랜잭션도 삽입되지 않았다는 확신을 줄 것입니다 ...

+1

더 나은, 그는 삽입 할 수 있습니다 즉, : (TransID, A, B, C, cnt) (Tranid, A, B, C, rownum 선택 DUD WHERE DUD.DATE = SYSDATE 및 DUD.STATUS = 'ACTIVE') –

+0

나는 Cade와 Pratik에 모두 동의합니다. 나는 for 루프와 커서를 사용하기를 원하기 때문에, rowcount를 얻는 코드에서 변수 i를 사용하여 해당 트랜잭션에 삽입 된 레코드의 시퀀스/순서를 삽입하려고합니다. 위의 글에서 내 추가 출력을 참조하십시오. – user547453

0

기본적으로, 당신이 설명하는 상황에서, 문제가 안된다.
그러나 오류를 기록하는 기능에 AUTONOMOUS_TRANSACTION을 사용하는 것이 더 나을 것입니다. 일반적으로, 그것을 사용하지 말아야하지만, (레코드를 로깅하기 위해) 어떤 원자 트랜잭션을 수행해야하므로 더 좋을 수 있으므로이 커밋이 루프에 삽입 된 내용을 커밋하지는 않을 것입니다. 당신이 직접 한 번에 모든 트랜잭션을 삽입 할 수 있습니다

+0

나는 Cade와 Pratik에 동의합니다. 나는 for 루프와 커서를 사용하기를 원하기 때문에, rowcount를 얻는 코드에서 변수 i를 사용하여 해당 트랜잭션에 삽입 된 레코드의 시퀀스/순서를 삽입하려고합니다. 내 게시물에 위의 추가 된 출력을 참조하십시오 : – user547453