如何确定 UPSERT 操作与 INSERT .. ON CONFLICT?

How to determine UPSERT operation with INSERT .. ON CONFLICT?

我想知道在执行 INSERT .. ON CONFLICT 之后发生了哪个操作(INSERTUPDATE)。也许作为子查询作为 RETURNING 子句的一部分?

似乎有一个 similar request about a month ago 并且 Peter Geoghegan 回应说,通过某种破解可能是可能的。如果有人有任何想法,我很想现在就听听。

我使用了以下伪代码。我在 plpgsql 函数中,所以我可以使用变量。但我认为我也可以将其包装成 CTE。

  1. DECLARE var INT;
  2. INSERT .. ON CONFLICT DO NOTHING RETURNING 1 INTO var;
  3. PERFORM ... WHERE var IS NOT NULL;(如果 INSERT 则 var 为 1,如果 update 则为 NULL)
  4. UPDATE ...(我想在第 2 步中解决冲突)

基本上总是执行更新,违背了新的UPSERT功能的目的,但目前似乎还没有正式的方法。

我正在使用以下方法:

insert into users (created_at, updated_at, email)
values (now(), now(), 'user@example.com')
on conflict (email) 
do update set updated_at = now()
returning users.*, (created_at = updated_at) as new_user_created

insert后new_user_created为true,update后为false。 我不确定它将如何在首先创建用户然后更新用户的事务中工作 - 可能现在()将 return 每次调用中的值完全相同。

将列添加到您的 table 以确定。例如.. 'I' 表示插入,'U' menas 更新使用。

ALTER TABLE foo ADD COLUMN lastoperation text;

INSERT INTO foo (c1,c2,...,lastoperation) values (?,?,.... 'I') ON CONFLICT (<your ndx or keys>) DO UPDATE SET lastoperation='U' returning lastoperation;

如果操作是 INSERT ,最后一个操作值将是 'I',否则 'U'。您可以使用 lastoperation 列值..