今天在工作中遇到一个看似简单的问题,大体要实现的功能是根据数据源查询出某张表的数据。由于表的字段是未知的,所以,在目前已经实现得到表所有字段的集合的基础上,Java层面要实现把每一行的数据查出来并映射到每个字段上。
首先,这是我建的测试表:
首先想到的是使用通常的Oracle分页:
select * from (select ROWNUM AS rowno,t.* from T_ADMIN t)
where rowno > 5 and rowno<=10;
查询结果:
通过该sql,确实查到了想要的分页数据,但是问题来了,我的后台代码是通过jdbc将每一行的数据查出来然后对应到该表的每个字段的,然而在这之前我所得到的表字段集合中并没有ROWNO这个字段,这就导致最终数据和字段映射错位以及长度不匹配的问题。那么只有想办法将查询结果中的ROWNO列去掉了(这里的查询字段是未知的,所以不能将“*”号换成字段名)。
于是,在网上找到一种查询方式
select b.* from
(select rowid rn,rownum from T_ADMIN where rownum<=10) a,T_ADMIN b
where a.rn=b.rowid;
可以看到查询结果中不包含ROWNUM列,本来喜出望外的以为只要再加上“>”的条件就要成功的时候
select b.* from
(select rowid rn,rownum from T_ADMIN where rownum<=10 and rownum>5) a,T_ADMIN b
where a.rn=b.rowid;
结果大跌眼镜:
查询结果为空,查了一下资料说是ROWNUM是个虚拟列,要从1开始查,大于1的条件就会导致这样的现象,于是想了一下,可以把SQL改成下面这样:
select b.* from
(select rowid rn,rownum from T_ADMIN where rownum<=10) a,T_ADMIN b
where a.rn=b.rowid and a.rownum>5;
这下可好,直接报错:
到这里,感觉到了Oracle分页的恶心,只能在这个基础上自己再进一步的优化SQL语句
在尝试优化SQL的过程中,突然想到了为什么不把第一种和最后一种方案结合起来使用呢,于是得到了下面的SQL语句:
select b.* from
(select rn,ri from (select ROWNUM AS rn,rowid ri from T_ADMIN t)
where rn > 5 and rn<=10) a
,T_ADMIN b where a.ri=b.rowid;
成功搞定!