Najbardziej prawdopodobną przyczyną błędu tabeli mutacji jest niewłaściwe użycie wyzwalaczy. Oto typowy przykład:
- wstawiasz wiersz w tabeli A
- wyzwalacz w tabeli A (dla każdego wiersza) wykonuje zapytanie w tabeli A, na przykład w celu obliczenia kolumny podsumowującej
- Oracle wyrzuca ORA-04091: tabela A mutuje, wyzwalacz / funkcja może go nie zobaczyć
Jest to oczekiwane i normalne zachowanie, Oracle chce cię chronić przed sobą, ponieważ Oracle gwarantuje:
- (i) każda instrukcja jest niepodzielna (tzn. albo zawiedzie, albo całkowicie się powiedzie)
- (ii) że każde oświadczenie ma spójny widok danych
Najprawdopodobniej przy pisaniu tego rodzaju wyzwalaczy oczekiwałbyś, że zapytanie (2) zobaczy wiersz wstawiony na (1). Byłoby to sprzeczne z powyższymi punktami, ponieważ aktualizacja nie jest jeszcze zakończona (może być więcej wierszy do wstawienia).
Oracle może zwrócić wynik zgodny z momentem tuż przed początkiem instrukcji, ale z większości przykładów, które widziałem, próbując zaimplementować tę logikę, ludzie widzą instrukcję wielorzędową jako serię kolejnych kroków i oczekują instrukcja [2], aby zobaczyć zmiany dokonane w poprzednich krokach. Oracle nie może zwrócić oczekiwanego wyniku i dlatego zgłasza błąd.
Do dalszej lektury: „mutating table” na Ask Tom .
Jeśli, jak podejrzewam, przyczyną błędu tabeli mutacji jest wyzwalacz, jednym ze sposobów uniknięcia błędu jest przeniesienie logiki z wyzwalacza do procedur.