暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MogDB INSERT支持ON CONFLICT子句

原创 MogDB 2024-08-06
203

可获得性

本特性自MogDB 5.0.6版本开始引入。

特性简介

MogDB支持INSERT ON CONFLICT DO UPDATE/DO NOTHING语法及其功能,ON CONFLICT子句指定引发唯一约束冲突时,执行ON CONFLICT后面的语句,将INSERT行为变更为UPDATE或DO NOTHING以避免报错。

客户价值

兼容PostgreSQL 9.5新增语法,减少应用程序的迁移代价。

语法说明

INSERT新增ON CONFLICT子句:

[ WITH [ RECURSIVE ] with_query [, ...] ] INSERT INTO table_name [ AS alias ] [ ( column_name [, ...] ) ] [ ON CONFLICT [conflict_target] DO { NOTHING | { UPDATE SET column_name = { expression | DEFAULT } } [, ...] [ WHERE condition ] } ]

其中conflict_target可以是以下之一:

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

可选的ON CONFLICT子句提供了一种处理插入冲突的方法,主要用于解决唯一约束或者主键约束导致的插入失败问题。当尝试插入一行数据时,如果唯一约束或主键约束已经存在相同值的数据,ON CONFLICT子句可以指定在发生冲突时的行为,例如执行更新操作而不是插入新数据,或者忽略冲突而不进行任何操作。

  • conflict_target

    通过选择索引,指定ON CONFLICT对哪些冲突采取替代操作。要么执行唯一索引推断,要么显式命名一个约束。对于ON CONFLICT DO NOTHING来说,conflict_target是可选的。在被省略时,与所有有效约束(以及唯一索引)的冲突都会被处理。对于ON CONFLICT DO UPDATE,必须提供conflict_target

  • index_column_name

    索引列名。

  • index_expression

    index_column_name类似,但用于索引中出现的列(而不是简单列)的表达式。

  • collation

    当指定时,要求相应的index_column_nameindex_expression使用特定的排序规则(collation)才能匹配。通常情况下会被省略,因为排序规则通常不会影响是否违反约束。

  • opclass

    当指定时,要求相应的index_column_nameindex_expression使用特定的运算符类(operator class)才能匹配。通常情况下会被省略。

  • index_predicate

    用于允许推断部分唯一索引。任何满足该谓词(不一定需要是部分索引)的索引都能被推断。

  • constraint_name

    用名称显式指定一个仲裁者约束, 而不是推断约束或者索引。

  • condition

    返回布尔类型值的表达式,只有该表达式返回true的记录才会被更新。

特性约束

  • 目标表不支持外部表
  • 目标表不支持视图,与PostgreSQL行为不一致
  • INSERT中存在查询语句时不支持SQL Bypass
  • 不支持列存表
  • 适用于A和PG兼容模式
  • 对PG有兼容性要求的场景需要关闭allow_concurrent_tuple_update参数
  • 对PG有兼容性要求的场景需要设置lockwait_timeout = 0

示例

drop index if exists i_upsert; drop table if exists t_upsert cascade; -- 创建普通表并插入数据 CREATE TABLE t_upsert( id int , name text, price numeric ); insert into t_upsert select generate_series,'test' || generate_series,generate_series*10 from generate_series(1,10); select * from t_upsert order by 1 limit 10; --创建索引 create unique index i_upsert on t_upsert(id); select a.relname,b.indnatts,b.indisusable,b.indisunique,b.indisprimary from pg_class a,pg_index b where a.oid = b.indexrelid and b.indrelid = (select oid from pg_class where relname = 't_upsert') order by 1; --插入重复值,insert on conflict语句中的conflict_target是索引列名 insert into t_upsert values(3,'gram',5.5) on conflict(id) do update set name='gram'; select * from t_upsert order by 1; --清除数据 drop index if exists i_upsert; drop table if exists t_upsert cascade;

相关页面

INSERT

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论