J'ai une requête SELECT suivante -

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%'

Result of SELECT query

J'ai besoin de mettre à jour la valeur dans le col V_CUST_NUMBER avec la valeur dans le col CASE_TITL_NM, donc j'ai branché mon SELECT à l'intérieur de l'instruction suivante UPDATE et l'ai exécutée uniquement pour obtenir 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.

Quelqu'un peut-il expliquer ce que signifie cette erreur et quelle serait la bonne requête UPDATE?

1
Reeya Oberoi 21 nov. 2018 à 01:04

3 réponses

Meilleure réponse

J'ai pu exécuter ma requête en utilisant la clause 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%');
1
Reeya Oberoi 20 nov. 2018 à 23:55

Cela signifie que la requête telle que spécifiée aboutit à un ensemble de sortie contenant des lignes dupliquées pour RA. Étant donné qu'une ligne RA correspond à deux lignes C différentes, vous ne pouvez pas mettre à jour RA, car il est possible d'essayer de mettre à jour la seule ligne RA pour avoir deux valeurs différentes

Vous pouvez essayer d'utiliser une instruction MERGE, en utilisant SQL-qui-écrit-SQL pour créer un tas d'instructions UPDATE, ou en modifiant la condition de jointure afin que les lignes dupliquées de RA ne soient pas présentes dans la sortie et que la clé primaire de RA soit couverte

2
Caius Jard 20 nov. 2018 à 23:11

Veuillez regarder ici, en particulier sur la clé préservée

La requête de vue modifiable doit renvoyer sans ambiguïté chaque ligne de la table modifiée une seule fois. La requête doit être "clé préservée", ce qui signifie qu'Oracle doit pouvoir utiliser une clé primaire ou une contrainte unique pour garantir que chaque ligne n'est modifiée qu'une seule fois.

0
RGruca 20 nov. 2018 à 23:19