Nie ma prostego sposobu zgłaszania wszystkich możliwych naruszeń ograniczeń. Ponieważ gdy Oracle natknie się na pierwsze naruszenie ograniczenia, nie jest możliwa dalsza ocena, instrukcja nie powiedzie się, chyba że ograniczenie jest odroczone lub log errors
klauzula została uwzględniona w instrukcji DML. Należy jednak zauważyć, że log errors
klauzula nie będzie w stanie wykryć wszystkich możliwych naruszeń ograniczeń, po prostu zarejestruje pierwsze.
Jednym z możliwych sposobów jest:
- utwórz
exceptions
stół. Można to zrobić wykonującora_home/rdbms/admin/utlexpt.sql
scenariusz. Struktura tabeli jest dość prosta; - wyłącz wszystkie ograniczenia tabeli;
- wykonaj DML;
- włącz wszystkie ograniczenia z
exceptions into <<exception table name>>
klauzula. Jeśli wykonałeśutlexpt.sql
skryptu, nazwa wyjątków tabeli, które będą przechowywane, toexceptions
.
Stół testowy:
create table t1(
col1 number not null,
col2 number not null,
col3 number not null,
col4 number not null
);
Spróbuj wykonać insert
oświadczenie:
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")
Wyłącz wszystkie ograniczenia tabeli:
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;
Spróbuj wykonać poprzednio nieudaną insert
oświadczenie ponownie:
insert into t1(col1, col2, col3, col4)
values(1, null, 2, null);
1 rows inserted.
commit;
Teraz włącz ograniczenia tabeli i przechowuj wyjątki, jeśli takie istnieją, w exceptions
tabela:
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;
Sprawdź exceptions
tabela:
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
Naruszono dwa ograniczenia. Aby poznać nazwy kolumn, po prostu zapoznaj się z user_cons_columns
widok słownika danych:
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
Powyższe zapytanie daje nam nazwy kolumn i wierszy problematycznych rekordów. Mając pod ręką rowidy, nie powinno być problemu ze znalezieniem tych rekordów, które powodują naruszenie ograniczeń, naprawienie ich i ponowne włączenie ograniczeń.
Oto skrypt, który został użyty do wygenerowania alter table
instrukcje włączania i wyłączania ograniczeń:
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