Слияние вставки первичного ключа нарушено - PullRequest
0 голосов
/ 06 февраля 2012

Итак, у меня есть следующий запрос, который получает ошибку Duplicate PK Что я делаю неправильно?

//////// РЕДАКТИРОВАТЬ PK = ITEM & LOC

MERGE INTO item_loc_traits il 
USING   (
        SELECT  item, loc, reward_eligible_ind 
        FROM    (
                SELECT  dc_vert.item , dc_vert.loc, dc_vert.actie, 
                        dc_vert.reward_eligible_ind, 
                        MAX(dc_vert.actie) over 
                            (PARTITION BY dc_vert.item, dc_vert.loc) actie_max
                FROM    dc_item_loc_vert dc_vert
                ) 
        WHERE   actie = actie_max
        ) dc_vert
ON      il.item = dc_vert.item
        AND il.loc = dc_vert.loc
WHEN MATCHED THEN
       UPDATE   
       SET      il.deposit_code = reward_eligible_ind
        ,       il.last_update_datetime = SYSDATE;
WHEN NOT MATCHED THEN
       INSERT (item, loc, deposit_code, last_update_datetime, 
               last_update_ID, create_datetime)
       VALUES (dc_vert.item, dc_vert.loc, dc_vert.reward_eligible_ind,
               SYSDATE, 'CNVOBJ_SRC', SYSDATE);

Ответы [ 2 ]

2 голосов
/ 06 февраля 2012

В источнике слияния возможно несколько строк для определенного item, loc.Вы можете проверить это с помощью следующего запроса:

SELECT  item, loc
FROM    (
        SELECT  item, loc, reward_eligible_ind 
        FROM    (
                SELECT  dc_vert.item , dc_vert.loc, dc_vert.actie, 
                        dc_vert.reward_eligible_ind, 
                        MAX(dc_vert.actie) over 
                            (PARTITION BY dc_vert.item, dc_vert.loc) actie_max
                FROM    dc_item_loc_vert dc_vert
                ) 
        WHERE   actie = actie_max
        ) sub
GROUP BY
        item, loc
HAVING  count(*) > 1

Если при этом будут возвращены какие-либо строки, часть when not matched вашего merge попытается вставить несколько строк с одной и той же комбинацией item, loc.Это может привести к нарушению первичного ключа.

0 голосов
/ 06 февраля 2012

ваш запрос

SELECT  item, loc, reward_eligible_ind 
        FROM    (
                SELECT  dc_vert.item , dc_vert.loc, dc_vert.actie, 
                        dc_vert.reward_eligible_ind, 
                        MAX(dc_vert.actie) over 
                            (PARTITION BY dc_vert.item, dc_vert.loc) actie_max
                FROM    dc_item_loc_vert dc_vert
                ) 
        WHERE   actie = actie_max

возвращает более одного значения для одной и той же комбинации dc_vert.item AND dc_vert.loc. Например, если у вас дважды 5, 10, первая строка будет вставлена, а вторая не увидит только что вставленную, поскольку она будет сравниваться с исходным источником данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...