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

时间:2016-09-29 10:08:22

标签: 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语句,以确保只有具有title,year和author的条目插入到新数据库中。 (如果旧的话。“引用”。“ID”存在于旧的中。“ReferenceAuthor”作为“ReferenceID”,然后作者存在。)即使没有附加的WHERE语句,查询也是错误的。我在SELECT中指定的列仅出现在old."Reference"中,而不出现在old."ReferenceAuthor"中。 目前old."ReferenceAuthor"old."Reference"没有独特的约束,书籍专用的唯一限制是:

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抛出:

  

错误:ON CONFLICT DO UPDATE命令不能再次影响行   提示:确保在同一命令中建议不插入的行具有重复的约束值。   **********错误**********

     

错误:ON CONFLICT DO UPDATE命令不能再次影响行   SQL状态:21000   提示:确保在同一命令中不建议插入的行具有重复的约束值。

我不知道什么是错的,或者为什么提示指向重复的约束值。

2 个答案:

答案 0 :(得分:8)

问题是由于显然某些条目有多个作者。因此,您编写的select查询中的内部联接将返回同一条目的多个行,而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)
; 

答案 1 :(得分:1)

使用显式INNER JOIN将两个源表连接在一起:

INSERT INTO new.bookmonographs  (citavi_id, abstract, createdon, edition, title, year)
SELECT "ID", "Abstract", "CreatedOn"::timestamp, "Edition", "Title", "Year"
FROM old."Reference"
INNER JOIN old."ReferenceAuthor"                                       -- explicit join
    ON old."ReferenceAuthor"."ReferenceID" = old."Reference"."ID"      -- ON condition
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)