DELETE FROM <subquery> </subquery>

时间:2014-01-25 07:58:45

标签: sql oracle oracle11g oracle10g

DELETE FROM (SELECT * FROM orders1 o,order_item1 i
WHERE i.order_id = o.order_id );

上面的查询没有提到特定的删除行。而不是我提到了一个子查询。 但是此查询执行时没有任何错误,并删除order_item1表行。

oracle服务器如何决定应删除哪些表行? 为什么orders1表行无法删除?

5 个答案:

答案 0 :(得分:11)

在您的情况下,子查询的表orders1肯定是主键 (order_id)和表order_item1具有相应的外键order_id

因此,Oracle将表order_item1转换为密钥保留表,并且能够在外部delete语句中从此表中删除。

密钥保留表的概念在This tahiti documentation link进一步说明。

如果你想找出删除的内容,你可以这样做

这些是在子查询中加入的表:

create table tq84_orders1 (
   id     number primary key,
   col_1  varchar2(10),
   col_2  date
);

create table tq84_order_item1 (
  order_id references tq84_orders1,
  col_3    varchar2(10),
  col_4    date
);

此视图模拟子查询:

create view tq84_orders_v as (
  select * 
  from
    tq84_orders1     o,
    tq84_order_item1 i
  where
    o.id = i.order_id
);

此查询(在user_updateable_columns上)现在可以找到实际删除(或可以删除​​)的列:

select
  table_name,
  column_name,
--updatable,
--insertable,
  deletable
from
  user_updatable_columns
where
  table_name = 'TQ84_ORDERS_V';

结果显示实际上可以删除三列ORDER_ID,COL_3和COL_4,所有这些都来自TQ84_ORDER_ITEM1。

TABLE_NAME                     COLUMN_NAME                    DEL
------------------------------ ------------------------------ ---
TQ84_ORDERS_V                  ID                             NO
TQ84_ORDERS_V                  COL_1                          NO
TQ84_ORDERS_V                  COL_2                          NO
TQ84_ORDERS_V                  ORDER_ID                       YES
TQ84_ORDERS_V                  COL_3                          YES
TQ84_ORDERS_V                  COL_4                          YES

答案 1 :(得分:0)

这可能对您有所帮助

DELETE FROM orders1 o CROSS JOIN order_item1 i WHERE i.order_id = o.order_id

答案 2 :(得分:0)

在您的Sub查询中,您提供了类似&#34; i.order_id = o.order_id&#34;。您可以尝试这样

DELETE FROM(SELECT * FROM orders1 o,order_item1 i WHERE o.order_id = i.order_id);

这是正确的

答案 3 :(得分:0)

我目前无法访问Oracle环境,因此无法验证,但以下内容在SQL Server中有效,并将从Orders表中删除。如果要从Order_Item中删除,请反转表。

DELETE o
FROM   Orders o
       JOIN Order_Item oi ON o.order_id = oi.order_id
WHERE  [filter condition]

答案 4 :(得分:0)

我认为如果你想删除just ONE表中的行,你可以使用这个查询:

DELETE FROM orders1 WHERE order_id in 
(SELECT o.order_id FROM orders1 o,order_item1 i
WHERE i.order_id = o.order_id );

但是如果你想从两个表中删除行,你可以这样做:

CREATE TABLE TEMP_TAB AS SELECT o.order_id FROM orders1 o,order_item1 i
WHERE i.order_id = o.order_id;

DELETE FROM order_item1 WHERE order_id in 
(SELECT TEMP_TAB.order_id FROM TEMP_TAB);

DELETE FROM orders1 WHERE order_id in 
(SELECT TEMP_TAB.order_id FROM TEMP_TAB);

DROP TABLE TEMP_TAB;