PostgreSQL merge insert(insert into on conflict) ERRCODE_CARDINALITY_VIOLATION (Ensure that no rows proposed for insertion within the same command hav

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
简介:

标签

PostgreSQL , insert into on conflict , merge insert


背景

使用insert into on conflict 合并插入,如果一条SQL语句中,对一个KEY(冲突键,或冲突约束)多次发生冲突时,会报错。

原因:

                         * It is the user's responsibility to prevent this situation from  
                         * occurring.  These problems are why SQL-2003 similarly specifies  
                         * that for SQL MERGE, an exception must be raised in the event of  
                         * an attempt to update the same row twice.  

因为在SQL标准中,sql merge也有同样的问题,因为一次请求中对行的处理,顺序是不固定的。数据库不知道应该以哪条为最后需要保留的。

例子

postgres=# \set VERBOSITY verbose  
  
postgres=# insert into t_conf select * from (values (1,'test'), (1,'test1')) t(id,info) on conflict(id) do update set info=excluded.info;  
ERROR:  21000: ON CONFLICT DO UPDATE command cannot affect row a second time  
HINT:  Ensure that no rows proposed for insertion within the same command have duplicate constrained values.  
LOCATION:  ExecOnConflictUpdate, nodeModifyTable.c:1259  
  
postgres=# insert into t_conf values (1,'test'), (1,'test1') on conflict(id) do update set info=excluded.info;  
ERROR:  21000: ON CONFLICT DO UPDATE command cannot affect row a second time  
HINT:  Ensure that no rows proposed for insertion within the same command have duplicate constrained values.  
LOCATION:  ExecOnConflictUpdate, nodeModifyTable.c:1259  

报错代码

src/backend/executor/nodeModifyTable.c

/*  
 * ExecOnConflictUpdate --- execute UPDATE of INSERT ON CONFLICT DO UPDATE  
 *  
 * Try to lock tuple for update as part of speculative insertion.  If  
 * a qual originating from ON CONFLICT DO UPDATE is satisfied, update  
 * (but still lock row, even though it may not satisfy estate's  
 * snapshot).  
 *  
 * Returns true if if we're done (with or without an update), or false if  
 * the caller must retry the INSERT from scratch.  
 */  
static bool  
ExecOnConflictUpdate(ModifyTableState *mtstate,  
                                         ResultRelInfo *resultRelInfo,  
                                         ItemPointer conflictTid,  
                                         TupleTableSlot *planSlot,  
                                         TupleTableSlot *excludedSlot,  
                                         EState *estate,  
                                         bool canSetTag,  
                                         TupleTableSlot **returning)  
{  
.....................  
                case HeapTupleInvisible:  
  
                        /*  
                         * This can occur when a just inserted tuple is updated again in  
                         * the same command. E.g. because multiple rows with the same  
                         * conflicting key values are inserted.  
                         *  
                         * This is somewhat similar to the ExecUpdate()  
                         * HeapTupleSelfUpdated case.  We do not want to proceed because  
                         * it would lead to the same row being updated a second time in  
                         * some unspecified order, and in contrast to plain UPDATEs  
                         * there's no historical behavior to break.  
                         *  
                         * It is the user's responsibility to prevent this situation from  
                         * occurring.  These problems are why SQL-2003 similarly specifies  
                         * that for SQL MERGE, an exception must be raised in the event of  
                         * an attempt to update the same row twice.  
                         */  
                        if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple.t_data)))  
                                ereport(ERROR,  
                                                (errcode(ERRCODE_CARDINALITY_VIOLATION),  
                                                 errmsg("ON CONFLICT DO UPDATE command cannot affect row a second time"),  
                                                 errhint("Ensure that no rows proposed for insertion within the same command have duplicate constrained values.")));  
  
                        /* This shouldn't happen */  
                        elog(ERROR, "attempted to lock invisible tuple");  

PostgreSQL 不处理这种错误,应该让用户自己来保障,不会在同一条SQL中出现多条同一个KEY的TUPLE。

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
6月前
|
SQL Oracle 关系型数据库
实时计算 Flink版操作报错之往GREENPLUM 6 写数据,用postgresql-42.2.9.jar 报 ON CONFLICT (uuid) DO UPDATE SET 语法有问题。怎么解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
关系型数据库 PostgreSQL
postgresql insert into插入记录时使用select子查询
postgresql insert into插入记录时使用select子查询
125 0
|
关系型数据库 PostgreSQL
PostgreSQL INSERT INTO 语句
PostgreSQL INSERT INTO 语句
361 0
|
SQL 弹性计算 关系型数据库
PostgreSQL 大宽表,全列索引,高并发合并写入(insert into on conflict, upsert, merge insert) - 实时adhoc query
标签 PostgreSQL , 全列索引 , 大宽表 , 写测试 , insert on conflict , upsert , merge insert , adhoc query 背景 OLAP系统中,adhoc query非常场景(任意维度查询分析)。 adhoc query,通常来说,可以加GIN倒排,或者每一列都加一个索引来实现。 《PostgreSQL 设计优化case
8627 0
|
弹性计算 关系型数据库 测试技术
PostgreSQL 分区表如何支持多列唯一约束 - 枚举、hash哈希 分区, 多列唯一, insert into on conflict, update, upsert, merge insert
标签 PostgreSQL , 分区表 , native partition , 唯一 , 非分区键唯一 , 组合唯一 , insert into on conflict , upsert , merge insert 背景 PG 11开始支持HASH分区,10的分区如果要支持hash分区,可以通过枚举绕道实现。 《PostgreSQL 9.x, 10, 11 hash分区表 用法举例
3104 0
|
关系型数据库 分布式数据库 PolarDB
《阿里云产品手册2022-2023 版》——PolarDB for PostgreSQL
《阿里云产品手册2022-2023 版》——PolarDB for PostgreSQL
359 0
|
存储 缓存 关系型数据库
|
存储 SQL 并行计算
PolarDB for PostgreSQL 开源必读手册-开源PolarDB for PostgreSQL架构介绍(中)
PolarDB for PostgreSQL 开源必读手册-开源PolarDB for PostgreSQL架构介绍
413 0
|
存储 算法 安全
PolarDB for PostgreSQL 开源必读手册-开源PolarDB for PostgreSQL架构介绍(下)
PolarDB for PostgreSQL 开源必读手册-开源PolarDB for PostgreSQL架构介绍
376 0
|
关系型数据库 分布式数据库 开发工具

相关产品

  • 云原生数据库 PolarDB