我正在尝试清理DEV数据库中的一些不良数据(每个人都可以插入数据进行自我测试)并通过外键约束添加RI。这些表是为FK设置的,但数据不是。
是否有一种相对简单的方法从(tobe)子表中删除会违反复合键的数据?
CREATE TABLE parentTable
( key1 VARCHAR2(1) NOT NULL
, key2 VARCHAR2(1) NOT NULL
);
CREATE TABLE childTable
( key1 VARCHAR2(1) NOT NULL
, key2 VARCHAR2(1) NOT NULL
, key3 VARCHAR2(1) NOT NULL
);
ALTER TABLE parentTable ADD CONSTRAINT pk_parentTable primary key(key1,key2);
ALTER TABLE childTable ADD CONSTRAINT pk_childTable primary key(key1,key2,key3);
insert into parentTable values('0','A');
insert into parentTable values('0','B');
insert into parentTable values('1','C');
insert into childTable values('0','A','X');
insert into childTable values('0','B','Y');
insert into childTable values('1','C','X');
insert into childTable values('0','C','X'); -- bad data
我用来识别错误数据的查询如下:
select distinct key1, key2 from childTable
minus
select distinct key1, key2 from parentTable;
如何获取此结果集并从子表中删除它们。从逻辑上讲,我试图使用下面的查询,但它给出了ORA-00928的错误:缺少SELECT。
with x as(
select distinct key1, key2 from childTable
minus
select distinct key1, key2 from parentTable
)
delete from childtable where key1 = x.key1 AND key2 = x.key2;
还有其他方法可以轻松删除这些数据吗?
答案 0 :(得分:1)
Oracle实际上有一些内置功能来处理这个问题。
首先,运行@?/rdbms/admin/utlexcpt.sql
以创建例外表。
然后,(尝试)添加FK约束,如下所示:
alter table childtable add constraint my_fk foreign key (key1,key2) references parenttable(key1,key2) exceptions into exceptions;
那将完成,否则会出错。如果错误输出,则违反约束的行的行ID将位于例外表中。
然后,这是一个简单的执行问题:
delete from childtable where rowid in(select row_id from exceptions);
然后,只需重新执行上面的alter table add约束。
更多细节可以在这里找到: http://docs.oracle.com/cd/E11882_01/server.112/e41084/clauses002.htm#SQLRF52228
希望有所帮助....
答案 1 :(得分:0)
可替换地:
delete from childtable
where (key1,key2) not in
(select key1,key2 from parenttable)
答案 2 :(得分:0)
可能的解决方案是:
delete
from childTable
where not exists (select null
from parentTable
where childTable.key1 = parentTable.key1
and childTable.key2 = parentTable.key2);