关键时刻,第一时间送达
最近看到一个有趣的题目,拿出来和大家分享一下,我的解决方法可能比较笨,就此抛砖引玉希望能有更优的办法。
题目内容
有一批Oracle数据库中的表(超过1000张),表中的一些字段的指定字符需要修改成其他指定字符。表名是类似的,例如TABLE0001,TABLE0002,TABLE0003等等,但是表名并不是连续的,有可能没有表TABLE0100,TABLE0200,TABLE0300等等。字段名称也是固定的,例如FIELD001,FIELD002,FIELD003以此类推。表的字段名也不固定,有的可能只有1个字段,有的可能有100多个字段,而且有的表有可能没有数据。现在就是要把所有这些表里的字段中包含“张三”字符的内容全部修改成“李四”,字段中的其他字符不变,例如:“张三是个好学生”改成“李四是个好学生”。
看到这样的题目,脑海中想到的第一个办法就是写个游标让它重复执行。但是随着我仔细的深入,发现并没那么简单。(想看答案的可以直接跳到文末代码部分)问题分解如下:
表名不连续的问题
表名不连续就要判断这个表是否存在数据库当中,这时候想到的是从Oracle的系统表USER_TABLES(用户表)中找到这些表,然后再插入到一张临时表中,并且将表中的记录数也一起插入,方便过滤记录为0的表,减少后期的内容更新。
查询语句如下:
很遗憾的是这里一直报错,错误原因是我想把变量的表名CUR.TABLE_NAME作为字符插入到临时表中,这样我查询临时表TEMP_TABLE就可以直接知道每个表的具体记录数,但是在动态SQL语句中就是不成功,只能另辟蹊径。
将遍历出来的表放在EXCEL里面自动生成我需要的查询语句,如下图:
图 EXCEL完成查询语句拼接
然后将这些拼接好的查询语句开始执行,即可将每张表的数据量查询出来并插入到临时表TEMP_TABLE中。第一步算顺利完成啦~
字段不固定
这个问题和表名不连续有点类似,但是也有不同的地方,我开始的做法是把所有列都给列出来,说做就做。
具体代码如下:
代码可以顺利执行,但是里面发现了个问题,它这个列不一定存在,如果执行中没有这个列,肯定会报错,数据库报错是不会自动帮你跳过的,就直接停止了。这样达不到效果!
进一步修改
既然这个列有可能不存在,那我先给它来个判断如何?
顺着这个思路,对代码加以修改,从系统表USER_TAB_COLUMNS中查询被更新的表中是否存在定义的列名,如果存在则执行更新,不存在就跳过。
具体代码如下:
结果成功了,只需要修改变量v_name即可。执行一次挺快的,只需要7秒左右。
后续优化
还有最后一步可以完全自动化执行,就是把所有列都放到一个表,循环执行这个游标,前提是知道最大列有多少个,或者直接取最大值FIELD999,这样在执行的时候可能会比较耗时间,因为每一轮他都要判断999次列是否存在。
至此,整改批量修改部分字段内容的功能全部完成。
一点思考
从这个题目中引发我的一点思考,有好的也有坏的。
好的是遇到问题能用其他办法解决就不要一棵树上吊死,第一步出错的地方至今未找到。如果把时间全放在这一步肯定得不偿失。工作中更多讲究的是效率,能用其他方法解决问题就尽快换方法解决。此外将问题细化也能让思维更优逻辑性。
坏的是遇到问题就一股脑的写代码,也不考虑写的结果是怎么样,这样其实还是很费时间的,磨刀不误砍柴工,将问题思考清楚再处理会更好。
结语
工作和生活中难免会遇到一些难题,当你能把一道题或者一件事通过自己思考做出来,那种成就感不言而喻。可能这就是程序员的快乐吧!
领取专属 10元无门槛券
私享最新 技术干货