ORA-04091: table SCHEMA.TABLE is mutating, trigger/function may not see it
Satır düzeyinde bir trigger ya da onun çağırdığı bir fonksiyon, değiştirilmekte olan tabloyu sorguladı veya değiştirdi. Tablo değişimin ortasında, içeriği tutarlı değil. Compound trigger kullanın ya da mantığı satır trigger’ının dışına taşıyın.
ORA-04091 ne demek?
Bir ifade tabloyu değiştirirken o tablodaki FOR EACH ROW trigger’ı tabloyu okuyamaz; çünkü sonuç satırların işlenme sırasına bağlı olurdu. Oracle bunu ORA-04091 ile engeller. Ardından gelen ORA-06512 satırları hangi trigger’ın çalıştığını gösterir.
ORA-04091 neden olur?
- Kendi tablosundan okuyan satır düzeyinde bir trigger; örneğin satır saymak ya da toplamak için.
- Trigger’dan ya da DML’den çağrılan ve tabloyu okuyan bir fonksiyon.
- Kademeli silme sürerken üst tabloyu okuyan bir alt tablo trigger’ı.
- Birden çok satırı ilgilendiren bir kuralı trigger’la zorlamak.
ORA-04091 nasıl çözülür?
- Çoğu durumda
:NEWve:OLDgerekeni zaten verir; sorguya gerek kalmaz. - Compound trigger kullanın: satırları
AFTER EACH ROWbölümünde toplayın, sorguyu tablonun durulduğuAFTER STATEMENTbölümünde yapın. - Satırlar arası kurallar için kısıt ya da uygulama mantığını düşünün.
- Kısa yol olarak
PRAGMA AUTONOMOUS_TRANSACTIONkullanmayın: commit edilmemiş değişiklikleri görmez, yani sessizce yanlış veri okuyabilir.
ORA-04091 örneği
Satır trigger’ında tabloyu okumak düşer; compound trigger ifadenin bitmesini bekler:
CREATE OR REPLACE TRIGGER orders_total_trg
FOR INSERT OR UPDATE ON order_lines
COMPOUND TRIGGER
TYPE t_ids IS TABLE OF order_lines.order_id%TYPE;
g_ids t_ids := t_ids();
AFTER EACH ROW IS
BEGIN
g_ids.EXTEND;
g_ids(g_ids.LAST) := :NEW.order_id;
END AFTER EACH ROW;
AFTER STATEMENT IS
BEGIN
FOR i IN 1 .. g_ids.COUNT LOOP
UPDATE orders o
SET o.total = (SELECT SUM(l.amount) FROM order_lines l WHERE l.order_id = o.id)
WHERE o.id = g_ids(i);
END LOOP;
END AFTER STATEMENT;
END orders_total_trg;
/
SQLlightspeed’de
Bir ifade hata verdiğinde SQLlightspeed’in hata paneli, hata kodunu sade bir Türkçe açıklama ve ne yapmanız gerektiğine dair bir öneriyle; Oracle’ın kendi mesajı ve Oracle dokümantasyonuna bağlantıyla birlikte gösterir — bu hata ve sık görülen onlarca başka hata için.
İlgili hatalar
ORA-06550ORA-00060ORA-01403 Tüm Oracle hataları →
Oracle dokümantasyonu: ORA-04091. Oracle, Oracle Corporation’ın tescilli ticari markasıdır. SQLlightspeed’in Oracle ile bir bağlantısı yoktur.