近日突然接到客户电话,反馈有张表不能update,需要帮忙看一下,下面我们回顾一下事情的始末,以供各位在日常工作中参考。
某日客户来电,电话那头只说了一句话,有张表不能update?帮忙看下。此时小编连忙三连问:
1、update 报错了?
2、update 执行时间长,hang住?
3、update 正常执行,数据没有被更新?
客户回了句,应该是第三者。此时,小编心想,这不可能吧。挂下电话,让客户把语句发过来,探探究竟。
查询:
更新:
欸,神了。可以查出该表有13609行数据。但通过相同查询条件去更新t_update表中xh列的时候,更新了0行。
这张表的数据量较小,小编新建了一张t_update_bak表(create table xxx as select * from xxx),再用上述update 语句去更新,可以更新成功。
再看查询条件,查询条件中存在函数f_getxx,这个函数是应用自己写的实现匹配功能的函数,把问题定位到这个函数上。把查询条件中joe.f_getxx(xh,9999,’lx’)=’1′ 去掉,再使用上述update 语句去更新,可以更新成功,但只要一使用这个查询条件去更新,0 rows update。
小编把这个函数的有效部分提取出来,如下:
此操作可以简述为:在更新这张表的某一列时,同时又使用这个列做为查询条件查询,这个查询语句写在函数f_getxx中,这种写法是错误的。
小编把异常处理模块去掉,再次执行的时候,就会产生下面报错。
所以说,这条函数本身就存在问题。
随即给客户回了个电话,说了下这个前因后果,建议应用把这个函数修改下。
电话那头,客户希望让小编顺便帮他们改改掉。
要解决这个问题,我们引入自治事务这个概念。随即解决思路就很简单了,在函数f_getxx pl/sql模块变量声明部分加上这么一行— PRAGMA AUTONOMOUS_TRANSACTION(即使用自治事务)。
修改完成之后,重新编译,再次执行更新。
这里小编跟大家说说自治事务。
oracle 自治事务
PRAGMA AUTONOMOUS_TRANSACTION(自治事务),对于定义成自治事务的Procedure,实际上相当于一段独立运行的程序段,这段程序不依赖于主程序,也不干涉主程序。
第一:这段程序不依赖于原有Main程序。比如Main程序中有未提交的数据,那么在自治事务中是查找不到的。
第二:在自治事务中,commit或者rollback只会提交或回滚当前自治事务中的DML,不会影响到Main程序中的DML。
下面举个例子:
创建自治事务:
请大伙儿细品。
美创运维中心数据库服务团队拥有Oracle ACE 1人、OCM 10余人、数十名Oracle OCP、MySQL OCP、红帽RHCA、中间件weblogic、tuxedo认证、达梦工程师 ,著有《Oracle DBA实战攻略》,《Oracle数据库性能优化方法和最佳实践》,《Oracle内核技术揭秘》等多本数据运维优化书籍。目前运维各类数据库合计2000余套,精通Oracle、MySQL、SQLServer、DB2、PostgreSQL、达梦等主流商业和开源数据库。并成为首批国内达梦战略合作伙伴之一,拥有海量经验和完善的人员培养体系。并同时提供超融合,私有云整体解决方案。
来源:freebuf.com 2020-05-29 15:52:24 by: database
请登录后发表评论
注册