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:
- erstelle
exceptions
Tisch. Dies kann durch Ausführen vonora_home/rdbms/admin/utlexpt.sql
erfolgen Skript. Die Struktur der Tabelle ist ziemlich einfach; - alle Tabelleneinschränkungen deaktivieren;
- DMLs ausführen;
- alle Beschränkungen mit
exceptions into <<exception table name>>
aktivieren Klausel. Wenn Sieutlexpt.sql
ausgeführt haben -Skript, der Name der Tabellenausnahmen, die gespeichert werden sollen, wäreexceptions
.
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