A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区


【黑马程序员济南】oracle数据库分页实现的总结




  • 1 根据伪列来分。
在分页时使用的伪列主要有两个,分别是rowid和rownum。rownum是在查询时生成的带有顺序的序列,当扫描到一行记录符合条件时就会生成从1开始的数,直到查询扫描结束。rowid是在创建数据时生成的物理伪列,在创建表时oracle就自动生成rowid,并且这个rowid是唯一的,当创建索引时会先找rowid再根据rowid查询具体的记录,所以根据rowid查询的效率非常高。下面就是基于伪列实现的带排序的分页。
[SQL] 纯文本查看 复制代码
select * from 待分页的表名 where rowid in 
(select rid from 
(select rownum rn,rid from 
(select rowid rid,待分页的表主键 from 待分页的表名 order by 待分页的表主键 desc) 
where rownum<=#end)where rn>=#start) order by 待分页的表主键 desc; 
  • 2 按分析函数来分。
oracle提供了很多函数可以在sql中使用,这里用到的函数就是row_number()。具体语法如下:ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BYCOLUMN)。PARTITION BY表示要分组的列, 如果不需要分组可以忽略,ORDER BY表示要排序的列
[SQL] 纯文本查看 复制代码
select * from 
(select t.*,row_number() over(order by 待分页的表主键 desc) rk from 待分页的表名 t) where 
rk<=#end and rk>=#start
  • 3 只用ROWNUM来分。
上面已经介绍了这个伪列,这里直接使用rownum这个伪列查询。
[SQL] 纯文本查看 复制代码
select * from 
  (select t.*,rownum rn from 
    (要分页的SQL) t where rownum<=#end) where rn>=#start;

#注意:对于以上3种方式,1的性能最好,2的性能最差,3性能也很好,简单易用,一般为主要选择方式!

  • 4 基于存储过程的实现。
除了函数之外也可以使用存储过程实现,在使用时可以直接用应用程序调用者存储过程,使用起来是非常方便的,只是写起来有些麻烦。存储过程可以直接将总记录数、总页数和要显示的数据全部查询出来。如下就是这种方式实现的

4.1创建一个包,该包中定义一个游标类型
[SQL] 纯文本查看 复制代码
create or replace package cursor_type_page is 
type my_cursor is ref cursor; 
end; 
4.2编写存储过程

[SQL] 纯文本查看 复制代码
create or replace procedure fenye( 
  v_in_sql in varchar2,--待分页的SQL 
  v_in_pagesize in number,--每页显示记录数 
  v_in_pagenow in number,--当前页数 
  v_out_result out cursor_type_page.my_cursor,--返回结果集 
  v_out_rows out number,--记录总数 
  v_out_pagecount out number--总页数 
) is 
--定义变量 
v_sql varchar2(2000); 
v_start number; 
v_end number; 
begin 
  --开始记录数 
v_start:=v_in_pagesize*(v_in_pagenow-1)+1; 
--结束记录数 
v_end:=v_in_pagenow*v_in_pagesize; 
--分页SQL实现 
v_sql:=select * from 
  (select t.*,rownum rn from 
    (v_in_sql) t where rownum<='||v_end||') where rn>='||v_start||'; 

--打开游标 
open v_out_result for v_sql; 
--查询共有多少条记录 
select count(*) into v_out_rows from  (v_in_sql); 
--计算总页数 
if mod(v_out_rows,v_in_pagesize)=0 then 
  v_out_pagecount:=v_out_rows/v_in_pagesize; 
  else 
     v_out_pagecount:=v_out_rows/v_in_pagesize+1; 
     end if; 
  end;


您需要登录后才可以回帖 登录 | 加入黑马