Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用不带WHERE或IN的subselect删除(保留键的表)_Sql_Oracle_Oracle10g - Fatal编程技术网

Sql 使用不带WHERE或IN的subselect删除(保留键的表)

Sql 使用不带WHERE或IN的subselect删除(保留键的表),sql,oracle,oracle10g,Sql,Oracle,Oracle10g,这里有一个delete子句,它对我来说非常有效,但我想知道oracle如何知道要删除哪个表中的数据 delete from (select * from t1 join t2 on t1.field1 = t2.field1) 确定将删除哪个表的机制是什么 在我的例子中,数据是从t1中删除的,t1和t2之间的关系是n->1 如果我更改子选择返回的顺序,结果将相同: delete from (select * from t2 join t1 on t1.field1 = t2.fiel

这里有一个delete子句,它对我来说非常有效,但我想知道oracle如何知道要删除哪个表中的数据

delete from (select * from t1 join t2  
on t1.field1 = t2.field1) 
确定将删除哪个表的机制是什么

在我的例子中,数据是从t1中删除的,t1和t2之间的关系是n->1

如果我更改子选择返回的顺序,结果将相同:

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

Oracle只会从所谓的。这是其键保留在结果联接中的表。换句话说,键保留表的行只能在结果联接中出现一次

这里,由于外键约束,在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中删除行:

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


@Piyush的问题是为什么数据会从t1表中删除为什么不从t2正如NoDisplayName所说,我的问题是为什么数据会从t1中删除,因为subselect的结果是两个表的连接,如果我将delete from select t1.*from t1 join t2 on t1.field1=t2.field1从t1中删除将是完全正常的,但是我放了select,甲骨文怎么知道的?这就是为什么它被称为甲骨文-如果我有两个表是join,但其中一个表没有PK,Oracle会选择该表进行键保留吗?我已经测试过了,join中没有只出现一次的值,但是oracle删除了没有PK的表的数据,但是如果两个表都有PK,oracle会出错,我编辑了我的答案,以向您展示一个示例,说明为什么Oracle会在您的第一个用例中从非PK表中删除行。但是请注意,密钥保留表不是数据的属性,而是架构的属性。因此,即使b表中没有重复的值,Oracle也会表现出相同的行为。关于您的第二个用例,我不知道您是如何进行测试的,但很可能Oracle没有或没有两个可能的键保留表,并且抱怨说它不知道您要从哪个表中删除行Oracle只会删除一个表中的行,我不建议您使用从选择中删除。。。参加语法,因为它是太多的混乱,至少说。你通常可以也应该这样做?将其重写为从中删除。。。哪里在选择中。检查查询执行计划,但它应该几乎相同。首先感谢您的解释,还有一个疑问:如果您从第一个表中删除PK,Oracle将得到一个错误,如如果没有一个保留键的表,则无法从视图中删除,为什么即使没有重复行也无法删除?如果两个表有PK,则删除非重复数据的操作正常。我知道这是schema的一个属性,但是当没有PK时出现的错误是奇怪的。@JohnnyWiller不考虑重复行。考虑模式提供的不变量。如果没有任何PK,则无法保证中的唯一性,并且Oracle无法假定任何表与联接结果集之间的1对1映射。
delete from (select * from a join b on a.n = b.n);
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