Я хотел бы написать триггер, который проверяет перед вставкой на таблицу, чтобы увидеть, есть ли в этой таблице существующие записи с теми же fk_id
и active flag
. Например представьте следующую таблицу:Оракул - исключение из таблицы Mutating Table в триггере?
| row_id | fk_id | active_flag |
| ------------------------------|
| 1 | 500 | 1 |
| 2 | 500 | 0 |
| 3 | 501 | 1 |
сказать, что я хочу, чтобы вставить новую строку с fk_id = 500
и active_flag = 1
. Я хочу сделать исключение, потому что, основываясь на моих правилах, вы не можете иметь две строки с одинаковыми fk_id
, которые также являются активными в этой таблице в любой момент времени.
я написал триггер, чтобы попытаться справиться с этим:
CREATE OR REPLACE TRIGGER MYSCHEMA.CHECK_DUPS_BIU
BEFORE INSERT OR UPDATE ON MYSCHEMA.MYTABLE_T FOR EACH ROW
DECLARE
l_cnt NUMBER;
e_dup EXCEPTION;
BEGIN
SELECT COUNT(*)
INTO l_cnt
FROM MYSCHEMA.MYTABLE_T
WHERE fk_id = :new.fk_id
AND active_flag > 0;
IF(l_cnt > 0)
THEN
RAISE e_dup;
END IF;
EXCEPTION
WHEN e_dup THEN
raise_application_error(-20300, 'You cannot insert two active items with the same fk_id');
END CHECK_DUPS_BIU;
/
С этим триггером работает совершенно нормально на вставках, но когда я делаю обновление, я получаю исключение Mutating таблицы:
ORA-04091: table MYSCHEMA.CHECK_DUPS_BIU is mutating, trigger/function may not see it
ORA-06512: at "MYSCHEMA.CHECK_DUPS_BIU ", line 12
ORA-04088: error during execution of trigger 'MYSCHEMA.CHECK_DUPS_BIU '
Я сделал небольшое исследование по этой проблеме, и я прочитал, что лучший способ справиться с такой ситуацией * может заключаться в использовании ограничения, но я не уверен, как закодировать такое ограничение, которое проверяет другой столбец (active_flag).
Как я могу осуществить такую проверку?
Вы уверены, что видите скомпилированный код? Ошибка Mutating возникает, когда вы выполняете какую-либо операцию в той же таблице, для которой вы создаете 'before trigger' for. Поэтому, скорее всего, код, который вы показываете, не является фактическим кодом, который вы видите. –
Да, я только что обновил логику, которую я показывал в своем первоначальном вопросе. Вы правы, раньше это было неправильно. –
Ну, так как вы отредактировали свой код, изменив таблицу, которую вы делаете, выберите проблему, как я уже сказал в предыдущем комментарии. Вы не можете выполнить какую-либо операцию выбора в той же таблице, в которой вы создали свой 'before trigger' –