概述
问题描述
首先是在开发需求迭代时,发现数据库某个非空字段需要修改成非必填类型。然后就一顿操作猛如虎(就是数据库直接把必输选项的对号取消了),测试环境一顿测试没问题,好了到了预生产环境,一开始就一片片报错:现实惨不忍睹,一片片啊。
Cause: java.sql.SQLIntegrityConstraintViolationException: ORA-02290: check constraint (TEST.SYS_C0016848) violated; ];
ORA-02290: check constraint (TEST.SYS_C0016848) violated
; nested exception is java.sql.SQLIntegrityConstraintViolationException: ORA-02290: check constraint (TEST.SYS_C0016848) violated
问题分析
由报错信息发现时某个字段不能为空被Oracle的检查校验拦住了,然后把所有的sql都打印出来单独执行还是报错。于是开始看这个检查校验具体是指的什么:select * from user_constraints where table_name='ONE_TEST', 发现报错的是TEST_ID字段不能为空,但是数据库是这样的:
检查校验的表里面有两条TEST_ID IS NOT NULL的校验,当我取消勾选的时候 SYS_C0016851这个校验没了,但是16848还在,就像现在的环境中的报错。于是就有了一个质疑的地方是不是和建表语句有关。其实现在呢你把报错的检查校验删除掉问题就解决了。下面是验证自己的猜想。
问题复现
首先我在测试环境建一个表ONE_TEST如下图所示:
CREATE TABLE "TESTTZ"."ONE_TEST" (
"ID" NUMBER NOT NULL ,
"INTERNAL_ID" VARCHAR2(40 BYTE) NOT NULL ,
"TEST_ID" VARCHAR2(40 BYTE) NOT NULL
)
ALTER TABLE "TESTTZ"."ONE_TEST" ADD CONSTRAINT "SYS_C0013346" PRIMARY KEY ("ID");
然后关键问题来了,导出建表语句如下所示,发现最后三行就是检查校验的内容,在把这个sql放到预生产环境执行后,查询相应的检查校验规则问题展现:
CREATE TABLE "TESTTZ"."ONE_TEST" (
"ID" NUMBER NOT NULL ,
"INTERNAL_ID" VARCHAR2(40 BYTE) NOT NULL ,
"TEST_ID" VARCHAR2(40 BYTE) NOT NULL
)
TABLESPACE "USERS"
LOGGING
NOCOMPRESS
PCTFREE 10
INITRANS 1
STORAGE (
INITIAL 65536
NEXT 1048576
MINEXTENTS 1
MAXEXTENTS 2147483645
BUFFER_POOL DEFAULT
)
PARALLEL 1
NOCACHE
DISABLE ROW MOVEMENT
;
-- ----------------------------
-- Checks structure for table ONE_TEST
-- ----------------------------
ALTER TABLE "TESTTZ"."ONE_TEST" ADD CONSTRAINT "SYS_C0016846" CHECK ("ID" IS NOT NULL) NOT DEFERRABLE INITIALLY IMMEDIATE NORELY VALIDATE;
ALTER TABLE "TESTTZ"."ONE_TEST" ADD CONSTRAINT "SYS_C0016847" CHECK ("INTERNAL_ID" IS NOT NULL) NOT DEFERRABLE INITIALLY IMMEDIATE NORELY VALIDATE;
ALTER TABLE "TESTTZ"."ONE_TEST" ADD CONSTRAINT "SYS_C0016848" CHECK ("TEST_ID" IS NOT NULL) NOT DEFERRABLE INITIALLY IMMEDIATE NORELY VALIDATE;
每次执行建表语句会根据create 里面的参数类型的 not null创建新的检查校验规则到 user_constraints 里面,但是当我们直接把测试环境的建表语句导入到预生产环境的时候,预生产环境生成了新的检查校验规则,同时也把测试环境的检查校验规则插入到预生产环境的规则表里。再我们根据业务需要取消某个字段的非空选项时,仅仅取消了预生产环境新生成的检查校验规则,而测试环境的检查校验规则还存在,当插入字段为空时,就会报错。解决方案查出这个表所有的检查校验规则,ALTER TABLE TABLENAME DROP CONSTRAINT SYS_C0069731,删除即可。
如有披露或问题欢迎留言或者入群探讨
最后
以上就是热情云朵为你收集整理的ORACLE数据库之ORA-02290检查校验问题解析的全部内容,希望文章能够帮你解决ORACLE数据库之ORA-02290检查校验问题解析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复