【问题标题】:Postgres 9.5+: UPSERT to return the count of updated and inserted rowsPostgres 9.5+:UPSERT 返回更新和插入行的计数
【发布时间】:2016-08-09 12:48:30
【问题描述】:

我得到了典型的例子:

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

但现在我也需要知道:

  1. 插入了多少行
  2. 有多少行因为存在而被更新
  3. 由于限制而无法插入多少行
  4. 如果最后一行不遵守约束,之前插入/更新的行是否会保留在数据库中?

【问题讨论】:

    标签: postgresql upsert


    【解决方案1】:

    我不知道您还能如何理解发生了什么事件。 你应该看看xmax的值,如果xmax = 0意味着有行被插入,其他值xmax有行被更新。

    我的英语不好,我会试着展示这个例子。

    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 INTO test3 
    VALUES('www7','rrr'), ('www8','rrr2') 
    ON CONFLICT (r1) DO UPDATE SET r2 = 'QQQQ' RETURNING xmax;
     xmax 
    ------
        0
        0
    

    如果您尝试插入重复项:

    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
    

    结果可以这样处理:
    插入 1 个新行和 1 个重复行

    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
    

    5.4. System Columns MVCC

    非常有趣如何更优雅地解决问题

    【讨论】:

    • 演员::text::int有什么意义?
    猜你喜欢
    • 2016-10-01
    • 2016-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-07
    • 2022-01-06
    • 2016-04-18
    • 2017-07-30
    相关资源
    最近更新 更多