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

Come aggirare una violazione di un vincolo unico?

Un'opzione potrebbe essere quella di utilizzare instead of grilletto. Tuttavia, questa soluzione richiede di rinominare le tabelle e creare viste con i nomi che avevano. In questo modo non influirai sulla logica dell'applicazione, tuttavia potrebbe influire sulle prestazioni complessive, quindi dovrebbe essere testato correttamente.

Tuttavia, l'utilizzo di trigger per modificare la logica dell'applicazione errata non è una buona idea. Comprendo la tua situazione difficile che a volte dobbiamo trovare soluzioni alternative ai problemi esistenti, ma questo non lo rende giusto.

Ad ogni modo, di seguito un semplice esempio che puoi applicare alla tua logica

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.

Ora creiamo un instead of innesco

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.

Con questo trigger, qualsiasi tentativo di violare il vincolo renderà possibile l'aggiornamento del valore nel tavolo finale.

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