Select中的ROWNUM
最近在项目中遇到了一个关于ROWID理解不足而产生的BUG。现总结如下:
环境
- DB:Oracle
- AP:Weblogic
BUG现象
程序是这样的有一个打印的机能,是按照某一个顺序进行顺次打印。BUG的描述也很简单,就是顺序不对。
BUG解析
这BUG解析不复杂,一看顺序不对,肯定就是SQL那错了呗。但看了一下程序处理很特别,是有个SQL文,SQL文里也有Order By,但不是把数据全取出来,而是每次只取第一条。通过循环无限的去取。可能是怕数据太多了内存会溢出吧。但在抽取的时候他使用了ROWNUM这个伪列,错也由此而来。
总结
我们先说一下ROWNUM这个虚拟列的特征:
- 排序前将检索出来的结果的记录序号设定到ROWNUM这个列中。
- 可以用来限制WHERE检索的记录数
- 含有ROWNUM的条件会在所有条件的最后进行解析。
看到这大家应该明白,我错在哪了吧。就是ROWNUM的值是排序前的值,也就是说数据程序中存在ORDERY BY,并且使用了ROWNUM<5这种条件的话,并且是在同一层级的SQL中,那么得到的结果就一定是错的。解析方法也很简单。就是将ORDER BY的程序做为子查询,也就是将SQL再套一层就是了。