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

ORA-04091:tabel [bla] bermutasi, pemicu/fungsi mungkin tidak melihatnya

Saya pikir saya tidak setuju dengan deskripsi Anda tentang apa yang coba dilakukan oleh pemicu. Bagi saya sepertinya ini dimaksudkan untuk menegakkan aturan bisnis ini:Untuk nilai t1_appnt_event yang diberikan, hanya satu baris yang dapat memiliki nilai non-NULL oft1_prnt_t1_pk pada suatu waktu. (Tidak masalah apakah mereka memiliki nilai yang sama di kolom kedua atau tidak.)

Menariknya, ini didefinisikan untuk UPDATE OF t1_appnt_event tetapi tidak untuk kolom lainnya, jadi saya pikir seseorang dapat melanggar aturan dengan memperbarui kolom kedua, kecuali ada pemicu terpisah untuk kolom itu.

Mungkin ada cara Anda bisa membuat indeks berbasis fungsi yang memberlakukan aturan ini sehingga Anda bisa menyingkirkan pemicu sepenuhnya. Saya menemukan satu cara tetapi memerlukan beberapa asumsi:

  • Tabel memiliki kunci utama numerik
  • Kunci utama dan t1_prnt_t1_pk keduanya selalu bilangan positif

Jika asumsi ini benar, Anda dapat membuat fungsi seperti ini:

dev> create or replace function f( a number, b number ) return number deterministic as
  2  begin
  3    if a is null then return 0-b; else return a; end if;
  4  end;

dan indeks seperti ini:

CREATE UNIQUE INDEX my_index ON my_table
  ( t1_appnt_event, f( t1_prnt_t1_pk, primary_key_column) );

Jadi baris di mana kolom PMNT adalah NULL akan muncul di indeks dengan kebalikan dari kunci utama sebagai nilai kedua, sehingga mereka tidak akan pernah bertentangan satu sama lain. Baris yang bukan NULL akan menggunakan nilai aktual (positif) kolom. Satu-satunya cara Anda bisa mendapatkan pelanggaran batasan adalah jika dua baris memiliki nilai non-NULL yang sama di kedua kolom.

Ini mungkin terlalu "pintar", tetapi mungkin membantu Anda mengatasi masalah Anda.

Pembaruan dari Paul Tomblin:Saya mengikuti pembaruan ke ide asli yang igor masukkan di komentar:

 CREATE UNIQUE INDEX cappec_ccip_uniq_idx 
 ON tbl1 (t1_appnt_event, 
    CASE WHEN t1_prnt_t1_pk IS NOT NULL THEN 1 ELSE t1_pk END);


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana mengatasi ORA-02014:tidak dapat memilih UNTUK PEMBARUAN dari tampilan dengan DISTINCT, GROUP BY

  2. ORA-00911:karakter tidak valid

  3. Gabung dalam vs Dimana

  4. System.Data.OracleClient memerlukan perangkat lunak klien Oracle versi 8.1.7

  5. Operator penggabungan string di Oracle, Postgres dan SQL Server