我有一个名为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
我真正关心的问题是:
如果循环中的插入失败,它应该回滚在此事务中生成的所有插入,并且不会以事务的部分插入记录或孤立记录结束。我只在循环完成后才提交,没有引发异常。
发生异常时,我也想知道哪条记录无法插入。我希望在我的异常中捕获这个并在异常处理程序中调用一个函数,该函数将此信息插入到Error表中以供进一步调查。
在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;
答案 0 :(得分:1)
在这种情况下你也可以使用FORALL语句....
您正在使用游标并在循环中插入表格.. 您可以一次性直接插入所有交易。这也将提高代码的性能,这也可以保证所有插入的事务或者没有插入任何事务......
答案 1 :(得分:0)
基本上,在您描述的情况下,应该没有问题,因为您只在回滚后提交 但也许最好将AUTONOMOUS_TRANSACTION用于记录错误的函数。一般情况下,应该避免使用它,但是因为你需要做一些原子事务(用于记录记录)它可能会更好,所以你将确保这个提交不会提交循环中的插入。