插入Cursor循环和异常处理 - Oracle

时间:2012-02-19 04:10:30

标签: sql oracle plsql cursor

我有一个名为DUD的表,它几乎是静态的(这意味着一旦插入数据它就永远不会改变)。我从DUD查询数据并填充每天Webmethods轮询的临时表CAR。

每笔交易通常为10条记录。每天有两笔交易。

我已经写了一个Cursor来做这个,我很满意逻辑。

输出如下:

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. 如果循环中的插入失败,它应该回滚在此事务中生成的所有插入,并且不会以事务的部分插入记录或孤立记录结束。我只在循环完成后才提交,没有引发异常。

  2. 发生异常时,我也想知道哪条记录无法插入。我希望在我的异常中捕获这个并在异常处理程序中调用一个函数,该函数将此信息插入到Error表中以供进一步调查。

  3. 在DB中禁用自动提交。但是oracle会将所有插入循环视为一个事务或独立事务并立即插入吗?

  4. 代码

      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;
    

2 个答案:

答案 0 :(得分:1)

在这种情况下你也可以使用FORALL语句....

您正在使用游标并在循环中插入表格.. 您可以一次性直接插入所有交易。这也将提高代码的性能,这也可以保证所有插入的事务或者没有插入任何事务......

答案 1 :(得分:0)

基本上,在您描述的情况下,应该没有问题,因为您只在回滚后提交 但也许最好将AUTONOMOUS_TRANSACTION用于记录错误的函数。一般情况下,应该避免使用它,但是因为你需要做一些原子事务(用于记录记录)它可能会更好,所以你将确保这个提交不会提交循环中的插入。