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

テーブル内の複数の制約:すべての違反を取得する方法は?

    考えられるすべての制約違反を報告する簡単な方法はありません。 Oracleが制約の最初の違反に遭遇した場合、それ以上の評価は不可能であるため、その制約が延期されるか、log errorsでない限り、ステートメントは失敗します。 句はDMLステートメントに含まれています。ただし、log errorsに注意する必要があります 句は、考えられるすべての制約違反をキャッチすることはできず、最初の違反を記録するだけです。

    考えられる方法の1つは、次のとおりです。

    1. exceptions テーブル。これは、ora_home/rdbms/admin/utlexpt.sqlを実行することで実行できます。 脚本。テーブルの構造は非常に単純です。
    2. すべてのテーブル制約を無効にします。
    3. DMLを実行します;
    4. exceptions into <<exception table name>>に有効にします 句。 utlexpt.sqlを実行した場合 スクリプトの場合、保存されるテーブルの例外の名前はexceptionsになります。 。

    テストテーブル:

    create table t1(
      col1 number not null,
      col2 number not null,
      col3 number not null,
      col4 number not null
    );
    

    insertを実行してみてください ステートメント:

    insert into t1(col1, col2, col3, col4)
      values(1, null, 2, null);
    
    Error report -
    SQL Error: ORA-01400: cannot insert NULL into ("HR"."T1"."COL2")
    

    すべてのテーブルの制約を無効にします:

    alter table T1 disable constraint SYS_C009951;     
    alter table T1 disable constraint SYS_C009950;     
    alter table T1 disable constraint SYS_C009953;     
    alter table T1 disable constraint SYS_C009952; 
    

    以前に失敗したinsertを実行してみてください もう一度声明:

    insert into t1(col1, col2, col3, col4)
      values(1, null, 2, null);
    
    1 rows inserted.
    
    commit;
    

    次に、テーブルの制約を有効にし、例外がある場合は、exceptionsに保存します。 テーブル:

    alter table T1 enable constraint SYS_C009951 exceptions into exceptions; 
    alter table T1 enable constraint SYS_C009950 exceptions into exceptions; 
    alter table T1 enable constraint SYS_C009953 exceptions into exceptions; 
    alter table T1 enable constraint SYS_C009952 exceptions into exceptions; 
    

    exceptionsを確認してください テーブル:

    column row_id     format a30;
    column owner      format a7;
    column table_name format a10;
    column constraint format a12;
    
    select *
      from exceptions 
    
    ROW_ID                         OWNER   TABLE_NAME CONSTRAINT 
    ------------------------------ ------- -------    ------------
    AAAWmUAAJAAAF6WAAA             HR      T1         SYS_C009951  
    AAAWmUAAJAAAF6WAAA             HR      T1         SYS_C009953
    

    2つの制約に違反しています。列名を確認するには、user_cons_columnsを参照してください。 データディクショナリビュー:

    column table_name   format a10;
    column column_name  format a7;
    column row_id       format a20;
    
    select e.table_name
         , t.COLUMN_NAME
         , e.ROW_ID
      from user_cons_columns t
      join exceptions e
        on (e.constraint = t.constraint_name)
    
    
    TABLE_NAME COLUMN_NAME ROW_ID             
    ---------- ----------  --------------------
    T1         COL2        AAAWmUAAJAAAF6WAAA   
    T1         COL4        AAAWmUAAJAAAF6WAAA
    

    上記のクエリは、問題のあるレコードの列名とROWIDを提供します。 ROWIDが手元にあれば、制約違反の原因となるレコードを見つけて修正し、制約を再度有効にするのに問題はありません。

    これは、alter tableを生成するために使用されたスクリプトです。 制約を有効または無効にするためのステートメント:

    column cons_disable format a50
    column cons_enable format a72
    
    select 'alter table ' || t.table_name || ' disable constraint '|| 
            t.constraint_name || ';' as cons_disable
         , 'alter table ' || t.table_name || ' enable constraint '|| 
            t.constraint_name || ' exceptions into exceptions;' as cons_enable
      from user_constraints t
    where t.table_name = 'T1'
    order by t.constraint_type
    


    1. Oracle PL/SQLオブジェクトのスーパーメソッドを呼び出す方法

    2. 新しいMicrosoftSSMAバージョン7.8を使用する際に避けるべき落とし穴

    3. 列の平均を計算し、それをOracleの選択クエリに含めるにはどうすればよいですか?

    4. CASTとIsNumeric