在 PostgreSQL 中使用 EXCLUDE 值进行 Upsert(重复更新时插入、合并)

发布时间 2023-04-08 14:39:23作者: Thenext

上次,我们读到了如何在 PostgreSQL 中使用 UPSERT

在快速回顾中,UPSERT 是 INSERT ON DUPLICATE UPDATE 的缩写,如果它们与以前的条目不匹配,则倾向于将 INSERT 值插入表中。如果有,它们会自动更新。

PostgreSQL 中的 EXCLUDED 是什么

EXCLUDED 是 DBMS 给一个特殊表的名称,在该表中我们有为 INSERTION 提议的所有行。一旦 INSERT 操作运行,这些行可能会插入到该表中。

这主要是在 ON CONFLICT DO UPDATE 子句之前,专门针对此表。此外,SET 和 WHERE 子句往往具有访问此 EXCLUDED 表的权限。

因此,下次你尝试 INSERT 某些内容时,如果它似乎满足你的需求,你可以使用 EXCLUDED 表。我们希望你清楚本文中使用的基本术语及其背后的机制。

让我们开始学习一些方法,其中许多是简短而有效的变通方法,以实现 EXCLUDED 表的使用。

PostgreSQL 中的基本 EXCLUDE 用法

可以实现第一个非常简单的 EXCLUDE 用法。

  1. 让我们为动物创建一个 TABLE

    createtableanimal(idintPRIMARYKEY,ageint,typeTEXT);

    TYPE 这里代表动物类型。可以是猫、狗、马等。

  2. 让我们插入一些值。

    insertintoanimalvalues(1,10,'Dog'),(2,12,'Horse')
  3. 现在,让我们继续编写 EXCLUDED 的查询。

    insertintoanimalvalues(1,3,'Cat'),(3,4,'Kitten')onconflict(id)doupdatesetid=excluded.id,age=excluded.age,type=excluded.type;

那么这里发生了什么?首先,有一个副本。

集合 (1, 3, 'Cat') 违反了 PRIMARY KEY 的唯一约束,因为已经存在带有键 1 的 (1, 10, 'Dog')

所以我们调用 ON CONFLICT DO UPDATE,然后一旦它发现违规,我们将该行的键设置为正在插入的新数据集的键,从而覆盖先前的条目。

输出将是这样的。

输出:

在 PostgreSQL 中使用排除

但是,这取决于你是否要执行此操作。如果在插入时,你可能不想覆盖,而是保持前一个条目完整,那么在这种情况下,你根本不应该使用此查询。

PostgreSQL 中基本 EXCLUDED 用法的结构差异

如果用户可能试图保持语句紧凑和可读,他们可能会尝试避免使用上述查询,其中:

setid=excluded.id,age=excluded.age,type=excluded.type;

如果大量数据是 INSERTED 或 UPDATED,这可能会变得混乱并随后导致问题。

一个更简单的方法是改用它。

set(id,age,type)=(EXCLUDED.id,EXCLUDED.age,EXCLUDED.type)

这倾向于对元素进行分组,并且与上面描述的几乎相同,但更加有序和可读。