【问题标题】:ERROR: duplicate key value violates unique constraint in postgreSQL错误:重复键值违反 postgreSQL 中的唯一约束
【发布时间】:2011-07-11 14:06:35
【问题描述】:

我在更新表时在 postgresql 中遇到了一个独特的约束问题。我有一个包含 3 列的表,并且在其中一列(internal_state)上有一个唯一约束。该表将只有两列,internal_state 的值为 1,0。 更新查询是

UPDATE backfeed_state SET internal_state = internal_state - 1
WHERE EXISTS (SELECT 1 FROM backfeed_state d2 WHERE d2.internal_state = 1 )

在 MSSqlserver 中运行此查询很好,但在 postgre 中它会引发唯一约束错误。 我的理解是在更新所有行之后在 SQLServer 中,然后只检查列上的约束,但在更新每一行后在 postgre 中,正在检查约束。因此,在更新第一行(internal_state 值从 1 到 0)之后,postgre 甚至在更新第二行之前检查约束并抛出错误。

有没有办法避免这种情况?

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    http://www.postgresql.org/docs/9.0/static/sql-createtable.html 在“非延迟唯一性约束”部分 - “当 UNIQUE 或 PRIMARY KEY 约束不可延迟时,只要插入或修改行,PostgreSQL 就会立即检查唯一性。”

    将您的唯一约束更改为可延迟将推迟检查,直到更新结束。要么使用 SET CONSTRAINTS 在会话级别禁用(这很烦人),要么使用 deferable 选项删除并重新创建唯一性约束(我不知道 ALTER 构造可以在不删除的情况下做到这一点)。

    【讨论】:

    • 嗨,我们正在使用 postgres8.4,其中这个 DEFERRABLE 概念没有针对唯一约束实现。是否有任何其他解决方法或替代方法
    • 我看错了你的代码;我将从一个更简单的重写开始,如下所示: UPDATE backfeed_state SET internal_state = internal_state - 1 WHERE internal_state = 1。如果您的意图是“翻转” 1 和 0,您可以尝试删除唯一性,使用 SET internal_state 进行更新= 1 - internal_state,然后加回唯一性(假设您确实想保留该约束)。
    • 只有当我至少有一行的 internal_state 值为“1”时,我才会更新记录。这就是为什么我有条件WHERE EXISTS (SELECT 1 FROM backfeed_state d2 WHERE d2.internal_state = 1 )
    • @subash - 这没有意义 - 你说你总是有两行,其中一个总是 internal_state=0,另一个 internal_state=1。所以你的where exists 永远是真的。
    猜你喜欢
    • 2011-10-17
    • 2016-10-24
    • 2011-05-25
    • 2016-09-28
    • 2020-02-15
    • 2016-07-27
    • 1970-01-01
    • 2012-03-03
    相关资源
    最近更新 更多