Kesalahan pemicu mutasi Oracle terjadi saat pemicu mereferensikan tabel yang memiliki pemicu, menghasilkan pesan “ORA-04091:nama tabel bermutasi, pemicu/fungsi mungkin tidak melihatnya”.
Mari kita lihat solusi yang ada.
Yang pertama, melalui paket, sudah kuno dan tampaknya efektif, namun butuh banyak waktu untuk mempersiapkan dan menjalankannya. Yang kedua sederhana dan dilakukan menggunakan pemicu majemuk.
create table turtles as select 'Splinter' name, 'Rat' essence from dual union all select 'Leonardo', 'Painter' from dual union all select 'Rafael', 'Painter' from dual union all select 'Michelangelo', 'Painter' from dual union all select 'Donatello', 'Painter' from dual;
Ketika Splinter bermutasi dari tikus menjadi sensei, pelukis harus secara otomatis berubah menjadi ninja. Pemicu ini tampaknya cocok:
create or replace trigger tr_turtles_bue before update of essence on turtles for each row when ( new.name = 'Splinter' and old.essence = 'Rat' and new.essence = 'Sensei' ) begin update turtles set essence = 'Ninja' where essence = 'Painter'; end;
Namun, saat memperbarui catatan:
update turtles set essence = 'Sensei' where name = 'Splinter'
Terjadi kesalahan berikut:
ORA-04091:tabel SCOTT.TURTLES sedang bermutasi, pemicu/fungsi mungkin tidak melihatnya
Mari kita hapus pemicu ini:
drop trigger tr_turtles_bue;
Metode 1: Menggunakan paket dan pemicu tingkat instruksi.
create or replace package pkg_around_mutation is bUpdPainters boolean; procedure update_painters; end pkg_around_mutation; / create or replace package body pkg_around_mutation is procedure update_painters is begin if bUpdPainters then bUpdPainters := false; update turtles set essence = 'Ninja' where essence = 'Painter'; end if; end; end pkg_around_mutation; / create or replace trigger tr_turtles_bue before update of essence on turtles for each row when ( new.name = 'Splinter' and old.essence = 'Rat' and new.essence = 'Sensei' ) begin pkg_around_mutation.bUpdPainters := true; end tr_turtles_bue; / create or replace trigger tr_turtles_bu after update on turtles begin pkg_around_mutation.update_painters; end tr_turtles_bu; /
Metode 2: Menggunakan pemicu DML gabungan (tersedia dimulai dengan Oracle 11g).
create or replace trigger tr_turtles_ue for update of essence on turtles compound trigger bUpdPainters boolean; before each row is begin if :new.name = 'Splinter' and :old.essence = 'Rat' and :new.essence = 'Sensei' then bUpdPainters := true; end if; end before each row; after statement is begin if bUpdPainters then update Turtles set essence = 'Ninja' where essence = 'Painter'; end if; end after statement; end tr_turtles_ue;
Mari kita coba yang berikut ini:
update turtles set essence = 'Sensei' where name = 'Splinter'
Bahkan jika Anda menghadapi kasus mutasi yang lebih kompleks, Anda dapat menggunakan ide yang disebutkan di atas sebagai solusi. Dalam pemicu tingkat instruksi, tidak seperti pemicu tingkat baris, tidak ada mutasi yang terjadi. Anda dapat menggunakan salah satu variabel (tag, kait, tabel PL SQL) dalam paket tambahan, atau variabel yang bersifat global untuk semua bagian pemicu gabungan, yang sebaiknya dimulai dengan versi Oracle 11g. Jadi, sekarang kamu juga tahu kung fu.
Anda dapat menemukan informasi tambahan tentang pemicu di:Pemicu DML Gabungan
Jangan ragu untuk menambahkan komentar apa pun.