感谢群中的狗狗的讲解,今天上了一课。
在ORACLE中,分页是由ROWNUM来实现的。
ROWNUM存在使用规则,在单个子查询中,对于WHERE中的ROWNUM限制只能使用<或者<=。
如:
正确为:
SELECT * FROM T
WHERE ROWNUM<=10
错误为:
SELECT * FROM T WHERE ROWNUM>10
对于分页使用,正确为:
SELECT * FROM (SELECT *,T.ROWNUM RN FROM T WHERE ROWNUM<10)B WHERE B.RN>5
错误为:
SELECT * FROM (SELECT * FROM T WHERE ROWNUM <10) WHERE ROWNUM>5;
错误的情况无论表中是否存在数据,返回的结果都为0行。
对于此类情况的原因,是因为ORACLE中的ROWNUM 的实现机制导致的。
在ORACLE中,ROWNUM并非真正的标记在查出结果集的每列中后,再执行查询。
ROWNUM的实现类似如下代码:
ROWNUM:=1;
FOR X IN (SELECT * FROM T)
LOOP
IF (ROWNUM>1)
THEN
...
//具体实现输出查询结果
...
ROWNUM:=ROWNUM+1;
END IF;
END LOOP;
实际上,对于ROWNUM>1的情况,根本不会进入循环,所以根本不会出现ROWNUM:=ROWNUM+1的操作。
所以结果集必然为空。
另外,为了验证上面的伪代码,可以进行如下测试:
SELECT * FROM T WHERE ROWNUM=1;
如表中存在数据,则会返回一列数据。
SELECT * FROM T WHERE ROWNUM=2;
则不会返回数据。