Найбільш вірогідною причиною помилки мутуючої таблиці є неправильне використання тригерів. Ось типовий приклад:
- ви вставляєте рядок у таблицю A
- тригер таблиці A (для кожного рядка) виконує запит у таблиці A, наприклад, для обчислення стовпця підсумків
- Oracle кидає ORA-04091: таблиця A мутує, тригер / функція може цього не бачити
Це очікувана і нормальна поведінка, Oracle хоче захистити вас від себе, оскільки Oracle гарантує:
- (i) що кожне твердження є атомним (тобто буде або невдалим, або успішним повністю)
- (ii) що кожне твердження бачить послідовний вигляд даних
Швидше за все, коли ви пишете подібний тригер, ви очікуєте, що запит (2) побачить рядок, вставлений на (1). Це суперечить обом пунктам вище, оскільки оновлення ще не завершено (може бути вставлено більше рядків).
Oracle міг би повернути результат узгоджено з моментом часу перед початком заяви, але з більшості прикладів, які я бачив, що намагаються реалізувати цю логіку, люди бачать багаторядкове твердження як серію послідовних кроків і очікують, що заява [2], щоб побачити зміни, внесені попередніми кроками. Oracle не може повернути очікуваного результату і тому кидає помилку.
Для подальшого читання: «мутаційний стіл» на Ask Tom .
Якщо я підозрюю, що причина мутаційної помилки таблиці - це тригер, одним із способів уникнути помилки є переміщення логіки з тригера в процедури.