在 PostgreSQL 中使用 EXCLUDE 值进行 Upsert(重复更新时插入、合并)
上次,我们读到了如何在 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
用法。
-
让我们为动物创建一个
TABLE
。createtableanimal(idintPRIMARYKEY,ageint,typeTEXT);
TYPE
这里代表动物类型。可以是猫、狗、马等。 -
让我们插入一些值。
insertintoanimalvalues(1,10,'Dog'),(2,12,'Horse')
-
现在,让我们继续编写
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 中基本 EXCLUDED
用法的结构差异
如果用户可能试图保持语句紧凑和可读,他们可能会尝试避免使用上述查询,其中:
setid=excluded.id,age=excluded.age,type=excluded.type;
如果大量数据是 INSERTED
或 UPDATED
,这可能会变得混乱并随后导致问题。
一个更简单的方法是改用它。
set(id,age,type)=(EXCLUDED.id,EXCLUDED.age,EXCLUDED.type)
这倾向于对元素进行分组,并且与上面描述的几乎相同,但更加有序和可读。