ChatGPT解决这个技术问题 Extra ChatGPT

PostgreSQL INSERT ON CONFLICT UPDATE (upsert) 使用所有排除值

当您更新一行时(PostgreSQL >= 9.5),并且您希望可能的 INSERT 与可能的 UPDATE 完全相同,您可以这样编写:

INSERT INTO tablename (id, username, password, level, email) 
                VALUES (1, 'John', 'qwerty', 5, 'john@mail.com') 
ON CONFLICT (id) DO UPDATE SET 
  id=EXCLUDED.id, username=EXCLUDED.username,
  password=EXCLUDED.password, level=EXCLUDED.level,email=EXCLUDED.email

有没有更短的方法?只是说:使用所有 EXCLUDE 值。

在 SQLite 中,我曾经这样做:

INSERT OR REPLACE INTO tablename (id, user, password, level, email) 
                        VALUES (1, 'John', 'qwerty', 5, 'john@mail.com')
不是一个真正的答案,但您可以使用稍微简短的符号:INSERT INTO tablename (id, username, password, level, email) VALUES (1, 'John', 'qwerty', 5, 'john@mail.com') ON CONFLICT (id) DO UPDATE SET (username, password, level, email) = (EXCLUDED.username, EXCLUDED.password, EXCLUDED.level, EXCLUDED.email). 几乎相同,但易于复制/粘贴/管理列列表
另一种选择是使用 jsonb 列,这样您就不必担心列
@foal 作为答案发布,这是一个非常有用的选择。
您不需要更新 id,因为它是相同的(冲突字段)。这使它更短一些。

B
Braiam

Postgres 尚未实现 INSERT OR REPLACE 的等效项。从 ON CONFLICT docs(强调我的):

它可以是 DO NOTHING 或 DO UPDATE 子句,指定在发生冲突时要执行的 UPDATE 操作的确切细节。

虽然它没有为您提供替换的简写,但 ON CONFLICT DO UPDATE 更普遍适用,因为它允许您根据预先存在的数据设置新值。例如:

INSERT INTO users (id, level)
VALUES (1, 0)
ON CONFLICT (id) DO UPDATE
SET level = users.level + 1;

您能否扩展“但插入中的确切问题并未导致更新”?
@pojo-guy - 我认为您没有看到 MrR 的问题 - 您能否扩展“但插入中的确切问题并未导致更新”?
当您尝试在 postgresql 中使用 insert ... on update 时,在某些特定情况下结果与合并不同。我遇到的案例相当模糊和具体,但它是可以重复的。已经几个月了,所以我现在不能再给了。
也许这不是冲突,而是另一个错误,例如字段类型错误?