关于分页存储过程中使用到的rownum陷阱解析:
http://www.blogjava.net/CONANS/ARTICLES/219693.HTML
create or replace procedure pd_page_query
(
in_colnames varchar2, --列名
in_tablename varchar2, --表名
in_where varchar2, --查询条件
in_order varchar2, --排序条件
in_curpage number, --当前页
in_pagesize number, --每页记录数
out_totalrecords out number, --总记录数
out_totalpages out number, --总页数
out_query_result out sys_refcursor --返回的结果集
)
------------------------------------------------------------------------------
---功能描述:通过传入的查询条件返回对应的分页查询结果
---时间: 2013-07-10
---作者: sunw
---版本: 1.0 beta
------------------------------------------------------------------------------
is
v_start_record int; --开始显示的记录条数
v_end_record int; --结束显示的记录条数
v_pagesize int; --每页记录数
v_curpage int; --当前页
v_colnames varchar2(2000); --列名
v_where varchar2(2000); --查询条件
v_order varchar2(2000); --排序条件
v_count_sql varchar2(2000); --记录数语句
v_select_sql varchar2(2000); --分页语句
begin
---------------------------------------------------开始判断条件---------------------------------------------------
--如果没有表名,则直接返回异常消息
--如果没有字段,则表示全部字段
if in_colnames is not null then
v_colnames:=in_colnames;
else
v_colnames:='*';
end if;
--如果没有where条件
if in_where is not null then
v_where:=' WHERE '||in_where;
end if;
--如果没有order by条件
if in_order is null then
v_order:='';
else
v_order:=' ORDER BY '||in_order;
end if;
--如果未指定查询页,则默认为首页
if in_curpage is null or in_curpage<1 then
v_curpage:=1;
else
v_curpage:=in_curpage;
end if;
--如果未指定每页记录数,则默认为10条记录
if in_pagesize is null then
v_pagesize:=10;
else
v_pagesize:=in_pagesize;
end if;
---------------------------------------------------开始数据处理----------------------------------------------------
--查询总条数
v_count_sql:='select count(*) from '||in_tablename||v_where;
--执行查询,得到out_totalrecords输出结果
execute immediate v_count_sql into out_totalrecords;
--输出查询语句
dbms_output.put_line('查询总记录数sql=>'||v_count_sql);
dbms_output.put_line('查询总记录数='||out_totalrecords);
--得到总页数,并进行处理
if mod(out_totalrecords,in_pagesize)=0 then
out_totalpages:=out_totalrecords/in_pagesize;
else
out_totalpages:=floor(out_totalrecords/in_pagesize)+1;
end if;
--如果传入的当前页大于最大页
if in_curpage>out_totalpages then
v_curpage:=out_totalpages;
end if;
--设置开始结束的记录数
v_start_record:=(v_curpage-1)*v_pagesize+1;
v_end_record:=v_curpage*v_pagesize;
---------------------------------------------------开始构造分页查询语句----------------------------------------------
--构造核心查询语句
v_select_sql:='(select '||v_colnames||' from '||in_tablename||v_where||v_order||') t';
--进行完整的动态sql语句拼写
v_select_sql:='select * from '||
'('||
'select t.*,rownum rn '||
' from '||
v_select_sql||
' where rownum<='||v_end_record||
')'||
' where rn>='||v_start_record;
--打印完整分页查询语句
dbms_output.put_line('查询sql=>'||v_select_sql);
open out_query_result for v_select_sql;
end pd_page_query;
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29812844/viewspace-1988810/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/29812844/viewspace-1988810/
本文详细解析了分页存储过程中使用到的rownum陷阱,并提供了一个实现分页查询的存储过程示例,包括如何计算总记录数、总页数以及构造分页查询语句。
2012

被折叠的 条评论
为什么被折叠?



