sql >> データベース >  >> RDS >> Oracle

一意の制約違反を回避するにはどうすればよいですか?

    1つのオプションは、の代わりにを使用することです。 引き金。ただし、このソリューションでは、テーブルの名前を変更し、テーブルの名前でビューを作成する必要があります。そうすれば、アプリケーションロジックに影響を与えることはありませんが、全体的なパフォーマンスに影響を与える可能性があるため、適切にテストする必要があります。

    それでも、トリガーを使用して間違ったアプリケーションロジックを変更することは、あまり良い考えではありません。既存の問題の回避策を見つける必要があるというあなたの苦境を理解していますが、それでは正しくありません。

    とにかく、ロジックに適用できる簡単な例を以下に示します

    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.
    

    ここで、の代わりにを作成します トリガー

    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
    



    1. Mysqlは最新の2つの日付でアイテムを注文します

    2. Pythonユニコードエンコーディングの問題

    3. MySQLWorkbenchで図からスクリプトを生成する方法

    4. マルチイベントトーナメントの順位