如果触发器引发错误,则DELETE语句将失败,并且事务将回滚到在运行语句之前创建的隐式保存点.这意味着触发器所做的任何更改也会回滚.
您可以通过使用自治事务来解决此问题.就像是
CREATE PROCEDURE write_audit
AS
PRAGMA AUTOMOMOUS_TRANSACTION;
BEGIN
INSERT INTO tpm_audit
VALUES( 'Query has attempted to delete root project version!',
sysdate );
commit;
END;
CREATE TRIGGER TPMDBO.PreventVersionDelete
BEFORE DELETE ON TPM_PROJECTVERSION
FOR EACH ROW
DECLARE
BEGIN
IF( :old.VERSIONID = 1 )
THEN
write_audit;
RAISE_APPLICATION_ERROR( -20001, 'Query has attempted to delete root project version!' );
END IF;
END;
这将把INSERT放入TPM_AUDIT到一个单独的事务中,该事务可以在DELETE语句的上下文之外提交.但是,要非常小心使用自治事务
>如果您发现自己使用自动事务而不是写入日志表,那么您几乎肯定会做错事.>使用自治事务声明的PL / SQL块中的代码是真正自治的,因此无法查看当前会话所做的未提交的更改.>由于写入一致性,Oracle完全有可能部分执行DELETE语句,多次触发行级触发器,回滚该工作,然后重新执行DELETE.但是,静默回滚不会回滚自治事务所做的更改.因此,单个行的单个DELETE实际上可能会导致触发器被多次触发,因此在TPM_AUDIT中创建多个行.