解决 PostgreSQL 检查约束导致的数据插入异常问题
解决 PostgreSQL 检查约束引发的数据插入问题
一、问题描述
在将产品规格相关数据插入到 erp_product_specification
表时,程序抛出了异常。从日志中可以清晰地看到错误信息:
org.springframework.dao.DataIntegrityViolationException:
### Error updating database. Cause: org.postgresql.util.PSQLException: ERROR: new row for relation "erp_product_specification" violates check constraint "erp_product_specification_applicable_product_type_check"
详细: Failing row contains (1915232443175804930, 袋装, reagent, 1, 1, 1, 2025-04-24 10:32:52.408734, 1, 2025-04-24 10:32:52.408734, 0, 0).
### The error may exist in cn/iocoder/module/erp/dal/mysql/productspecification/ProductSpecificationMapper.java (best guess)
### The error may involve cn.iocoder.module.erp.dal.mysql.productspecification.ProductSpecificationMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO erp_product_specification (spec_id, spec_name, applicable_product_type, spec_type, remark, create_time, update_time, creator, updater ) VALUES (?,?,?,?,?,?,?,?,? )
### Cause: org.postgresql.util.PSQLException: ERROR: new row for relation "erp_product_specification" violates check constraint "erp_product_specification_applicable_product_type_check"
详细: Failing row contains (1915232443175804930, 袋装, reagent, 1, 1, 1, 2025-04-24 10:32:52.408734, 1, 2025-04-24 10:32:52.408734, 0, 0).
; ERROR: new row for relation "erp_product_specification" violates check constraint "erp_product_specification_applicable_product_type_check"
详细: Failing row contains (1915232443175804930, 袋装, reagent, 1, 1, 1, 2025-04-24 10:32:52.408734, 1, 2025-04-24 10:32:52.408734, 0, 0).
经进一步查看,发现该检查约束的定义为:
CHECK (((applicable_product_type)::text = ANY ((ARRAY['试剂'::character varying, '耗材'::character varying])::text[])))
这意味着 applicable_product_type
列的值只能是 '试剂'
或者 '耗材'
。而我们在将输入框由字典选择改为手动输入后,可能输入了其他值,从而触发了约束异常。
二、问题排查
1. 确认约束定义
通过以下 SQL 语句查询约束的具体定义:
SELECT pg_get_constraintdef(oid)
FROM pg_constraint
WHERE conname = 'erp_product_specification_applicable_product_type_check';
确认了约束确实是限制 applicable_product_type
列取值范围的。
2. 分析业务需求变化
由于之前是字典选择,数据输入范围可控,符合约束条件。但改为手动输入后,没有及时调整约束或者在应用层添加相应验证,导致不符合约束条件的数据尝试插入。
三、解决方法
1. 删除检查约束(谨慎操作)
如果当前业务逻辑允许 applicable_product_type
列输入任意值,那么可以删除该检查约束。使用如下 SQL 语句:
ALTER TABLE erp_product_specification
DROP CONSTRAINT erp_product_specification_applicable_product_type_check;
在执行此操作前,务必备份相关表数据,因为删除约束后可能会导致不符合原始业务规则的数据进入数据库,影响数据完整性。
2. 应用层数据验证(推荐)
为了保证数据在满足新业务需求(手动输入)的同时,依然符合一定规则,可在应用层添加数据验证逻辑。例如在 Java 项目中,可以在接收用户输入的 Controller 层或者 Service 层对 applicable_product_type
的值进行判断,只允许符合业务要求的值进入后续的数据库操作流程。