Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Oracle sebagai Solusi dari Mutasi Tabel

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.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Membuat tabel/tampilan yang diratakan dari kumpulan data yang ditentukan secara hierarki

  2. cara memilih daftar 10.000 id unik dari dual di Oracle SQL

  3. Bagaimana cara menerapkan pengambilan batch dengan Fluent NHibernate saat bekerja dengan Oracle?

  4. Mengapa klausa Oracle IN memiliki batas 1000 hanya untuk data statis?

  5. Bagaimana cara menjatuhkan tabel di oracle