Oracle бросает ORA-04091, когда триггер выдает DML для таблицы, которой принадлежит триггер; это включает в себя инструкции SELECT. Причина проста: состояние таблицы неизвестно, потому что триггер срабатывает во время транзакции , поэтому результат DML триггера непредсказуем.
Решение обычно довольно простое: удалить DML. Это, безусловно, может быть ответом здесь, потому что ваша запись: NEW содержит все значения, необходимые для выполнения обновления на stock_item
:
create or replace trigger beforeItem
before update on item
for each row
begin
update stock_item si
set si.stock_Qty = si.stock_Qty - :new.qty
where si.no = :new.no;
end;
но таблица stock_item не знает, из какого значения вычитается текущее значение таблицы элементов qty.
Хорошо, значит, вы хотите обновить STOCK_ITEM.QTY с разницей между старым (текущим) ITEM.QTY и новым (обновленным) значением. Тогда это будет что-то вроде:
create or replace trigger beforeItem
before update on item
for each row
begin
update stock_item si
set si.stock_Qty = si.stock_Qty - (nvl(:old.qty,0) - nvl(:new.qty,0))
where si.no = :new.no;
end;
Вот демонстрация моего решения на SQL Fiddle .
Кстати, обратите внимание, что я исправил ваше утверждение ОБНОВЛЕНИЕ: вычитание количества товара из названия запаса действительно не имеет смысла. Кроме того, нет необходимости использовать itemName
в предложении WHERE, где есть первичный ключ для использования.