postgresql - Upsert 错误(On Conflict Do Update)指向重复的约束值

标签 postgresql upsert

当我尝试在 FROM 语句中使用多个源时,我在 Postgres 9.5 中遇到 ON CONFLICT DO UPDATE 问题。

工作代码示例:

    INSERT INTO new.bookmonographs  (citavi_id, abstract, createdon, edition, title, year)
SELECT "ID", "Abstract", "CreatedOn"::timestamp, "Edition", "Title", "Year"
FROM old."Reference"
WHERE old."Reference"."ReferenceType" = 'Book'
    AND old."Reference"."Year" IS NOT NULL
    AND old."Reference"."Title" IS NOT NULL
ON CONFLICT (citavi_id) DO UPDATE 
    SET (abstract, createdon, edition, title, year) = (excluded.abstract, excluded.createdon, excluded.edition, excluded.title, excluded.year)
; 

错误代码:

    INSERT INTO new.bookmonographs  (citavi_id, abstract, createdon, edition, title, year)
SELECT "ID", "Abstract", "CreatedOn"::timestamp, "Edition", "Title", "Year"
FROM old."Reference", old."ReferenceAuthor"
WHERE old."Reference"."ReferenceType" = 'Book'
    AND old."Reference"."Year" IS NOT NULL
    AND old."Reference"."Title" IS NOT NULL
    AND old."ReferenceAuthor"."ReferenceID" = old."Reference"."ID"
    --Year, Title and Author must be present in the data, otherwise the entry is deemed useless, hence won't be included
ON CONFLICT (citavi_id) DO UPDATE 
    SET (abstract, createdon, edition, title, year) = (excluded.abstract, excluded.createdon, excluded.edition, excluded.title, excluded.year)
; 

我在 FROM 语句和一个 WHERE 语句中添加了一个额外的源,以确保只有具有标题、年份和作者的条目被插入到新数据库中。 (如果旧的“Reference”,“ID”作为“ReferenceID”存在于旧的“ReferenceAuthor”中,那么作者就存在。)即使没有附加的 WHERE 语句,查询也是错误的。我在 SELECT 中指定的列仅出现在 old."Reference" 中,而不出现在 old."ReferenceAuthor" 中。 目前 old."ReferenceAuthor"old."Reference" 没有 UNIQUE CONSTRAINT,专着的 uniqe 约束是:

CONSTRAINT bookmonographs_pk PRIMARY KEY (bookmonographsid),
CONSTRAINT bookmonographs_bookseries FOREIGN KEY (bookseriesid)
      REFERENCES new.bookseries (bookseriesid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT bookmonographs_citaviid_unique UNIQUE (citavi_id)

PSQL 抛出的错误:

ERROR: ON CONFLICT DO UPDATE command cannot affect row a second time HINT: Ensure that no rows proposed for insertion within the same command have duplicate constrained values. ********** Error **********

ERROR: ON CONFLICT DO UPDATE command cannot affect row a second time SQL state: 21000 Hint: Ensure that no rows proposed for insertion within the same command have duplicate constrained values.

我不知道出了什么问题,或者为什么提示指向重复的约束值。

最佳答案

问题是由于某些条目显然有多个作者这一事实引起的。因此,您编写的选择查询中的内部联接将为同一条目返回多行,而 INSERT ... ON CONFLICT 不喜欢这样。由于您仅使用 ReferenceAuthor 表进行过滤,因此您可以简单地重写查询,以便它使用该表通过执行 exists 来仅过滤没有任何作者的条目> 在相关子查询上。方法如下:

INSERT INTO new.bookmonographs  (citavi_id, abstract, createdon, edition, title, year)
SELECT "ID", "Abstract", "CreatedOn"::timestamp, "Edition", "Title", "Year"
FROM old."Reference"
WHERE old."Reference"."ReferenceType" = 'Book'
    AND old."Reference"."Year" IS NOT NULL
    AND old."Reference"."Title" IS NOT NULL
    AND exists(SELECT FROM old."ReferenceAuthor" WHERE old."ReferenceAuthor"."ReferenceID" = old."Reference"."ID")
    --Year, Title and Author must be present in the data, otherwise the entry is deemed useless, hence won't be included
ON CONFLICT (citavi_id) DO UPDATE 
    SET (abstract, createdon, edition, title, year) = (excluded.abstract, excluded.createdon, excluded.edition, excluded.title, excluded.year)
; 

关于postgresql - Upsert 错误(On Conflict Do Update)指向重复的约束值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39767369/

相关文章:

mongodb - Upsert 操作时 MongoDB 出现重复键错误

mysql - ASP.net C#——将来自 MySQL 的数据集合并到 SQL Server 2008 表中

sql-server - 检查记录是否存在,如果是,则“更新”,如果不是,则“插入”

python - 将 connection_factory 指定给 SQLAlchemy 的 create_engine()

mysql - 插入MySQL表或更新(如果存在)

database - 持久化docker容器的数据库

sql - 如果group by满足一个条件,则过滤

sqlite - 如果不存在则插入其他更新?

sql - 当 Dbh 查询在 FreeSWITCH 中返回零行时,如何在 Lua 脚本中匹配 "-ERR no reply"?

ruby-on-rails - 我如何构造此 Rails/PostgreSQL 查询以根据模型子项的属性返回模型实例?