Мутации в триггерах ORACLE BD
Я делаю БД с таблицами "Товары" и "Группы товаров". У меня есть триггеры CASCADE_DELETE_PRODUCT_GROUP - для каскадного удаления группы вместе с ее товарами, DELETE_GROUP_C_RETAIL - обновление сводной стоимости группы при удалении товара, INSERT_GROUP_C_RETAIL - обновление сводной стоимости группы при добавлении товара, UPDATE_GROUP_C_RETAIL - обновление сводной стоимости группы при обновлении входной стоимости, UPDATE_GROUP_COUNT - обновление количества товаров в группе при добавлении товаров, изменении их количества или удалении, UPDATE_RETAIL_PRICE - рассчет розничной цены при добавлении товара или обновлении входной стоимости, UPDATE_RETAIL_PRICES - обновление розничных цен всех товаров в группе при изменении наценки.
Я хочу еще сделать триггер обновления сводной стоимости при изменении наценки:
CREATE OR REPLACE NONEDITIONABLE TRIGGER "USER1"."UPDATE_C_RETAIL_MARKUP"
BEFORE UPDATE OF RETAIL_PRICE ON product
FOR EACH ROW
BEGIN
UPDATE product_group
SET c_retail = :NEW.retail_price * :NEW.count
WHERE id = :NEW.group_id;
END;
Но возникает мутация:
One error saving changes to table "USER1"."PRODUCT_GROUP":
Row 1: ORA-04091: таблица USER1.PRODUCT_GROUP изменяется, триггер/функция может не заметить это
ORA-06512: на "USER1.UPDATE_C_RETAIL_MARKUP", line 2
ORA-04088: ошибка во время выполнения триггера 'USER1.UPDATE_C_RETAIL_MARKUP'
ORA-06512: на "USER1.UPDATE_RETAIL_PRICES", line 3
ORA-04088: ошибка во время выполнения триггера 'USER1.UPDATE_RETAIL_PRICES'
Я пробовал добавить обновление сводной стоимости в UPDATE_RETAIL_PRICES, но тоже возникала мутация. Как правильно можно сделать триггер,чтобы не возникала мутация?
https://pastebin.com/PhD54Usm
Возникновение мутации (ORA-04091) в вашем случае связано с тем, что вы пытаетесь изменить таблицу "product_group" внутри триггера "UPDATE_C_RETAIL_MARKUP", который уже вызывается из триггера "UPDATE_RETAIL_PRICES". Это создает циклическую зависимость, которая приводит к ошибке.
Чтобы избежать этой мутации, вы можете использовать переменные для сохранения значений и применять обновления после завершения основного обновления.