Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment contourner une violation de contrainte unique ?

Une option serait d'utiliser instead of gâchette. Cependant, cette solution vous oblige à renommer vos tables et à créer des vues avec les noms qu'elles avaient. De cette façon, vous n'affectez pas la logique de l'application, mais cela pourrait affecter les performances globales, il doit donc être testé correctement.

Néanmoins, utiliser des déclencheurs pour changer la mauvaise logique d'application n'est pas une très bonne idée. Je comprends votre situation difficile selon laquelle nous devons parfois trouver des solutions de contournement aux problèmes existants, mais cela ne règle pas les choses.

Quoi qu'il en soit, ci-dessous un exemple simple que vous pouvez appliquer à votre logique

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.

Maintenant, nous créons un instead of déclencheur

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.

Avec ce déclencheur, toute tentative de violation de la contrainte rendra possible la mise à jour de la valeur dans le tableau final.

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