PostgreSQL:重复键值违反了UPDATE命令的唯一约束

时间:2014-06-27 09:03:11

标签: postgresql postgresql-9.3

执行UPDATE查询时,我们收到以下错误消息:

ERROR:  duplicate key value violates unique constraint "tableA_pkey"
DETAIL:  Key (id)=(47470) already exists.

但是,我们的UPDATE查询不会影响主键。这是一个简化版本:

UPDATE tableA AS a
SET
    items = (
        SELECT array_to_string(
            array(
                SELECT b.value
                FROM tableB b
                WHERE b.a_id = b.id
                GROUP BY b.name
            ),
            ','
        )
    )
WHERE
    a.end_at BETWEEN now() AND  now() - interval '1 day';

我们确保主键序列已经同步:

\d tableA_id_seq

产生:

    Column     |  Type   |          Value           
---------------+---------+--------------------------
 sequence_name | name    | tableA_id_seq
 last_value    | bigint  | 50364
 start_value   | bigint  | 1
 increment_by  | bigint  | 1
 max_value     | bigint  | 9223372036854775807
 min_value     | bigint  | 1
 cache_value   | bigint  | 1
 log_cnt       | bigint  | 0
 is_cycled     | boolean | f
 is_called     | boolean | t

寻找最大表索引:

select max(id) from tableA;

我们的价值较低:

  max  
-------
 50363
(1 row)

你知道为什么会出现这种行为吗?如果我们排除有问题的ID,它就会起作用。

另一个奇怪的地方是将以前的UPDATE替换为:

UPDATE tableA AS a
SET
    items = (
        SELECT array_to_string(
            array(
                SELECT b.value
                FROM tableB b
                WHERE b.a_id = b.id
                GROUP BY b.name
            ),
            ','
        )
    )
WHERE a.id = 47470;

效果很好。我们错过了什么吗?

编辑:触发器

我在这张桌子上没有用户定义的触发器:

SELECT t.tgname, c.relname
FROM pg_trigger t
JOIN pg_class c ON t.tgrelid = c.oid
WHERE
    c.relname = 'tableA'
    AND
    t.tgisinternal = false
;

返回没有行。

注意:我正在使用 psql(PostgreSQL)9.3.4 版本。

1 个答案:

答案 0 :(得分:2)

不确定原因是什么。但是,删除与现有ID(?)对应的两条(非重要)记录可以解决问题。