Postgres 9.5+: UPSERT to return the count of updated and inserted rows

荒凉一梦 提交于 2019-12-20 18:09:32

问题


I get the canonical example:

 INSERT INTO user_logins (username, logins)
 VALUES ('Naomi',1),('James',1)
 ON CONFLICT (username)
 DO UPDATE SET logins = user_logins.logins + EXCLUDED.logins;

But now I also need to know:

  1. How many rows were inserted
  2. How many rows were updated because existing
  3. How many rows could not be inserted because of constraints
  4. If the constraint is not respected for the last row, will the previous inserted/updated rows be persisted in the DB?

回答1:


I do not know how else you can understand what event occurred. You should look at the value of xmax, if xmax = 0 means there row was inserted, other value xmax there row was update.

I have bad English and I will try to show the example.

create table test3(r1 text unique, r2 text);
\d+ test3
                       Table "public.test3"
 Column | Type | Modifiers | Storage  | Stats target | Description 
--------+------+-----------+----------+--------------+-------------
 r1     | text |           | extended |              | 
 r2     | text |           | extended |              | 
Indexes:
    "test3_r1_key" UNIQUE CONSTRAINT, btree (r1)

INSERT

INSERT INTO test3 
VALUES('www7','rrr'), ('www8','rrr2') 
ON CONFLICT (r1) DO UPDATE SET r2 = 'QQQQ' RETURNING xmax;
 xmax 
------
    0
    0

If you try to insert a duplicate:

INSERT INTO test3 
VALUES('www7','rrr'), ('www8','rrr2') 
ON CONFLICT (r1) DO UPDATE SET r2 = 'QQQQ' RETURNING xmax;
   xmax    
-----------
 430343538
 430343538
(2 rows)

INSERT 0 2

The result can be processed in such a way:
Inserting 1 new and 1 duplicate rows

WITH t AS  (
  INSERT INTO test3 
  VALUES('www9','rrr'), ('www7','rrr2') 
  ON CONFLICT (r1) DO UPDATE SET r2 = 'QQQQ' RETURNING xmax
) 
SELECT COUNT(*) AS all_rows, 
       SUM(CASE WHEN xmax = 0 THEN 1 ELSE 0 END) AS ins, 
       SUM(CASE WHEN xmax::text::int > 0 THEN 1 ELSE 0 END) AS upd 
FROM t;

all_rows  | ins | upd 
----------+-----+-----
        2 |   1 |   1

see 5.4. System Columns and MVCC

Very interesting how can solve the problem more gracefully



来源:https://stackoverflow.com/questions/38851217/postgres-9-5-upsert-to-return-the-count-of-updated-and-inserted-rows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!