2008-7-6 21:09
gthboy
关于触发器的after和自定义异常,有点儿困惑,请高手讲解一下
先把触发器代码和表里面的数据贴出来
[quote]
create or replace trigger sale_ins
after insert on sales
for each row
declare
finalsl number;
not_enough exception;
begin
update spb set kucun=kucun-:new.xssl where spbm=:new.spbm;
select kucun into finalsl from spb where spbm=:new.spbm;
if finalsl<0 then
raise_application_error(-20001,'库存不足,无法出货');
raise not_enough;
end if;
end;
SQL> select spbm,kucun from spb;
SPBM KUCUN
---------- ----------
423 86
SQL> select spbm,xssl from sales;
未选定行
[/quote]
下面执行了一条insert语句,触发这个触发器。
[quote]SQL> insert into sales (djh,spbm,xssl) values (289,423,90);
insert into sales (djh,spbm,xssl) values (289,423,90)
*
ERROR 位于第 1 行:
ORA-20001: 库存不足,无法出货
ORA-06512: 在"INTEL.SALE_INS", line 8
ORA-04088: 触发器 'INTEL.SALE_INS' 执行过程中出错
SQL> select spbm,kucun from spb;
SPBM KUCUN
---------- ----------
423 86
SQL> select spbm,xssl from sales;
未选定行[/quote]
触发器被激发了,但是,,我有两个困惑:
1、为什么触发器里那个update语句的执行效果却没有了?是抛出异常的同时,把这条语句隐含地rollback了吗?
2、这个触发器的触发条件是after insert on sales,也就是应该在插入记录以后再触发,可是这里抛出异常后,insert语句的效果也没了,那它和before insert on sales岂不是没有区别了?
请各位高手解惑,谢谢了!
[[i] 本帖最后由 gthboy 于 2008-7-6 21:24 编辑 [/i]]
2008-7-6 21:13
sunfly1983
哈哈!等着高手解答!估计出现异常就自带rollback了!
2008-7-6 21:14
sunfly1983
触发器是不是如果一个执行失败了,另一个就回滚了呢!
2008-7-6 21:46
zhangfengh
报错回滚
成功就都成功,失败就都失败
至于用before还是用after需要根据业务以及具体的情况来确定
2008-7-6 22:17
newkid
相当于 INSERT 之前有个隐含的 SAVE POINT, 出错就回滚到这里,触发器里任何操作包括INSERT本身都被回滚。
AFTER触发器里不可以修改 :NEW值。
建议不要把业务写在触发器里,万一你要用IMP灌数据呢?
2008-7-7 08:25
阿日
触发器是在事务中的,如果报错整个事务都会回滚,而不是在触发器内部回滚到某一点的。
用before还是after这是和业务相关的。
还有看你的触发器,觉得应该用一个before触发器比较合适
2008-7-7 09:33
newkid
我说的SAVE_POINT是在触发器外面,INSERT语句之前。
再重申一下:千万不要把业务写到触发器里面,否则你就等着吃苦吧。这是一个老程序员的忠告。
2008-7-7 09:50
gthboy
嗯,明白。这是照着书上的触发器例子做试验的
页:
[1]

Powered by ITPUB论坛