合并插入主键违反

时间:2012-02-06 14:19:15

标签: sql insert primary-key

所以我有以下查询得到重复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 个答案:

答案 0 :(得分:2)

特定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的{​​{1}}部分会尝试插入多个具有相同merge组合的行。这将导致主键违规。

答案 1 :(得分:0)

您的查询

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和dc_vert.loc的相同组合返回多个值。 如果您有两次5,10,例如,第一行将被插入,第二行将不会看到刚插入的那一行,因为它将与原始数据源进行比较