Oracle
為什麼我在觸發器中沒有收到變異表錯誤?
(或至少是)已知您不能在觸發器內的變異表上使用 DML 語句。Oracle 文件的摘錄:
變異表是正在被 UPDATE、DELETE 或 INSERT 語句修改的表,或者是可能會因 DELETE CASCADE 約束的影響而更新的表。
發出觸發語句的會話不能查詢或修改變異表。此限制可防止觸發器看到不一致的數據集。
insert into emp
但是,當我執行使用 SQL Developer 或 SQL*Plus時,我無法理解為什麼這個展示觸發器沒有因“mutating table”錯誤而失敗:CREATE OR REPLACE TRIGGER emp_bri BEFORE INSERT ON emp FOR EACH ROW BEGIN SELECT max(id) + 1 INTO :NEW.id FROM emp; UPDATE emp SET salary = 5000; END emp_bri;
插入使用下一個
id
值成功完成並更新所有emp
記錄。我正在使用 Oracle Database 11g 企業版 11.2.0.1.0 版。我已閱讀有關複合觸發器的資訊,但範例未使用它們。
有一個例外。當您
before insert
在表上定義行級觸發器並發出單行INSERT
語句時,table is mutating
不會引發錯誤。但是如果定義同一種觸發器並發出多行INSERT
語句,則會引發錯誤。這是一個例子:SQL> create table TB_TR_TEST( 2 col1 number, 3 col2 number 4 ) 5 ; Table created SQL> create or replace trigger TR_TB_TR_TEST 2 before insert on TB_TR_TEST 3 for each row 4 begin 5 SELECT max(col1) + 1 INTO :NEW.col1 6 FROM TB_TR_TEST; 7 UPDATE TB_TR_TEST SET col2 = 5000; 8 end; 9 / Trigger created
這是一個單行
insert
語句,它不會引髮變異表錯誤:SQL> insert into TB_TR_TEST(col1, col2) values(1,2); 1 row inserted SQL> insert into TB_TR_TEST(col1, col2) values(3,5); 1 row inserted SQL> commit; Commit complete
這是一個多行插入語句,它會引髮變異表錯誤:
SQL> insert into TB_TR_TEST(col1, col2) 2 select 1, 2 3 from dual; insert into TB_TR_TEST(col1, col2) select 1, 2 from dual ORA-04091: table HR.TB_TR_TEST is mutating, trigger/function may not see it ORA-06512: at "HR.TR_TB_TR_TEST", line 2 ORA-04088: error during execution of trigger 'HR.TR_TB_TR_TEST'