可能是Oracle触发器异常和回滚

时间:2016-05-03 12:29:13

标签: oracle plsql triggers

假设我有以下触发器:

create or replace trigger trigInsertSaloane before insert on saloane
for each row
declare
  myExcp exception;
  pragma exception_init (myExcp,-20005);
begin
  for i in (select * from saloane) loop
    if(:new.numar_salon=i.numar_salon) and (trim(upper(:new.nume_sectie))=trim(upper(i.nume_sectie))) then
    raise myExcp;
    end if;
  end loop;
  exception when myExcp then dbms_output.put_line('Record exists');
end;
/

我想要的是在引发异常时不插入行,所以像回滚一样。在我的情况下,如果引发异常并捕获,则还会插入该行。我不想要那个。此外,我希望以一种漂亮的方式,通过显示一条消息而不会出现任何错误。如何制作它?

2 个答案:

答案 0 :(得分:0)

好的..几点。

1)您需要从触发器引发异常,因为插入将失败并且不会插入。所以要么不抓住你的例外,要么再次重新RAISE

2)使用dbms_output.put_line()只会在用户/客户端打开时显示一条消息。

3)您不需要循环光标。添加where子句更有效

4)你的触发器不起作用..它会抛出 如果您一次插入多于1行,则ORA-04091: table SALOANE is mutating, trigger/function may not see it。 (尝试insert into saloane select * from saloane

5)它可能就是你的例子......看起来你可以更简单地在给定列上使用一个唯一约束来强制执行这个要求。

答案 1 :(得分:0)

在其他答案中再添加几点作为精神。

  1. 因为你正在处理EXCEPTION(PRETTY WELL:p) 理想触发触发事件执行成功 INSERT / UPDATE / DELETE将会发生。
  2. 你需要的是提出某种例外情况 强制触发器失败并显示异常 在这里你需要有RAISE_APPLICATION_ERROR条件 处理这个。
  3. 如上所述,UNIQUE Key约束将是你最好的朋友 在这种情况下工作。