Top.Mail.Ru
Ответы

Мутации в триггерах 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 - обновление розничных цен всех товаров в группе при изменении наценки.
Я хочу еще сделать триггер обновления сводной стоимости при изменении наценки:

123456789101112131415
 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;  

Но возникает мутация:

123456
 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". Это создает циклическую зависимость, которая приводит к ошибке.

Чтобы избежать этой мутации, вы можете использовать переменные для сохранения значений и применять обновления после завершения основного обновления.