sql >> Database >  >> RDS >> Oracle

ORA-04091:tabel [blah] muteert, trigger/functie ziet het mogelijk niet

Ik denk dat ik het niet eens ben met uw beschrijving van wat de trigger probeert te doen. Het lijkt mij dat het bedoeld is om deze bedrijfsregel af te dwingen:Voor een gegeven waarde van t1_appnt_event kan slechts één rij een niet-NULL-waarde oft1_prnt_t1_pk tegelijk hebben. (Het maakt niet uit of ze dezelfde waarde hebben in de tweede kolom of niet.)

Interessant is dat het is gedefinieerd voor UPDATE OF t1_appnt_event maar niet voor de andere kolom, dus ik denk dat iemand de regel zou kunnen overtreden door de tweede kolom bij te werken, tenzij er een aparte trigger voor die kolom is.

Er is misschien een manier waarop u een op functies gebaseerde index kunt maken die deze regel afdwingt, zodat u de trigger volledig kunt verwijderen. Ik heb een manier bedacht, maar daar zijn enkele aannames voor nodig:

  • De tabel heeft een numerieke primaire sleutel
  • De primaire sleutel en de t1_prnt_t1_pk zijn beide altijd positieve getallen

Als deze aannames waar zijn, zou je een functie als deze kunnen maken:

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;

en een index zoals deze:

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

Dus rijen waar de PMNT-kolom NULL is, zouden in de index verschijnen met de inverse van de primaire sleutel als de tweede waarde, zodat ze nooit met elkaar in conflict zouden komen. Rijen waar het niet NULL is, zouden de werkelijke (positieve) waarde van de kolom gebruiken. De enige manier waarop u een beperkingsschending zou kunnen krijgen, zou zijn als twee rijen dezelfde niet-NULL-waarden in beide kolommen zouden hebben.

Dit is misschien overdreven "slim", maar het kan u helpen uw probleem te omzeilen.

Update van Paul Tomblin:ik ging met de update naar het oorspronkelijke idee dat igor in de reacties plaatste:

 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. SQLite AVG

  2. Aandacht besteden aan schattingen

  3. programmatisch controleren op open verbinding in JDBC

  4. Wat is DTU in Azure SQL Database en hoe kom je erachter hoeveel we nodig hebben?