自定义关系更新:是否需要主键?

时间:2018-10-24 16:11:05

标签: sql oracle sql-update primary-key

UPDATE (
    SELECT
        o.order_id,
        o.shipping_from
    FROM
        orders o,
        items i
    WHERE
        o.item_id = i.item_id
        AND o.shipping_from = 'foot'
        AND i.type = 'ent'
) t
SET
    t.shipping_from = 'car';

内部SELECT查询从orders返回2行。整个查询都可以正常工作,但例外情况除外。 o.order_idi.item_id是主键,o.item_id是外键,其他列的名称不匹配。

以这种方式运行更新时,是否需要在要更新的关系中包含主键?为什么?如果不是,DBMS将如何知道另一表中有一行?当然,items没有shipping_from字段,因此我选择哪一行并不是很明确,但是如果选择的话呢?

一些数据示例:

SELECT * FROM items WHERE type = 'ent';
   ITEM_ID ITEM_SERIAL_CODE     NAME                 BRAND                TYPE         DAILY_COST PURCHASE_DAT
---------- -------------------- -------------------- -------------------- ------------ ---------- ------------
      1007 DC00755250           Dragon costume       Branded              ent               19000 14-DEC.  -15
      1010 SS01003632           Serpentine streamer  Chinese              ent              132500 10-MÁRC. -03

SELECT * FROM orders WHERE shipping_from = 'foot';
  ORDER_ID    ITEM_ID   EVENT_ID LIABLE_PERSON   SHIPPING_T SHIPPING_F ORDER_COMMENT
---------- ---------- ---------- --------------- ---------- ---------- -----------------------------------
      3011       1006       2010 Géza Nagy       car        foot       It will be a great party.
      3018       1009       2011 Ferenc Nagy     boat       foot       Multiple celebs expected.
      3019       1010       2011 Ferenc Balázs   bus        foot       Changing weather, changing seasons.
      3020       1010       2012 Béci Patkó      boat       foot       Bring the stuff to the first floor.

2 个答案:

答案 0 :(得分:2)

  

是否需要在我想要的关系中包含主键   更新?为什么?


答案在文档中:24.1.5 DML Statements and Join Views

  

更新联接视图

     

可更新的联接视图(也称为可修改的联接视图)是包含以下内容的视图:   SELECT语句的顶级FROM子句,不受限制   通过WITH READ ONLY子句。

     

下表列出了可更新联接视图的规则。   符合这些条件的视图被认为具有固有的可更新性。

     
      
  • 一般规则:对联接视图进行的任何INSERT,UPDATE或DELETE操作一次只能修改一个基础表。
  •   
  • 更新规则:联接视图的所有可更新列都必须映射到键保留表的列。有关保留键表的讨论,请参见"Key-Preserved Tables"。如果视图是使用WITH CHECK OPTION子句定义的,则所有联接列和重复表的所有列均不可更新。
  •   
     

.......................

在上述文档的上下文中,UPDATE语句(UPDATE ( subquery ) SET ...)中的子查询被视为视图,就像UPDATE the_view SET ...一样-因为任何视图都是除了(子)查询而已。

答案 1 :(得分:0)

我想知道的答案是否定的。投影列表中不需要主键,即使在子查询中未选择UPDATEo.order_id的效果也相同。但是,由于声明性技术,这并不意味着主键未被使用。无论包括或不包括主键,都将创建相同的执行计划以获取将更新的记录:

SQL Developer's explain plan view

这里的投影变化不大,散列连接操作完成后,DBMS可以识别每行,请参阅krokodilko的答案。

如果您没有从表中选择任何内容(例如键入SELECT 1 FROM ...),则无法执行update命令,子查询的结果只是一些数据的常规集合,它可以不能被映射到表。

我认为我们应该始终包含主键,以使读者清楚地知道内部查询(我们计划更新哪个表)中使用了子查询的结果。