【问题标题】:Oracle 10g update table i from table 2 column join errorOracle 10g 从表 2 列连接错误更新表 i
【发布时间】:2013-12-20 10:18:13
【问题描述】:

我有以下 Oracle 10g sql,在我看来是正确的:

update ( select OLD1.TC_CUSTOMER_NUMBER,NEW1.PRD_CUST_NUMBER
       FROM  TBYC84_PROFILE_ACCOUNT OLD1,
             TMP_PRD_KEP NEW1
      WHERE 
        OLD1.TC_CUSTOMER_NUMBER = NEW1.KEP_CUST_NUMBER )
      SET 
        TC_CUSTOMER_NUMBER = PRD_CUST_NUMBER

但是当我运行脚本时出现这个错误:

SQL Error: ORA-01779: cannot modify a column which maps to a non key-preserved table
01779. 00000 -  "cannot modify a column which maps to a non key-preserved table"
*Cause:    An attempt was made to insert or update columns of a join view which
       map to a non-key-preserved table.
*Action:   Modify the underlying base tables directly.

我已经对此错误进行了一些研究,但不太确定如何补救。 所以我的问题是,我该如何解决这个问题,或者有没有更好的方法来编写更新 sql?

任何帮助将不胜感激。

非常感谢

更新 我已将更新 sql 更改为:

update 
  TBYC84_PROFILE_ACCOUNT PA 
set
  (
    PA.TC_CUSTOMER_NUMBER
      ) = (
    select
      TPK.PRD_CUST_NUMBER
    from
      TMP_PRD_KEP TPK
    where
      TPK.KEP_CUST_NUMBER = PA.TC_CUSTOMER_NUMBER  
     )

现在这已经更新了 TBYC84_PROFILE_ACCOUNT 表并取消了 TC_CUSTOMER_NUMBER 柱子。 为什么这样做? TBYC84_PROFILE_ACCOUNT.TC_CUSTOMER_NUMBER 中可能有不止一行 具有相同的帐号但用于不同的user_id。 请任何人都可以帮助我解决这个问题。 我需要做的就是将 TBYC84_PROFILE_ACCOUNT.TC_CUSTOMER_NUMBER 更新为 TMP_PRD_KEP 中的外部参照,这当然不是不可能的。

非常感谢

【问题讨论】:

标签: sql oracle oracle10g


【解决方案1】:

对于 UPDATE 语句,所有更新的列都必须从保留键的表中提取。

还有:

键保留表是指基表中的每个主键或唯一键值在连接视图中也是唯一的。

Here.

在这种情况下,TBYC84_PROFILE_ACCOUNT 正在更新。因此,它必须在视图的子查询中保留键。目前不是。必须通过在 where 子句中涉及主列或唯一列来将其更改为保留键的方式。如果不可能,您应该尝试更新基表。

更新

在表更新问题的情况下,假设子查询最多为TC_CUSTOMER_NUMBER 列返回一个不同的值,您得到 NULL 的原因是所有记录都在更新,即使它们在TMP_PRD_KEP 表。因此,父更新语句需要配备 where 子句:

update 
  TBYC84_PROFILE_ACCOUNT PA 
set
  (
    PA.TC_CUSTOMER_NUMBER
      ) = (
    select
      TPK.PRD_CUST_NUMBER
    from
      TMP_PRD_KEP TPK
    where
      TPK.KEP_CUST_NUMBER = PA.TC_CUSTOMER_NUMBER  
     )
where exists(select * 
             from TMP_PRD_KEP TPK
             where TPK.KEP_CUST_NUMBER = PA.TC_CUSTOMER_NUMBER) 
     ;

【讨论】:

  • 好的,所以我遇到的问题是 OLD1 表中的 TC_CUSTOMER_NUMBER 不是唯一的,并且永远不会作为具有名为 TC_PORTAL_ID 的列的复合主键的一部分。那么我该如何解决这个问题。我需要能够将所有 TC_CUSTOMER_NUMBER 值更新为引用表列 NEW1.PRD_CUST_NUMBER
  • 那么,要么所有主键列都必须出现在WHERE 子句中,要么如果不可能,您应该直接更新基表而不是视图:UPDATE TBYC84_PROFILE_ACCOUNT OLD1 = ...
  • 请阅读更新后的帖子,希望能解决问题。
【解决方案2】:

在 where 子句谓词中使用的列上创建索引。这应该可以解决您的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多