Se sabe (o al menos se sabía) que no se pueden usar sentencias DML en una tabla de mutaciones dentro de un activador. Un extracto de la documentación de Oracle :
Una tabla de mutación es una tabla que está siendo modificada por una instrucción UPDATE, DELETE o INSERT, o una tabla que podría actualizarse por los efectos de una restricción DELETE CASCADE.
La sesión que emitió la declaración de activación no puede consultar ni modificar una tabla de mutaciones. Esta restricción evita que un disparador vea un conjunto de datos inconsistente.
Sin embargo, no puedo entender por qué este desencadenador de demostración no falla con un error de "tabla de mutaciones" cuando realizo un insert into emp
uso de SQL Developer o 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;
La inserción se completa con éxito con el siguiente id
valor y actualiza todos los emp
registros. Estoy usando Oracle Database 11g Enterprise Edition Release 11.2.0.1.0. He leído sobre los desencadenantes compuestos, pero la muestra no los usa.
fuente
select max(id)
para asignar números únicos. Solo no lo hagas. Es simplemente incorrecto y no escalará también.Respuestas:
Hay una excepción Cuando define un
before insert
desencadenador de nivel de fila en una tabla y emite unaINSERT
declaración de fila única , eltable is mutating
error no se generará. Pero si define el mismo tipo de disparador y emite unaINSERT
instrucción de varias filas , se generará el error. Aquí hay un ejemplo:Aquí hay una
insert
declaración de una sola fila , que no generará un error de tabla mutante:Aquí hay una instrucción de inserción de varias filas, que generará un error de tabla mutante:
fuente
ID 132569.1
(ORA-4091 on BEFORE ROW TRIGGER with INSERT .. into SELECT statement
).