sql >> Databasteknik >  >> RDS >> Oracle

ORA-04091:tabellen [blah] muterar, trigger/funktion kanske inte ser den

Jag tror att jag inte håller med om din beskrivning av vad triggern försöker göra. Det verkar för mig som att det är tänkt att upprätthålla denna affärsregel:För ett givet värde på t1_appnt_event kan bara en rad ha ett icke-NULL-värde ofta1_prnt_t1_pk åt gången. (Det spelar ingen roll om de har samma värde i den andra kolumnen eller inte.)

Intressant nog är den definierad för UPPDATERING AV t1_appnt_event men inte för den andra kolumnen, så jag tror att någon kan bryta mot regeln genom att uppdatera den andra kolumnen, om det inte finns en separat trigger för den kolumnen.

Det kan finnas ett sätt att skapa ett funktionsbaserat index som upprätthåller denna regel så att du kan bli av med triggern helt. Jag kom på ett sätt men det kräver några antaganden:

  • Tabellen har en numerisk primärnyckel
  • Primärnyckeln och t1_prnt_t1_pk är båda alltid positiva tal

Om dessa antaganden är sanna kan du skapa en funktion så här:

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;

och ett index som detta:

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

Så rader där PMNT-kolumnen är NULL skulle visas i indexet med inversen av primärnyckeln som det andra värdet, så de skulle aldrig komma i konflikt med varandra. Rader där det inte är NULL skulle använda det faktiska (positiva) värdet för kolumnen. Det enda sättet du kan få en begränsningsöverträdelse skulle vara om två rader hade samma icke-NULL-värden i båda kolumnerna.

Det här är kanske överdrivet "smart", men det kan hjälpa dig att komma runt ditt problem.

Uppdatering från Paul Tomblin:Jag gick med uppdateringen till den ursprungliga idén som igor lade i kommentarerna:

 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. PL/SQL, hur undkommer man enstaka citattecken i en sträng?

  2. Importera Excel-data till PostgreSQL 9.3

  3. Postgres:konvertera en rad till flera rader (unpivot)

  4. [Video] Dataintegration med PostgreSQL