博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
无法运行的update问题解析
阅读量:2445 次
发布时间:2019-05-10

本文共 3048 字,大约阅读时间需要 10 分钟。

今天有个同事向我反馈一个问题,说是客户在部署他们提供的一个sql语句时,报了ora错误,想让我帮忙看看是什么原因。
update sub_errs set error_status = 'READY_TO_RECYCLE' WHERE sub_appl_id = 3008 AND ENTITY_ID = 8336079 AND MASTER_TRX_ID = 202809364 and error_status = 'PENDING_DEPENDENCY' 
Error report - 
SQL Error: ORA-02290: ????????????????????????????? (APPO.SUB_ERRS_1CK) 
首先看错误,还真接上小语种了,自己百度翻译了下,是违反约束条件的意思,也是开个玩笑,这个问题可以通过oerr来查看oracle的解释。
02290, 00000, "check constraint (%s.%s) violated"
// *Cause: The values being inserted do not satisfy the named check 
//      constraint.
// *Action: do not insert values that violate the constraint.
可以看出应该是约束的地方出问题了,从约束的命名来看是以CK结尾,即check constraint。
查看user_constraints中的search_condition字段,条件着实复杂,search_condition的条件如下:
(depen_ind='S' AND error_status='PENDING_DEPENDENCY')
OR (depen_ind='S' AND error_status='COMPLETED')
OR (depen_ind='S' AND error_status='PURGED')
OR depen_ind='B'
OR depen_ind='N'
即对于指定的字段 error_status  需要满足上面的这些条件。这个check constraint算是一个比较复杂的约束了。
可能有些人看这个约束就有点晕,到底是希望满足条件还是不满足条件啊。
我们可以类比一下,如果是not null constraint,可能约束就是类似 xxxx is not null的形式,这个时候是希望这个字段不为空的,即满足条件。所以这个问题是希望对 error_status  ,满足上面的条件才行。
给同事解释了一通,让他去看看是不是现有环境中存在数据问题,是不是因为数据问题导致条件不满足的。
结果过了一会同事又过来向我确认,说按照那个条件查出的结果和原有的一致的。都是19条数据。
因为表中的数据很多,所以为了尽快复现这个问题,自己采用了exp的query选项导出数据,
这样就会只导出19条数据,数据量就小多了,导入到一个测试环境中,就可以大胆的测试了。
exp xxxxx/xxx  file=a.dmp tables=sub_errs query=\" where  sub_appl_id = 3008 AND ENTITY_ID = 8336079 \"
我先根据id来抽取数据,抽取出19条数据来,然后在测试用户中使用对应的约束进行修改,看看问题是否会复现。
导入数据很顺利,19条数据很快就导入了。
imp xxxxx/xxxx    file=a.dmp tables= sub_errs indexes=n grants=n ignore=Y constraints=n buffer=9102000 
这个时候尝试重现,发现问题依旧。
这个时候我们把问题拆分一下,先把update改写成为select语句。数据条数是19条。
select count(*) from sub_errs WHERE sub_appl_id = 3008 AND ENTITY_ID = 8336079 AND MASTER_TRX_ID = 202809364 and error_status = 'PENDING_DEPENDENCY' 
and
((depen_ind='S' AND error_status='PENDING_DEPENDENCY')
OR (depen_ind='S' AND error_status='COMPLETED')
OR (depen_ind='S' AND error_status='PURGED')
OR depen_ind='B'
OR depen_ind='N')
这个时候其实约束的验证条件进行校验 error_status和depen_ind这两个字段,因为现有的数据中depen_ind已经是S了,所以数据上没有问题。
然后我们进一步分析。update会把error_status修改为'READY_TO_RECYCLE',这个时候细看过滤条件中,是没有符合的error_status校验的,这个时候depen_ind还是S,就会出问题,
因为这个时候从depen_ind+error_status还是单纯考虑depen_ind都是有问题的,和验证条件是有冲突的。
这个时候因为error_status是READY_TO_RECYCLE',所以第1,2两个条件不会起作用,考虑第3,4个条件,就会发现没有匹配的情况。难怪会抛错。
((depen_ind='S' AND error_status='PENDING_DEPENDENCY')
OR (depen_ind='S' AND error_status='COMPLETED')
OR (depen_ind='S' AND error_status='PURGED')
OR depen_ind='B'
OR depen_ind='N')
明白了这点之后,就提醒同事,脚本应该存在问题,也修改同时修改depen_ind字段的值,需要修改为B或者N,这个由他们来做进一步的确认了。
最后修改后的语句为:
update sub_errs set error_status = 'READY_TO_RECYCLE',depen_ind='N'  WHERE sub_appl_id = 3008 AND ENTITY_ID = 8336079 AND MASTER_TRX_ID = 202809364 and error_status = 'PENDING_DEPENDENCY' 
这个问题的解决就告一段落了。
这个案例带给我的启示就是看似是约束导致的问题,一般运维人员可能会直接认为是数据问题把问题直接退给开发人员,其实从开发人员的角度来说,去进一步排查这个问题就会显得很困难,不知道该从何开始。
其实问题最后的原因就是语句的修改不够规范和全面导致约束的校验失败,发现这个问题的过程还是需要一些耐心的。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23718752/viewspace-1686924/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/23718752/viewspace-1686924/

你可能感兴趣的文章
SQL Server中的报表–结合T-SQL和DAX查询以生成有效的报表
查看>>
ssis 数据转换_SSIS数据类型:高级编辑器的更改与数据转换的转换
查看>>
sql创建表主键gui_在SQL Server中使用主数据服务快速创建最终用户可以维护的GUI
查看>>
sql server 加密_SQL Server机密–第一部分–加密基础知识和SQL Server加密功能
查看>>
使用SQL Server Reporting Services基于现有存储过程创建报告
查看>>
sql azure 语法_Azure SQL数据同步–在Azure SQL数据库之间复制数据和架构更改
查看>>
SQL FILESTREAM与数据库快照,镜像,TDE和日志传送的兼容性
查看>>
ssis导出数据性能_如何使用SSIS将数据从Excel导出到Azure SQL数据库中的多个表
查看>>
使用PowerShell和SQL的示例可用性监视服务的插图
查看>>
使用Team Foundation Server在SQL数据库中的对象更改的修订历史记录
查看>>
sql server 锁定_如何使用SQL Server 2014托管锁定优先级控制在线索引重建锁定
查看>>
sql多语句表值函数_构造一个特殊的多语句表函数来检查SQL Server的运行状况
查看>>
如何将链接的服务器从SQL Server“调试”到Oracle数据库实例
查看>>
mercurial使用_DBA对Mercurial的介绍–什么时候以及为什么我们应该使用版本控制
查看>>
azure 免费帐户注册_如何使用模拟器模拟Azure SQL数据库存储帐户行为
查看>>
sql azure 语法_使用Azure门户监视安装了SQL Server的Azure计算机
查看>>
azure 入门_Azure Data Studio(ADS)入门; 初始安装和配置
查看>>
sql server 复制_SQL Server复制(合并)–复制架构更改中的性能问题
查看>>
SQL Server安全机制–如何控制用户能够在报告中查看哪些数据
查看>>
SQL Server事务复制移动分发数据库–分步指南
查看>>