ECPG PostgreSQL中重复键错误(ECPG_DUPLICATE_KEY)处理异常问题
解决ECPG插入PostgreSQL主键重复时跳过记录且不中止事务的问题
问题本质
PostgreSQL事务中发生错误(比如主键重复)后,整个事务会进入aborted状态,后续所有DML命令都会被拒绝,直到执行回滚操作,这就是你遇到25P02错误的原因。
解决方案
方案1:利用保存点实现局部回滚
在每条插入操作前设置保存点,捕获到主键重复错误时,回滚到该保存点而非全局回滚,这样事务能恢复可用状态,继续执行后续操作。
示例代码:
// 为单条插入设置保存点 EXEC SQL SAVEPOINT insert_sp; // 执行插入操作 EXEC SQL INSERT INTO target_table (id, col1, col2) VALUES (:id_val, :col1_val, :col2_val); // 判断错误类型 if (sqlca.sqlcode == ECPG_DUPLICATE_KEY || sqlca.sqlcode == -403) { Log_error_tab(); // 执行你的错误记录逻辑 // 回滚到保存点,恢复事务状态 EXEC SQL ROLLBACK TO SAVEPOINT insert_sp; } else if (sqlca.sqlcode != 0) { // 处理其他严重错误,比如全局回滚并终止任务 EXEC SQL ROLLBACK; // 其他错误处理逻辑 }
方案2:使用PostgreSQL原生冲突跳过语法
直接用INSERT ... ON CONFLICT DO NOTHING语法,主键重复时会自动跳过插入,不会触发错误,事务也不会进入aborted状态,代码更简洁高效。
示例代码:
EXEC SQL INSERT INTO target_table (id, col1, col2) VALUES (:id_val, :col1_val, :col2_val) ON CONFLICT (id) DO NOTHING;
方案对比
- 保存点方案:适合需要明确捕获并记录重复错误的场景,能追踪到具体哪条记录插入失败。
ON CONFLICT DO NOTHING方案:无需手动处理错误和事务状态,性能更优,适合只需要跳过重复记录的场景。
内容的提问来源于stack exchange,提问作者Munu
相关产品推荐
相关产品推荐

