Няма ясен начин за докладване на всички възможни нарушения на ограниченията. Тъй като когато Oracle се натъкне на първо нарушение на ограничение, не е възможна по-нататъшна оценка, операторът е неуспешен, освен ако това ограничение не е отложено едно или log errors
клауза е включена в DML изявлението. Но трябва да се отбележи, че log errors
клаузата няма да може да улови всички възможни нарушения на ограниченията, просто записва първото.
Като един от възможните начини е да:
- създайте
exceptions
маса. Това може да стане чрез изпълнение наora_home/rdbms/admin/utlexpt.sql
скрипт. Структурата на таблицата е доста проста; - деактивирайте всички ограничения на таблицата;
- изпълнение на DML;
- активирайте всички ограничения с
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
Нарушени са две ограничения. За да разберете имената на колоните, просто вижте 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
Горната заявка ни дава имена на колони и редове от проблемни записи. Като имате rowids под ръка, не би трябвало да има проблем да намерите онези записи, които причиняват нарушение на ограниченията, да ги коригирате и отново да активирате ограниченията отново.
Ето скрипта, който е бил използван за генериране на 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