KingbaseES Insert On Conflict 功能

针对数据写入时有主键冲突的情况,INSERT ON CONFLICT语法可以将冲突主键的INSERT行为转换为UPDATE行为,从而实现冲突主键的覆盖写入。该特性又称UPSERT覆盖写,与MySQL的REPLACE INTO类似。

语法

[ WITH [ RECURSIVE ] with_query [, ...] ]
INSERT INTO table_name [ [ AS ] alias ] [ ( column_name [, ...] ) ]
    [ OVERRIDING { SYSTEM | USER} VALUE ]
    { DEFAULT VALUES |
      VALUES ( { expression | DEFAULT } [, ...] ) [, ...] |
      query |
      VALUES record |
      SET { column_name = { expression | DEFAULT } |
            ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |
            ( column_name [, ...] ) = ( sub-SELECT )
          } [, ...]
    }
    [ ON CONFLICT [ conflict_target ] conflict_action ]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

其中 conflict_target 可以是以下之一:

    ( { index_column_name | ( index_expression ) } [ COLLATE collation ]
    [ opclass ]
    [, ...] ) [ WHERE index_predicate ]
    ON CONSTRAINT constraint_name

并且 conflict_action 是以下之一:

    DO NOTHING
    DO UPDATE SET { column_name = { expression | DEFAULT } |
                    ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT }
                    [, ...] ) |
                    ( column_name [, ...] ) = ( sub-SELECT )
                  } [, ...]
              [ WHERE condition ]

ON CONFLICT子句可以实现覆盖写入。该子句由conflict_target和conflict_action组成。

参数说明
conflict_targetconflict_action取值为Do Update时,conflict_target需要指定用来定义冲突的主键列或唯一索引列
conflict_action取值为Do Nothing时,conflict_target可省略
conflict_actionDO NOTHING:如果conflict_target指定的列有冲突,则丢弃待插入的数据
DO UPDATE:如果conflict_target指定的列有冲突,则按照后面的UPDATE子句进行数据覆盖

示例

CREATE TABLE  user_logins (
	user_id int PRIMARY KEY,
	login_cnt int,
	last_login_time date
); --记录用户登录信息的表

test=# insert into user_logins values (1,1,sysdate);
INSERT 0 1

test=# insert into user_logins values (1,2,sysdate);  --插入主键重复的数据报错
错误:  重复键违反唯一约束"user_logins_pkey"
描述:  键值"(user_id)=(1)" 已经存在

冲突时做更新操作:
test=# INSERT INTO user_logins VALUES 
test-# (1,2,sysdate),(2,1,sysdate)
test-# ON conflict(user_id)
test-# DO UPDATE SET login_cnt = user_logins.login_cnt + EXCLUDED.login_cnt;
INSERT 0 2
test=# select * from user_logins;
 user_id | login_cnt |   last_login_time   
---------+-----------+---------------------
       1 |         3 | 2022-10-14 15:02:45
       2 |         1 | 2022-10-14 15:06:47
(2 行记录)

user_logins.login_cnt 原表中的值
EXCLUDED.login_cnt insert语句中的值

冲突时不做处理:
test=# INSERT INTO user_logins VALUES 
test-# (1,2,sysdate),(3,1,sysdate)
test-# ON conflict(user_id)
test-# DO NOTHING;
INSERT 0 1
test=# select * from user_logins;
 user_id | login_cnt |   last_login_time   
---------+-----------+---------------------
       1 |         3 | 2022-10-14 15:02:45
       2 |         1 | 2022-10-14 15:06:47
       3 |         1 | 2022-10-14 15:09:52
(3 行记录)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值