sql >> Base de Datos >  >> RDS >> Oracle

¿Cómo sortear una violación de restricción única?

Una opción sería usar instead of generar. Sin embargo, esta solución requiere que cambie el nombre de sus tablas y cree vistas con los nombres que tenían. De esa manera, no afectará la lógica de la aplicación; sin embargo, podría afectar el rendimiento general, por lo que debe probarse correctamente.

Sin embargo, usar activadores para cambiar la lógica de aplicación incorrecta no es una buena idea. Entiendo su situación de que a veces necesitamos encontrar soluciones a los problemas existentes, pero eso no lo hace correcto.

De todos modos, debajo de un ejemplo simple que puede aplicar a su lógica

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.

Ahora creamos un instead of disparador

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 este disparador, cualquier intento de violar la restricción hará posible la actualización del valor en la tabla 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