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

时间:2018-11-20 22:04:23

标签: sql oracle sql-update oracle12c

我有以下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%'

Here

我需要将col V_CUST_NUMBER中的值更新为col CASE_TITL_NM中的值,因此我在SELECT语句之后将UPDATE插入了内部,并仅运行它以获得ORA01779-< / p>

    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查询吗?

3 个答案:

答案 0 :(得分:2)

这是指定查询所导致的结果,该输出集中具有用于RA的重复行。看到一个RA行映射到两个不同的C行,您就无法更新RA,因为有可能尝试将唯一的RA行更新为具有两个不同的值

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

答案 1 :(得分:0)

请注意here,尤其是关于密钥保留

  

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

答案 2 :(得分:0)

我可以使用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%');