sql >> Databáze >  >> RDS >> Oracle

Jak obejít jedinečné porušení omezení?

Jednou z možností by bylo použít instead of spoušť. Toto řešení však vyžaduje, abyste přejmenovali tabulky a vytvořili pohledy s názvy, které měly. Tímto způsobem neovlivníte logiku aplikace, ale mohlo by to ovlivnit celkový výkon, takže by měla být řádně otestována.

Nicméně použití spouštěčů ke změně nesprávné aplikační logiky není příliš dobrý nápad. Chápu vaši těžkou situaci, že někdy potřebujeme najít řešení existujících problémů, ale to není správné.

Každopádně níže jednoduchý příklad, který můžete aplikovat na svou logiku

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.

Nyní vytvoříme instead of spoušť

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.

S tímto spouštěčem každý pokus o porušení omezení umožní aktualizaci hodnoty v konečné tabulce.

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



  1. Jak odstranit hodnotu typu enum v postgresu?

  2. VYBRAT POCET(*);

  3. MYSQL a klauzule LIMIT

  4. Co představuje double v SQL serveru?