Il est (ou du moins était) connu que vous ne pouvez pas utiliser d'instructions DML sur une table de mutation à l'intérieur d'un déclencheur. Un extrait de la documentation Oracle :
Une table en mutation est une table en cours de modification par une instruction UPDATE, DELETE ou INSERT, ou une table qui peut être mise à jour par les effets d'une contrainte DELETE CASCADE.
La session qui a émis l'instruction de déclenchement ne peut pas interroger ou modifier une table en mutation. Cette restriction empêche un déclencheur de voir un ensemble de données incohérent.
Cependant, je ne comprends pas pourquoi ce déclencheur de démonstration n'échoue pas avec une erreur de "table de mutation" lorsque j'effectue une insert into emp
utilisation de 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 id
valeur suivante et met à jour tous les emp
enregistrements. J'utilise Oracle Database 11g Enterprise Edition version 11.2.0.1.0. J'ai lu des informations sur les déclencheurs composés, mais l'échantillon ne les utilise pas.
la source
select max(id)
pour attribuer des numéros uniques. Mais ne le fais pas. C'est tout simplement incorrect et il ne s'agrandira pas aussi bien.Réponses:
Il y a une exception. Lorsque vous définissez un
before insert
déclencheur de niveau ligne sur une table et émettez uneINSERT
instruction de ligne unique , l'table is mutating
erreur ne sera pas déclenchée . Mais si vous définissez le même type de déclencheur et émettez uneINSERT
instruction à plusieurs lignes , l'erreur sera déclenchée . Voici un exemple:Voici une
insert
instruction à une seule ligne , qui ne déclenchera pas d'erreur de table de mutation:Voici une instruction d'insertion à plusieurs lignes, qui générera une erreur de table de mutation:
la source
ID 132569.1
(ORA-4091 on BEFORE ROW TRIGGER with INSERT .. into SELECT statement
).