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

时间:2016-03-02 20:07:58

标签: postgresql-9.5

我希望能够告诉执行INSERT后发生了哪个操作(UPDATEINSERT .. ON CONFLICT)。也许作为子查询作为RETURNING子句的一部分?

似乎有一个similar request about a month ago,Peter Geoghegan回应说,有可能是某种黑客攻击。如果有人有任何想法,我很乐意现在就听到它。

3 个答案:

答案 0 :(得分:1)

我使用了以下伪代码。我在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,如果更新则为NULL)
  4. UPDATE ...(我想在第2步中对冲突做些什么)
  5. 基本上总是执行更新,破坏新UPSERT功能的目的,但到目前为止似乎没有官方方式。

答案 1 :(得分:0)

我正在使用以下方法:

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

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

答案 2 :(得分:0)

将列添加到表中以确定。例如。“ I”表示插入,“ U”表示要使用更新。

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;

如果operation为INSERT,则lastoperation的值为'I',否则为'U'。您可以使用lastoperation列的值。