Sql Oracle:如何获取所有可能的约束冲突?
我想知道数据库中是否存在会违反所有禁用约束的数据。(如果已启用约束) 我得到所有禁用的约束,如下所示:Sql Oracle:如何获取所有可能的约束冲突?,sql,oracle,constraints,Sql,Oracle,Constraints,我想知道数据库中是否存在会违反所有禁用约束的数据。(如果已启用约束) 我得到所有禁用的约束,如下所示: select * from all_constraints where STATUS='DISABLED'; SQL> @?\rdbms\admin\utlexpt1 Table created. 有解决方案吗?逐个启用禁用的约束。一旦它们失败,请检查哪些数据阻止启用它们 顺便问一下,禁用约束有什么用?如果应该约束数据,请启用它们。如果没有,您为什么会在意呢?使用PL/SQL和AL
select * from all_constraints where STATUS='DISABLED';
SQL> @?\rdbms\admin\utlexpt1
Table created.
有解决方案吗?逐个启用禁用的约束。一旦它们失败,请检查哪些数据阻止启用它们
顺便问一下,禁用约束有什么用?如果应该约束数据,请启用它们。如果没有,您为什么会在意呢?使用PL/SQL和
ALTER TABLE TABLE\u NAME ENABLE CONSTRAINT EXCEPTION INTO
功能收集有关约束冲突的数据
示例模式
创建两个具有禁用约束的表。一个有好数据,另一个有坏数据,验证失败:
drop table good_data;
drop table bad_data;
create table good_data(a number, constraint good_data_uq unique(a) disable novalidate);
insert into good_data values(1);
create table bad_data(a number, constraint bad_data_uq unique(a) disable novalidate);
insert into bad_data values(1);
insert into bad_data values(1);
commit;
启用所有禁用的约束
异常进入
子句需要一个特定形状的表来存储结果。没有帮助构建表的包,您必须在服务器上调用如下脚本:
select * from all_constraints where STATUS='DISABLED';
SQL> @?\rdbms\admin\utlexpt1
Table created.
此PL/SQL块循环遍历所有禁用的约束并尝试启用它们:
declare
v_sql varchar2(32767);
v_cannot_validate exception;
pragma exception_init(v_cannot_validate, -2299);
begin
--Remove previous exceptions.
delete from exceptions;
commit;
--Enable all disabled constraints.
--Ignore errors, but log all exceptions for later analysis.
for constraints in
(
select owner, constraint_name, table_name
from all_constraints
where status = 'DISABLED'
and owner = user
and table_name not like 'BIN$%'
order by owner, constraint_name
) loop
v_sql :=
'alter table '||constraints.owner||'.'||constraints.table_name||
' enable constraint '||constraints.constraint_name||
' exceptions into exceptions';
begin
execute immediate v_sql;
exception
when v_cannot_validate then null;
when others then
raise_application_error(-20000, 'Error with this SQL: '||
v_sql||chr(10)||sqlcode||sqlerrm);
end;
end loop;
end;
/
视图异常
我找到了一个简单的解决方案:
spool 'disabled_constraint_violations.txt';
set serverout on size unlimited
DECLARE
sql_enable varchar2(400);
sql_disable varchar2(400);
BEGIN
FOR c IN (select OWNER, TABLE_NAME, CONSTRAINT_NAME from all_constraints where STATUS='DISABLED') LOOP
BEGIN
sql_enable := ' alter table ' || c.owner||'.'||c.table_name || ' enable constraint ' || c.constraint_name;
execute immediate sql_enable ;
sql_disable := ' alter table ' || c.owner||'.'||c.table_name || ' disable constraint ' || c.constraint_name;
execute immediate sql_disable ;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('table: '||c.table_name||' || constraint: '||c.constraint_name||' || error message: '||sqlerrm);
END;
END LOOP;
END;
set serveroutput off
spool off
这涉及到数千个约束。应该移动数据库并记录这些信息。好吧,您可以编写一些代码来完成这项工作(循环禁用的约束/启用约束/记录失败的约束),然后只调查失败的约束。有没有办法自动化整个过程(包括违反这些约束的数据)?我不这么认为。我使用禁用的约束来运行从“自然”外键到代理外键的自动更新。自然关键点上的外键约束已禁用。