1

假设我有 2 张桌子,EMPLOYEE并且EMP_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,删除时会出错。这个想法是保持记录并跟踪系统更新。

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

4

1 回答 1

2

在触发器中提交几乎没有充分的理由。

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

如果你真的,真的,想要这样做,你需要使用一个自治事务,这使得一个独立的事务可以在另一个事务中提交。由于触发器是 PL/SQL 块,您可以在触发器中执行此操作。

Oracle 文档有一个单独的部分处理触发器中的自治事务,并为您提供了大量示例。无论您需要在哪里使用语法如下,它总是放在 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;
/

作为一个小提示,我总是以不同的方式处理这种情况,所以很明显你正在做一些你不应该做的事情。自主交易是危险的,应该非常小心地使用。

于 2013-05-30T20:24:41.393 回答