Oracle
 sql >> база данни >  >> RDS >> Oracle

ORA-04091:таблицата [blah] мутира, тригерът/функцията може да не я види

Мисля, че не съм съгласен с описанието ти за това какво се опитва да направи спусъкът. Струва ми се, че има за цел да наложи това бизнес правило:За дадена стойност на t1_appnt_event, само един ред може да има стойност, различна от NULL, на t1_prnt_t1_pk в даден момент. (Няма значение дали имат една и съща стойност във втората колона или не.)

Интересното е, че е дефиниран за UPDATE OF t1_appnt_event, но не и за другата колона, така че мисля, че някой може да наруши правилото, като актуализира втората колона, освен ако няма отделен тригер за тази колона.

Може да има начин да създадете индекс, базиран на функции, който налага това правило, така че да можете да се отървете изцяло от тригера. Измислих един начин, но той изисква някои предположения:

  • Таблицата има цифров първичен ключ
  • Първичният ключ и t1_prnt_t1_pk винаги са положителни числа

Ако тези предположения са верни, можете да създадете функция като тази:

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;

и индекс като този:

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

Така че редовете, където колоната PMNT е NULL, ще се появят в индекса с обратния на първичния ключ като втора стойност, така че никога няма да конфликтират един с друг. Редове, където не е NULL, ще използват действителната (положителна) стойност на колоната. Единственият начин да получите нарушение на ограничението е, ако два реда имат еднакви стойности, различни от NULL, и в двете колони.

Това може би е прекалено "умно", но може да ви помогне да заобиколите проблема си.

Актуализация от Пол Томблин:Отидох с актуализацията на оригиналната идея, която igor постави в коментарите:

 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. Търсете, ако числото се съдържа в израз като:1-3,5,10-15,20

  2. Как да потвърдя имейл адреса с помощта на PL/SQL?

  3. Проверка на sid на oracle и име на база данни

  4. Oracle Live SQL

  5. Прекалено сложна обработка на oracle jdbc BLOB