sql >> Databáze >  >> RDS >> Oracle

ORA-04091:tabulka [bla] mutuje, spouštěč/funkce ji nemusí vidět

Myslím, že nesouhlasím s vaším popisem toho, co se spoušť snaží udělat. Zdá se mi, že je to určeno k vynucení tohoto obchodního pravidla:Pro danou hodnotu t1_appnt_event může mít vždy pouze jeden řádek hodnotu offt1_prnt_t1_pk, která není NULL. (Nezáleží na tom, zda mají ve druhém sloupci stejnou hodnotu nebo ne.)

Je zajímavé, že je definován pro UPDATE OF t1_appnt_event, ale ne pro druhý sloupec, takže si myslím, že někdo by mohl pravidlo porušit aktualizací druhého sloupce, pokud pro tento sloupec neexistuje samostatný spouštěč.

Může existovat způsob, jak vytvořit index založený na funkcích, který vynucuje toto pravidlo, abyste se mohli spouštěče úplně zbavit. Přišel jsem na jeden způsob, ale vyžaduje určité předpoklady:

  • Tabulka má číselný primární klíč
  • Primární klíč a t1_prnt_t1_pk jsou vždy kladná čísla

Pokud jsou tyto předpoklady pravdivé, můžete vytvořit funkci jako je tato:

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;

a index, jako je tento:

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

Řádky, kde je sloupec PMNT NULL, by se tedy v indexu objevily s inverzní hodnotou primárního klíče jako druhou hodnotou, takže by nikdy nebyly ve vzájemném konfliktu. Řádky, kde není NULL, by použily skutečnou (kladnou) hodnotu sloupce. Jediným způsobem, jak byste mohli dosáhnout porušení omezení, by bylo, kdyby dva řádky měly v obou sloupcích stejné hodnoty než NULL.

To je možná příliš „chytré“, ale mohlo by vám to pomoci vyřešit váš problém.

Aktualizace od Paula Tomblina:S aktualizací jsem přešel k původní myšlence, kterou igor vložil do komentářů:

 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. Jak funguje TIMEDIFF() v MariaDB

  2. SYSDATE() vs NOW() v MySQL:Jaký je rozdíl?

  3. Proč postgres v mém dotazu nepoužívá index

  4. Jak analyzovat JSON v postgresql