Oracle 触发器不用于停止表插入

Oracle 触发器不用于停止表插入,oracle,oracle11g,oracle-sqldeveloper,Oracle,Oracle11g,Oracle Sqldeveloper,我使用以下代码来停止使用触发器将空值插入到表中。但是,当我传递null值时,插入操作进行得很好。知道我做错了什么吗 create table test (col1 number, col2 varchar2(40) ) create or replace trigger test_trg after insert on test for each row declare excp exception; pragma autonomous_transaction; begin

我使用以下代码来停止使用触发器将空值插入到表中。但是,当我传递null值时,插入操作进行得很好。知道我做错了什么吗

create table test
(col1 number,
 col2 varchar2(40)
 )

create or replace trigger test_trg
after insert on test
for each row
declare
    excp exception;
    pragma autonomous_transaction;
begin
    if :new.col2 is null then
     RAISE excp;
    end if;
exception
    when excp then
         dbms_output.put_line('error');
         rollback;
end;

(请注意,我接受在col2上使用not null或check约束是更好的解决方案。我只想找出这段看似正确的代码中错误的原因)

您必须在插入之前将触发器定义为
,以便在执行插入之前触发,删除
pragma autonomouse_事务
回滚
(它们在这里没有意义,因为您没有任何DML),然后在异常处理程序中重新确认异常

不要在触发器中回滚,只需在记录它之后重新引发EXCPATION:

create or replace trigger test_trg
after insert on test
for each row
declare
    excp exception;
    pragma autonomous_transaction;
begin
    if :new.col2 is null then
     RAISE excp;
    end if;
exception
    when excp then
         dbms_output.put_line('error');
         raise; -- propagate error
end;
当您在代码中放入“exception…end;”块时,您对PL/SQL说,管理此错误的后果是您的责任。所以,如果您没有从处理原始错误的代码中引发任何错误,对于PL/SQL来说,这意味着所有与此错误相关的操作都已经在您的代码中完成了,所有操作都正常,并且必须插入记录


你可以试一下。

事实上,最初我还是像以前一样只做了插入。但这并不奏效。我认为这是合乎逻辑的。如果我定义as BEFORE INSERT,那么这将在实际插入表之前执行。那么,在插入数据之前,回滚将如何实现呢。因此,将其更改为AFTER INSERT。为什么有
pragma自治\u事务
回滚触发器内部?回滚是防止插入的一种被动方式。您不能在触发器内执行提交、回滚,因为触发器不是单独的事务。要做到这一点,您需要一个自治事务,其中将发生回滚/提交。
自治事务
是一个新事务,它与插入无关,我将更新我的回答非常感谢Pavel的帮助。这就解决了问题:)非常感谢thinkJet的帮助。这解决了问题:)。。。。顺便说一句,SQLFiddle是一个伟大的,我不知道它。。。也谢谢你:)