尽管存在检查,“重复键值违反了唯一约束”

问题描述 投票:0回答:1

在PostgreSQL 9.4上。

我很惊讶地看到我们的服务器日志中的错误,精确定位到pl / pgsql函数内的唯一语句:

CREATE OR REPLACE FUNCTION my_upsert(
    intype text,
    invalue text)
  RETURNS void AS
$BODY$
BEGIN

  WITH upsert AS
  (
    UPDATE mytable
      SET count = count + 1
    WHERE type = inType
      AND value = inValue
    RETURNING *
  )
  INSERT INTO mytable
  (
    value,
    type
  )
  SELECT inValue, inType WHERE NOT EXISTS (SELECT * FROM upsert);

END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

除非升级到9.5,所以我们可以使用内置的upsert功能,这样的单个语句怎么可能以这种方式失败? (这可以避免吗?)

sql postgresql duplicates postgresql-9.4 upsert
1个回答
1
投票

https://www.postgresql.org/message-id/8316.1296788047%40sss.pgh.pa.us

Re:是不是“插入不存在的地方”原子?

不,它不是:它

在其他交易存在同样的事情时会失败...>

AFAIR的基本替代方案是insert - > exception - > update或在表级锁定

(引用非常不准确 - 强烈建议阅读帖子)

如果我理解Toms指令,在9.5 upsert之前,唯一的选择是insert,如果异常更新或者其他什么......

© www.soinside.com 2019 - 2024. All rights reserved.