Я имею базу данных Oracle с следующий сценарий (упрощенный):Oracle Trigger - имя таблицы мутирует, триггер/функция может не видеть, что это
Projects Params
------------- -----------
PROJ_ID SCODE PARAM_ID PARAM_TYPE PROJ_ID PARAM_VALUE
1000 123 5000 4614 1000 '00'
1001 124 5001 4610 1000 'Micro'
1002 123 5002 4614 1001 '02'
5003 4614 1002 '01'
Это означает, что 3 Проекты - Проект 1000 имеет 2 различных параметров а второй и третий проекты имеют по одному параметру.
Теперь мне нужно написать триггер в таблице проектов, который автоматически вставляет новую строку в таблицу params с максимальным значением +1 параметра с типом «4614» с данным SCODE.
INSERT INTO Projects VALUES (1003,123)
... должно вызвать событие
INSERT INTO Parameters VALUES (5004,4614,1003,'02')
Теперь у меня есть 2 возможности, и оба не работают:
Если триггер объявлен как «ДО», я не могу вставить в таблице «Параметры», потому что ограничение внешнего ключа показывает мне ошибку, что Project 1003 еще не создан. Выполнение Commit внутри триггера невозможно.
Если триггер объявлен как «после», я получаю сообщение об ошибке
ORA-04091: table name is mutating, trigger/function may not see it
, потому что я доступ к таблице, которая срабатывает прямо сейчас.
Должно быть какое-либо решение этой проблемы. Любая помощь приветствуется!
// Редактировать
Мой Trigger:
CREATE OR REPLACE TRIGGER PROJ_ARI_TRIGGER
AFTER INSERT
ON PROJECTS
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
v_param VARCHAR2(10);
BEGIN
v_param := get_next_param_val(:new.SCODE);
INSERT INTO Parameters(<<sequence>>,4614,:new.PROJ_ID,v_param);
END PROJ_ARI_TRIGGER;
Функция get_next_param_val просто делает выбор таблицы проектов и возвращает правильное значение параметра.
Вы можете изменить внешний ключ, так что откладываемые; таким образом, он не будет проверяться, пока вы не зафиксируете. Имейте в виду, что это может вызвать проблемы, если вы делаете массовые обновления - вы не получите ошибок до самого конца транзакции. В качестве альтернативы вместо того, чтобы вставлять непосредственно в таблицу, выполните ее с помощью хранимой процедуры. Таким образом, вы можете правильно управлять логикой и потоком, не выполняя причудливые обходные пути. – Boneist
@Boneist К сожалению, я не могу изменить ограничение системы баз данных. Зачем ставить заявление INSERT в хранимую процедуру? Содержимое триггера запуска похоже на v_new_param: = calculate_param(); вставьте значения параметров (...., new.proj_id, v_new_param). –
было бы лучше, если бы вы отредактировали свой вопрос, чтобы добавить скрипт для создания триггера. – Boneist