这是一个删除子句,它对我来说很完美,但我想知道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)
答案 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