ORA-01779 не может изменить столбец, который сопоставляется с таблицей без сохранения ключей - PullRequest
0 голосов
/ 21 ноября 2018

У меня следующий запрос 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%'

Result of SELECT query

Мне нужно обновить значение в столбце V_CUST_NUMBER значением в столбцеCASE_TITL_NM поэтому я подключил свой SELECT к следующему оператору UPDATE и запустил его только для получения 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запрос

Ответы [ 3 ]

0 голосов
/ 21 ноября 2018

Пожалуйста, посмотрите здесь , особенно о сохранении ключа

Обновляемый запрос представления должен однозначно возвращать каждую строку измененной таблицы только один раз.Запрос должен быть «сохранен ключом», что означает, что Oracle должен иметь возможность использовать первичный ключ или уникальное ограничение, чтобы каждая строка изменялась только один раз.

0 голосов
/ 21 ноября 2018

Я смог выполнить свой запрос, используя 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%');
0 голосов
/ 21 ноября 2018

Это означает, что указанный запрос приводит к выходному набору с дублированными строками для RA.Видя, что одна строка RA отображается на две разные строки C, вы не можете обновить RA, потому что есть возможность попытаться обновить единственную строку RA, чтобы получить два разных значения

Вы можете попробовать использовать инструкцию MERGE, используя SQL-that-write-SQL для создания группы операторов UPDATE или изменения условия соединения, чтобы дублированные строки из RA не присутствовали в выходных данных, а первичный ключ из RA покрыт

...