2013-04-18 2 views
1

У меня есть две таблицы, ПРОДУКТЫ и STATE_PRICE. Цены на каждый продукт зависят от штата. Таблица ПРОДУКТОВ отслеживает среднюю стоимость каждого продукта во всех штатах. Я пытаюсь написать триггер, который будет обновлять среднюю цену элемента в таблице ПРОДУКТОВ, когда цена будет вставлена, обновлена ​​или удалена в таблице STATE_PRICE. Я написал следующий триггер, который компилируется, но когда я его тестирую, я получаю сообщение об ошибке. Я понимаю концепцию мутирующей ошибки, что я пытаюсь обновить таблицу, в которой выполняется триггер, но я фактически пытаюсь обновить таблицу ПРОДУКТОВ, пока триггер выполняется в таблице STATE_PRICE.Ошибка мутирования на триггер для вычисления средней стоимости

create or replace trigger trg_avg_cost 
after insert or update or delete on state_price 
for each row 

declare 
w_price state_price.list_price%type; 
w_product state_price.productid%type; 

begin 
w_price := :new.list_price; 
w_product := :new.productid; 

update products 
set avg_cost_per_unit = (select avg(w_price) from state_price 
where productid = w_product); 

end; 
/

Конкретное сообщение об ошибке я получаю говорит: отчет

Ошибка:

SQL Error: ORA-04091: table STATE_PRICE is mutating, trigger/function may not see it 
ORA-06512: at "TRG_AVG_COST", line 9 
ORA-04088: error during execution of trigger 'TRG_AVG_COST' 
04091. 00000 - "table %s.%s is mutating, trigger/function may not see it" 
*Cause: A trigger (or a user defined plsql function that is referenced in 
      this statement) attempted to look at (or modify) a table that was 
      in the middle of being modified by the statement which fired it. 
*Action: Rewrite the trigger (or function) so it does not read that table. 
+0

Я думаю, что вы должны использовать Pragma Autonomous_transaction в объявлении и снова проверить – ajmalmhd04

ответ

1

Может быть есть refrential ограничение целостности (на ProductID), который также может поднять ту же самую ошибку. Если это так, ссылка ниже поможет вам избежать ошибки.

http://asktom.oracle.com/pls/asktom/ASKTOM.download_file?p_file=6551198119097816936

+0

ORA-04091 будет выброшен только из триггера строки, если оператор SQL в триггере попытается получить доступ к таблице, на которой существует триггер. Нарушение внешнего ключа приводит к различным ошибкам (ORA-02291, ORA-02292 или ORA-02298 в зависимости от обстоятельств). –

0

В строке запуска не SQL оператор не может получить доступ к таблице, на которой существует триггер. Ваш SELECT AVG(W_PRICE) FROM STATE_PRICE WHERE PRODUCTID = W_PRODUCT является причиной ошибки. Классический способ обойти это ограничение - использовать сложный триггер - документацию here. Также см. Мой ответ на this StackOverflow question для примера реализации составного триггера.

Делитесь и наслаждайтесь.

+0

Благодарим за помощь. Похоже, сложный триггер - это то, что мне нужно! –

Смежные вопросы