sql >> Database teknologi >  >> RDS >> Oracle

ORA-04091:tabel [blah] muterer, trigger/funktion kan muligvis ikke se den

Jeg tror, ​​jeg er uenig i din beskrivelse af, hvad triggeren forsøger at gøre. Det ser for mig ud til, at det er beregnet til at håndhæve denne forretningsregel:For en given værdi af t1_appnt_event kan kun én række have en ikke-NULL værdi ofte1_prnt_t1_pk ad gangen. (Det er lige meget, om de har samme værdi i den anden kolonne eller ej.)

Interessant nok er det defineret for OPDATERING AF t1_appnt_event, men ikke for den anden kolonne, så jeg tror, ​​nogen kunne bryde reglen ved at opdatere den anden kolonne, medmindre der er en separat trigger for den kolonne.

Der kan være en måde, hvorpå du kan oprette et funktionsbaseret indeks, der håndhæver denne regel, så du kan slippe af med triggeren helt. Jeg fandt på én måde, men det kræver nogle antagelser:

  • Tabellen har en numerisk primærnøgle
  • Den primære nøgle og t1_prnt_t1_pk er begge altid positive tal

Hvis disse antagelser er sande, kan du oprette en funktion som denne:

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;

og et indeks som dette:

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

Så rækker, hvor PMNT-kolonnen er NULL, ville blive vist i indekset med den inverse af primærnøglen som den anden værdi, så de ville aldrig være i konflikt med hinanden. Rækker, hvor den ikke er NULL, vil bruge den faktiske (positive) værdi af kolonnen. Den eneste måde, du kan få en overtrædelse af begrænsningen på, ville være, hvis to rækker havde de samme ikke-NULL-værdier i begge kolonner.

Dette er måske alt for "klogt", men det kan måske hjælpe dig med at omgå dit problem.

Opdatering fra Paul Tomblin:Jeg gik med opdateringen til den originale idé, som igor skrev i kommentarerne:

 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. Hvordan SUBDATE() virker i MariaDB

  2. Sådan løses ORA-29283:ugyldig filoperation

  3. SÆT SQLBLANKLINES:Sådan tillades tomme linjer i SQLcl &SQL*Plus

  4. MySQL COUNT() – Få antallet af rækker, der skal returneres af en forespørgsel