1

我正在尝试从 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; 

还有其他方法可以轻松删除这些数据吗?

4

3 回答 3

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 constraint即可。

更多细节可以在这里找到:http: //docs.oracle.com/cd/E11882_01/server.112/e41084/clauses002.htm#SQLRF52228

希望有帮助....

于 2013-10-30T06:28:08.550 回答
0

或者:

delete from childtable 
where (key1,key2) not in 
    (select key1,key2 from parenttable)
于 2013-10-30T07:16:54.367 回答
0

一个可能的解决方案是:

delete
  from childTable
 where not exists (select null
                     from parentTable
                    where childTable.key1 = parentTable.key1
                      and childTable.key2 = parentTable.key2);
于 2013-10-30T07:18:49.143 回答