使用subselect删除,不带WHERE或IN(Key-Preserved-Table)

时间:2015-01-20 17:14:08

标签: sql oracle oracle10g

这是一个删除子句,它对我来说很完美,但我想知道oracle如何知道哪个表删除数据?

delete from (select * from t1 join t2  
on t1.field1 = t2.field1) 

确定删除哪个表的机制是什么?

在我的情况下,数据从t1删除,t1和t2之间的关系是n - > 1。

如果我改变了subselect return的顺序,结果将是相同的:

delete from (select * from t2 join t1  
on t1.field1 = t2.field1) 

1 个答案:

答案 0 :(得分:3)

Oracle只会从所谓的key preserved table中删除。这是表,其键在结果连接中保留。换句话说,密钥保留表的行只能在结果连接中出现一次

这里,由于外键约束,您在t1和t2之间有一个n -> 1映射。因此,Oracle必须选择t1作为密钥保留表,因为在联接结果中可能会有几次相同的t2行。


表的密钥保留属性不依赖于表中的实际数据。它是其架构的属性。下面的评论中的每个OP请求,这是一个例子:

create table a (n int primary key);
create table b (n int);

insert into a values(1);
insert into b values(1);
insert into b values(1);

以下语句将删除b中的行:

delete from (select * from a join b on a.n = b.n);

为什么来自b的行?因为,Oracle可以确保表b中的行与结果集中的行之间存在一对一映射。因此,b密钥保留表。参见:

select a.*, a.rowid, b.*, b.rowid from a join b on a.n = b.n;

  a.n | a.ROWID            | b.n| b.ROWID
  ----+--------------------+----+-------------------
    1 | AAAKUKAAEAAAAv8AAA |  1 | AAAKUMAAEAAAAwMAAA 
    1 | AAAKUKAAEAAAAv8AAA |  1 | AAAKUMAAEAAAAwMAAB