Это мой триггер insert на Table_A, где я храню параметры в своей системе. Когда я вставляю в таблицу, я хочу изменить end_date последней записи, чтобы сохранить запись в версиях.Обновление предыдущей версии записи во время вызова Oracle insert
create or replace trigger parameter_version
before insert
on parameters
for each row
declare
v_is_exist number := 0;
v_rowid rowid;
begin
select count(*) into v_is_exist from parameters where name = :new.name; -- check if parameter exist
select rowid into v_rowid from parameters where name = :new.name and end_date is null; -- record rowid, which sholud be changed
if v_is_exist <> 0 then
set end_date = :new.start_date - 1
end if;
end;
Ситуации в таблице перед вставкой является:
| id | name | value | start_date | end_date |
-----------------------------------------------
| 1 |Par_A | 10 | 2016-09-01 | 2016-10-01 |
-----------------------------------------------
| 2 |Par_A | 20 | 2016-10-02 | 2016-10-03 |
-----------------------------------------------
| 3 |Par_A | 30 | 2016-10-05 | <null> |
-----------------------------------------------
Записи с идентификатором = 3 следует установить END_DATE на: new_start_date - 1 (близкий вариант) и вставив запись у меня есть следующая версия пар с датой_начал = sysdate.
У меня есть имя ошибки ORA-04091, это мутирует, триггер/функция может его не видеть.
Я знаю, что этот случай тяжелый и, вероятно, невозможно, но, возможно, кто-то знает решение? Или, может быть, существует другое решение в этом случае?
Это нехороший кандидат на использование триггера. Как следует из сообщения об ошибке, содержимое таблицы все еще находится в потоке, и триггер может не запускаться после обновления всех соответствующих строк. Намного лучше, чтобы код вызова делал необходимые обновления. Если это твердое требование, вам лучше всего будет исследовать [сложные триггеры] (https://docs.oracle.com/database/121/LNPLS/triggers.htm#LNPLS2005) –
В зависимости от версии вашей базы данных Oracle есть посмотрите на [составные триггеры] (http://viralpatel.net/blogs/compound-triggers-in-oracle-11g-tutorial-example/) (только в крайнем случае, я думаю, вы должны пересмотреть свой дизайн) – sers
You необходимо использовать триггер уровня инструкции. Триггеры уровня строки не могут изменять обновляемую таблицу. –