Il est (ou au moins) connu que vous ne pouvez pas utiliser des instructions DML sur une table de mutation dans un déclencheur. Un extrait de la Oracle Documentation :
Une table de mutation est une table modifiée par une mise à jour, une suppression ou une instruction insertion, ou une table pouvant être mise à jour par les effets d'une contrainte de cascade Suppr.
La session qui a émis la déclaration de déclenchement ne peut ni interroger ni modifier une table de mutation. Cette restriction empêche une gâchette de voir un ensemble de données incohérentes.
Cependant, je ne peux pas comprendre pourquoi ce déclencheur de démonstration n'échoue pas une erreur "Table de mutation" lorsque j'effectue un insert into emp
Utiliser SQL Developer ou SQL * Plus:
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;
L'insertion se termine avec succès avec la valeur suivante id
valeur et met à jour tous les enregistrements emp
. J'utilise la base de données Oracle 11G Enterprise Edition version 11.2.0.1.0. J'ai lu sur les déclencheurs composés, mais l'échantillon ne les utilise pas.
Il y a une exception. Quand vous définissez un before insert
, déclencheur au niveau des lignes sur une table et émettre une seule ligne INSERT
déclaration, le table is mutating
une erreur ne sera pas soulevée. Mais si vous définissez le même type de déclencheur et émettez une instruction à plusieurs lignes INSERT
, l'erreur sera soulevée. Voici un exemple:
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
Voici une instruction à une seule ligne insert
, qui ne soulever aucune erreur de table de mutation:
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
Voici une instruction insertion à plusieurs lignes, qui augmentera l'erreur de la table de mutation:
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'