ORA-01779 无法修改映射到非键保留表的列

Posted

技术标签:

【中文标题】ORA-01779 无法修改映射到非键保留表的列【英文标题】:ORA-01779 cannot modify a column which maps to a non key-preserved table 【发布时间】:2018-11-20 22:04:22 【问题描述】:

我有以下SELECT 查询-

SELECT C.CASE_TITL_NM,RA.V_CUST_NUMBER
FROM KDD_CASES C
JOIN FCT_RA RA
ON RA.N_RA_ID = C.RA_ID
WHERE UPPER(C.CNTRY_KEY_ID) LIKE '%MANUAL%' 
AND C.SCORE_CT IN (99,100)
AND C.STATUS_CD = 'CCD'
AND C.CASE_TITL_NM NOT LIKE 'MANUAL%'

我需要用 col CASE_TITL_NM 中的值更新 col V_CUST_NUMBER 中的值,所以我将我的 SELECT 插入到 UPDATEstatement 之后并运行它只是为了得到 ORA01779 -

    UPDATE (
    SELECT C.CASE_TITL_NM,RA.V_CUST_NUMBER
    FROM KDD_CASES C
    JOIN FCT_RA RA
    ON RA.N_RA_ID = C.RA_ID
    WHERE UPPER(C.CNTRY_KEY_ID) LIKE '%MANUAL%' 
    AND C.SCORE_CT IN (99,100)
    AND C.STATUS_CD = 'CCD'
    AND C.CASE_TITL_NM NOT LIKE 'MANUAL%'
    ) X
    SET X.V_CUST_NUMBER = X.CASE_TITL_NM;

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.

谁能解释这个错误是什么意思以及正确的UPDATE查询是什么?

【问题讨论】:

【参考方案1】:

这意味着指定的查询会导致输出集包含重复的 RA 行。看到一个 RA 行映射到两个不同的 C 行,您无法更新 RA,因为有可能尝试更新唯一的 RA 行以具有两个不同的值

您可以尝试使用 MERGE 语句,使用 SQL-that-writes-SQL 创建一堆 UPDATE 语句,或修改连接条件,使来自 RA 的重复行不会出现在输出中,并且来自 RA 的主键是覆盖

【讨论】:

【参考方案2】:

我能够使用EXIST 子句运行我的查询

UPDATE FCT_RA F
SET F.V_CUST_NUMBER = ( SELECT CASE_TITL_NM 
             FROM KDD_CASES C
             WHERE F.N_RA_ID = C.RA_ID
             AND UPPER(CNTRY_KEY_ID) LIKE '%MANUAL%' 
             AND SCORE_CT IN (99,100)
             AND STATUS_CD = 'CCD'
             AND CASE_TITL_NM NOT LIKE 'MANUAL%')
WHERE EXISTS ( SELECT 1 
             FROM KDD_CASES C
             WHERE F.N_RA_ID = C.RA_ID
             AND UPPER(CNTRY_KEY_ID) LIKE '%MANUAL%' 
             AND SCORE_CT IN (99,100)
             AND STATUS_CD = 'CCD'
             AND CASE_TITL_NM NOT LIKE 'MANUAL%');

【讨论】:

【参考方案3】:

请看here,尤其是关于密钥保留的问题

可更新视图查询必须明确返回 只修改了一次表。查询必须是“保留密钥”,即 意味着 Oracle 必须能够使用主键或唯一约束来 确保每一行只修改一次。

【讨论】:

以上是关于ORA-01779 无法修改映射到非键保留表的列的主要内容,如果未能解决你的问题,请参考以下文章

Oracle - 更新连接 - 非键保留表

Oracle - 更新连接 - 非键保留表

更新表不能修改映射到非键保留表的列

如何在 Power BI 中合并两个基于非键表的表

使用具有和 MIN 函数非键保留表错误进行更新

RestKit 映射错误“无法将对象集合映射到非可变集合。”