使用触发器记录所有删除操作,包括回滚

时间:2013-05-30 19:46:18

标签: oracle triggers commit rollback

假设我有2个表,EMPLOYEEEMP_BAK。我需要为从员工中删除的所有数据创建备份表,即使是已回滚的数据

我的触发器:

CREATE OR REPLACE TRIGGER emp_del_bak_trg
before delete ON employee 
FOR EACH row 
DECLARE 
oldname department.department_name%type;
newname department.department_name%type;
BEGIN
INSERT INTO emp_bak 
VALUES (:OLD.employee_id, :OLD.employee_name, :OLD.job
       ,:OLD.hire_date,:OLD.department_id, sysdate);
--commit;
end;

现在,如果我回滚,那么数据将被删除;如果我取消注释commit,我将在删除时收到错误。我们的想法是保持记录并跟踪系统更新。

任何想法如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

几乎没有理由在触发器内部提交。

现在,即使事务已回滚,您也需要跟踪它,特别是您的情况似乎更加特殊。这是一个相当不寻常的要求,但我会假设您有非常这样做的理由。

如果您确实想要这样做,则需要使用autonomous transaction,这样可以在另一个事务中提交独立事务。由于触发器是PL / SQL块,您可以在触发器中执行此操作。

Oracle文档在触发器中有一个单独的部分dealing with autonomous transactions,有很多示例供您使用。无论您需要使用哪一个,语法如下所示,它始终放在DECLARE块中:

PRAGMA AUTONOMOUS_TRANSACTION;

因此,您的触发器如下所示:

create or replace trigger emp_del_bak_trg
   before delete on employee 
   for each row 
declare 
   PRAGMA AUTONOMOUS_TRANSACTION;
begin

   insert into emp_bak 
   values ( :old.employee_id, :old.employee_name, :old.job
          , :old.hire_date, :old.department_id, sysdate);
   commit;

end;
/

作为一个小小的说明,我总是以不同的方式表达,所以很明显,你做的事情是你不应该做的。自主交易是危险的,应谨慎使用。