【问题标题】:Postgres upsert: distinguish between new and updated rows [duplicate]Postgres upsert:区分新行和更新行[重复]
【发布时间】:2016-07-27 13:07:18
【问题描述】:

我正在考虑使用 PostgreSQL INSERT .. ON CONFLICT UPDATE 功能。理想情况下,我将能够区分成功插入哪些行以及更新了哪些行。有办法吗?

【问题讨论】:

  • 你需要一个额外的辅助列。
  • 使用这样的功能我看不到获得这些信息的方法,正如 Klin 所说,你需要一个列来存储发生的操作,即使这样你也需要另一件事来知道具体操作(因为它可以同时发生许多事情)。我能看到的最好的方法是有一个带有审计表的触发器。触发器将审核插入和更新,但即使使用触发器,您也需要一些东西来识别该操作以区别于以前的操作
  • 插入命令有一个RETURNING 子句,但我不知道它是否具有区分插入和更新的能力。在这里查看:Insert

标签: sql postgresql upsert


【解决方案1】:

有一种方法无需在表格中添加列:

CREATE TABLE tbl(id int PRIMARY KEY, col int);
INSERT INTO tbl VALUES (1, 1);
INSERT INTO tbl(id, col)
VALUES (1,11), (2,22)
ON     CONFLICT (id) DO UPDATE
SET    col = EXCLUDED.col
RETURNING *, (xmax = 0) AS inserted;

解释:

【讨论】:

    【解决方案2】:

    为此,您需要一个额外的辅助列(示例中为updated)。

    create table test (id int primary key, str text, updated boolean);
    insert into test values (1, 'old', false);
    
    insert into test values
        (1, 'new 1', false),
        (2, 'new 2', false)
    on conflict (id) do
    update set 
        str = excluded.str, updated = true
    returning *;
    
     id |  str  | updated 
    ----+-------+---------
      1 | new 1 | t
      2 | new 2 | f
    (2 rows)
    

    【讨论】:

    • 他如何将新更新的=true 与之前的冲突(来自另一个插入/更新)区分开来?这就是为什么我没有提供这样的答案。
    • 无需区分新旧冲突,因为returning * 的结果始终是最新的。
    • 嗯,没想到。感谢您的信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 2016-12-27
    • 1970-01-01
    • 2013-06-20
    相关资源
    最近更新 更多