Ваш триггер не обновляет breweryTable
, потому что вы используете автономную транзакцию.
Когда вы вставляете пиво в beerTable
, только пиво, которое вставило это пиво, может видеть это пиво, пока вы не COMMIT
. При вставке, обновлении или удалении сеанс открывает транзакцию, которая закрывается, когда вы COMMIT
или ROLLBACK
. Триггер использует автономную транзакцию, которая отделена от транзакции вашего сеанса. Ни одна транзакция не может увидеть незафиксированные данные, измененные другой.
Вот пример с тремя сортами пива, которые я сделал. У меня есть две пивоварни, образно называемые brewery 1
и brewery 2
:
SQL> insert into beerTable (beer_name, brewery) values ('Eeuurgh', 'brewery 1');
1 row created.
SQL> insert into beerTable (beer_name, brewery) values ('Nasty Nasty', 'brewery 2');
1 row created.
SQL> insert into beerTable (beer_name, brewery) values ('Who drinks this stuff?', 'brewery 2');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from breweryTable;
BREWERY NUMBER_OF_BEERS_PRODUCED
------------------------------ ------------------------
brewery 1 0
brewery 2 0
Триггер сработал три раза, по одному для каждого оператора INSERT
, но, поскольку он выполнялся в автономной транзакции, он не мог видеть вводимые каналы, поэтому сообщал, что счетчик равен нулю.
С другой стороны, если мы фиксируем после каждой строки, мы получаем следующий результат:
SQL> truncate table beerTable;
Table truncated.
SQL> insert into beerTable (beer_name, brewery) values ('Eeuurgh', 'brewery 1');
1 row created.
SQL> commit;
Commit complete.
SQL> insert into beerTable (beer_name, brewery) values ('Nasty Nasty', 'brewery 2');
1 row created.
SQL> commit;
Commit complete.
SQL> insert into beerTable (beer_name, brewery) values ('Who drinks this stuff?', 'brewery 2');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from breweryTable;
BREWERY NUMBER_OF_BEERS_PRODUCED
------------------------------ ------------------------
brewery 1 0
brewery 2 1
В этом случае, когда курок срабатывал в третий раз, он мог видеть пиво Nasty Nasty
, сваренное на brewery 2
, так как к тому времени это пиво было совершено. Тем не менее, он не мог видеть пиво Who drinks this stuff?
, потому что это пиво еще не было совершено. Следовательно, счет для brewery 2
равен 1.
Как вы заметили, удаление автономной транзакции не сработало: вместо этого вы получили ошибку ORA-04091 «таблица мутирует».
Я должен спросить, почему вы хотите обновлять эти показатели следующим образом. Будете ли вы использовать их достаточно часто, чтобы сделать их актуальными на ходу?
РЕДАКТИРОВАТЬ : Я не могу вспомнить ситуацию, в которой было бы полезно обновлять эти показатели. Для поддержания их актуальности требуется немало усилий (вам нужно написать триггеры для обработки INSERT, UPDATE и DELETE), а также могут возникнуть проблемы с производительностью, если вы запускаете UPDATE или DELETE, которые влияют на многие из них. строк.
Альтернативный подход, который мог бы избежать ошибок таблицы мутаций, заключался бы в увеличении или уменьшении количества затронутых пивоваренных заводов в триггере. Однако эти показатели могут быть не синхронизированы с тем, что на самом деле находится в таблице, и я не уверен, что это также полностью устранит проблемы с производительностью.
Отслеживание этих показателей таким образом, в конечном счете, доставляет больше хлопот, чем стоит.