Oracle 10g更新表i来自表2列连接错误

时间:2013-12-20 10:18:14

标签: sql oracle oracle10g

我有以下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中的xrefed,这肯定不是不可能的。

非常感谢

2 个答案:

答案 0 :(得分: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) 
     ;

答案 1 :(得分:0)

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