Известно (или, по крайней мере, было известно), что вы не можете использовать операторы DML для мутирующей таблицы внутри триггера. Выдержка из документации Oracle :
Мутирующая таблица - это таблица, которая изменяется с помощью оператора UPDATE, DELETE или INSERT, или таблица, которая может обновляться в результате ограничения DELETE CASCADE.
Сеанс, который выдал инициирующий оператор, не может запрашивать или изменять изменяющуюся таблицу. Это ограничение не позволяет триггеру видеть несогласованный набор данных.
Однако я не могу понять, почему этот демонстрационный триггер не завершается с ошибкой «таблица мутаций», когда я insert into emp
использую SQL Developer или 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;
Вставка успешно завершается со следующим id
значением и обновляет все emp
записи. Я использую Oracle Database 11g Enterprise Edition Release 11.2.0.1.0. Я читал о сложных триггерах, но образец их не использует.
источник
select max(id)
для назначения уникальных номеров. Просто не надо. Это просто неправильно и не будет масштабироваться.Ответы:
Есть исключение. Когда вы определяете
before insert
триггер на уровне строк для таблицы и запускаете одну строкуINSERT
,table is mutating
ошибка не возникает. Но если вы определяете тот же тип триггера и запускаете многострочнуюINSERT
инструкцию, ошибка будет возникать. Вот пример:Вот
insert
инструкция, состоящая из одной строки , которая не вызывает ошибку изменяющейся таблицы:Вот многострочный оператор вставки, который вызовет ошибку изменяющейся таблицы:
источник
ID 132569.1
(ORA-4091 on BEFORE ROW TRIGGER with INSERT .. into SELECT statement
).