我正在使用ORACLE 12c。
在桌子上我有2个触发器,两个"在更新"之前。 更新列时触发其中一个触发器,在此触发器中,另一列获取新值。更新第二列时应触发第二个触发器。但他没有。
update TRIGGER_TEST set COL1 = 'now we will see';
插入行后,执行UPDATE。而且我期待COL1 = "现在我们将看到",COL2 ="仅测试"和COL3 =" trigger_test_2已经解雇"。
select * from TRIGGER_TEST;
COL1 COL2 COL3
----------------------------------------------------------------
now we will see only testing 1_col3
但我得到的是:
UIApplication.shared.open(_ url:)
有人可以向我解释一下吗?我很确定,对于以前的ORACLE版本,这个szenario已经有效了。但现在却没有。
答案 0 :(得分:3)
我很确定,对于以前的ORACLE版本,这个szenario已经有效了。
没有。我在11gR2中运行了你的代码并获得了相同的结果:
set serveroutput on
update TRIGGER_TEST set COL1 = 'now we will see';
here we are in TR_TRIGGER_TEST_1
1 row updated.
select * from TRIGGER_TEST;
COL1 COL2 COL3
------------------------------ ------------------------------ ------------------------------
now we will see only testing 1_col3
before update of COL2 on TRIGGER_TEST
是DML event clause。您正在创建simple DML triggers:
在表或视图上创建DML触发器,其触发事件由DML语句DELETE,INSERT和UPDATE组成。 ...
当您发布DML导致第一个触发器触发的更新时。但是当你在该触发器中分配一个新值时:
:new.col2 := 'only testing';
.. 不是 DML语句 - 它不是单独的更新。
如果以这种方式分配值确实会触发触发,那么如果您改为:
:new.col1 := 'something';
...然后第一个触发器会再次触发,直到你遇到错误ORA-00036: maximum number of recursive SQL levels (50) exceeded
。那显然是不好的。
如果您需要这样做,则必须在第一个触发器中重复col3
的分配。对于你想要发生的更复杂的副作用,无论你是否触及任何一个触发器,你都可以有一个程序来执行任何必要的操作(不会影响这个表),然后从两个触发器中调用它。虽然那时你需要一种机制来确保如果DML更新触及两个列,那么该过程不会被调用两次 - 会导致两个触发器都被触发。
答案 1 :(得分:0)
触发器中的“更新COL2”意味着使用诸如UPDATE或MERGE之类的SQL语句进行更新,否则无法更新。为什么不编写第一个触发器的第二个触发器?