文章目录
场景
新增数据时提示:
nested exception is java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (UUU.SYS_C0019999_01) violated
问题排查
看了下 UUU.SYS_C0019999_01 是 id,对应某个序列。
报这个错,通常是序列的当前值和id不对应了。
例如:正常来说,id是根据序列产生的,但是如果手动增量维护了id,那么实际id可能大于序列中的id,就会报这个错了。
解决方案
方案一 重建序列,设置初始值。(略)
方案二 手动调整初始值。
原理就是先根据 初始值和期待值,计算差值,然后调节步长。再触发下nextVal,这样会刷新初始值,然后再恢复步长即可。
例如:
初始值 2112
期待值 2124
那么差值是 2124-2112=12
修改步长为12:
Alter Sequence T_SEQUENCE Increment By 12;
触发nextVal,初始值变为2124:
Select T_SEQUENCE.NextVal From Dual;
恢复步长为1:
Alter Sequence T_SEQUENCE Increment By 1;
以上是比较精确步长,还有一种简单粗暴,适配性比较强的办法,就是步长调的特别大(如5千万),nextval一次,让库里的数据都追不上,这样在seq比较多的时候,就不用逐个计算了。
自动修改sequence的尝试
手动的会了,想让它自动化,结果碰壁了。
SELECT 序列名.currval FROM dual a
minus
SELECT max(to_number(id)) FROM 表名;
报错:ORA-02287: 此处不允许序号 # 关于这个报错详见其他博客
这里简单说下,是sequence.nextval不能用在minus等语法里(也不能union)。
如果通过设置参数是可以的,但是涉及到存储过程,稍微麻烦,所以先不弄了。
半自动修改sequence
模板化查询:
SELECT '表名 的最大id=' || max(to_number(id)) FROM 表名;
SELECT '序列名 的当前值=' || 序列名.currval FROM dual;
然后将要调整的sequence也先写好,一起操作即可。
懒人写法
懒一点也可以不计算到底是多少,直接弄个很大的步长,例如300000000,那么一般来说都够了。
报错 SQLIntegrityConstraintViolationException: ORA-00001: unique constraint
详细信息:
SQLIntegrityConstraintViolationException: ORA-00001: unique constraint
就是seq值不对的问题。