Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Mehrere Einschränkungen in der Tabelle:Wie bekomme ich alle Verstöße?

Es gibt keine direkte Möglichkeit, alle möglichen Beschränkungsverletzungen zu melden. Da Oracle beim ersten Verstoß gegen eine Einschränkung stolpert, ist keine weitere Auswertung möglich, schlägt die Anweisung fehl, es sei denn, diese Einschränkung wird verschoben oder die log errors -Klausel wurde in die DML-Anweisung aufgenommen. Aber es sollte beachtet werden, dass log errors -Klausel nicht alle möglichen Beschränkungsverletzungen abfangen kann, sondern nur die erste aufzeichnet.

Einer der möglichen Wege ist:

  1. erstelle exceptions Tisch. Dies kann durch Ausführen von ora_home/rdbms/admin/utlexpt.sql erfolgen Skript. Die Struktur der Tabelle ist ziemlich einfach;
  2. alle Tabelleneinschränkungen deaktivieren;
  3. DMLs ausführen;
  4. alle Beschränkungen mit exceptions into <<exception table name>> aktivieren Klausel. Wenn Sie utlexpt.sql ausgeführt haben -Skript, der Name der Tabellenausnahmen, die gespeichert werden sollen, wäre exceptions .

Testtabelle:

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

Versuchen Sie, ein insert auszuführen Aussage:

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")

Alle Einschränkungen der Tabelle deaktivieren:

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; 

Versuchen Sie, das zuvor fehlgeschlagene insert auszuführen Aussage noch einmal:

insert into t1(col1, col2, col3, col4)
  values(1, null, 2, null);

1 rows inserted.

commit;

Aktivieren Sie nun die Einschränkungen der Tabelle und speichern Sie Ausnahmen, falls vorhanden, in den exceptions Tabelle:

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; 

Überprüfen Sie die exceptions Tabelle:

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

Zwei Beschränkungen wurden verletzt. Um die Spaltennamen herauszufinden, beziehen Sie sich einfach auf user_cons_columns Datenwörterbuchansicht:

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

Die obige Abfrage gibt uns Spaltennamen und Rowids von problematischen Datensätzen. Wenn Sie die Rowids zur Hand haben, sollte es kein Problem sein, die Datensätze zu finden, die eine Einschränkungsverletzung verursachen, sie zu beheben und die Einschränkungen erneut zu aktivieren.

Hier ist das Skript, das zum Generieren von alter table verwendet wurde Anweisungen zum Aktivieren und Deaktivieren von Einschränkungen:

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