Един вариант би бил да използвате instead of
спусък. Това решение обаче изисква да преименувате вашите таблици и да създадете изгледи с имената, които са имали. По този начин не засягате логиката на приложението, но може да повлияе на цялостната производителност, така че трябва да се тества правилно.
Въпреки това използването на тригери за промяна на грешна логика на приложението не е много добра идея. Разбирам затруднението ви, че понякога трябва да намерим заобиколни решения на съществуващите проблеми, но това не го прави правилно.
Както и да е, по-долу има прост пример, който можете да приложите към вашата логика
SQL> create table t ( c1 number primary key , c2 varchar2(1) ) ;
Table created.
SQL> alter table t rename to tbl_t ;
Table altered.
SQL> create view t as ( select c1 , c2 from tbl_t ) ;
View created.
Сега създаваме instead of
задействане
SQL> create or replace trigger tr_v_t
2 instead of insert
3 on t
4 for each row
5 declare
6 pk_violation_exception exception;
7 pragma exception_init(pk_violation_exception, -00001);
8 begin
9 insert into tbl_t (c1,c2)
10 values ( :new.c1,:new.c2 );
11 exception
12 when pk_violation_exception then
13 dbms_output.put_line('ora-00001 (pk_violation_exception) captured');
14 update tbl_t
15 set c2 = :new.c2
16 where c1 = :new.c1 ;
17* end;
SQL> /
Trigger created.
С този тригер всеки опит за нарушаване на ограничението ще направи възможна актуализацията на стойността във финалната таблица.
SQL> select * from t ;
no rows selected
SQL> insert into t values ( 1 , 'A' ) ;
1 row created.
SQL> commit ;
Commit complete.
SQL> insert into t values ( 2, 'B' ) ;
1 row created.
SQL> commit ;
Commit complete.
SQL> insert into t values ( 2, 'C' ) ;
ORA-00001 (pk_violation_exception) captured
1 row created.
SQL> select * from tbl_t ;
C1 C
---------- -
1 A
2 C