当我尝试在 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/