关于oracle分页存储过程---在线结贴

xuejiyong0619 2012-12-06 08:57:32
下面是一个oracle分页存储过程,执行单表分页是没什么问题,在多表进行联合查询时,当有2页数据时,第一页的最后几条会和第二页的开始几条重复;需要怎么改进,用的是rownum方式分页。
CREATE OR REPLACE Procedure sp_page(
i_tablename in varchar2, --表名emp e也可以这样 emp e left join dep d on e.dep_id=d.dep_id)
i_tablecolumn in varchar2, --查询列e.id,e.ename,e.job
i_order in varchar2, --排序e.ename desc
i_pagesize in number, --每页大小
i_curpage in number, --当前页
i_where in varchar2, --查询条件e.ename like '%S%'
o_cur_count out sys_refcursor, --行数和页数
o_cur_data out sys_refcursor
--o_cur_data out sys_refcursor --结果集
) is
v_count_sql varchar2(2000);
v_select_sql varchar2(2000);
l_rowcount integer; --总条数,输出参数
l_pagecount integer; --总页数
begin
--查询总条数
v_count_sql := 'select count(1) from ' || i_tablename;
--连接查询条件(''也属于is null)
if i_where is not null then
v_count_sql := v_count_sql || ' where ' || i_where;
end if;
--执行查询,查询总条数
execute immediate v_count_sql
into l_rowcount;

--得到总页数
if mod(l_rowcount, i_pagesize) = 0 then
l_pagecount := round(l_rowcount / i_pagesize);
else
l_pagecount := round(l_rowcount / i_pagesize) + 1;
end if;

open o_cur_count for
Select l_rowcount row_count, l_pagecount page_count from dual;

--如果查询记录大于0则查询结果集
if l_rowcount > 0 and i_curpage >= 1 and i_curpage <= l_pagecount then
--查询所有(只有一页)
if l_rowcount <= i_pagesize then
v_select_sql := 'select ' || i_tablecolumn || ' from ' ||
i_tablename;
if i_where is not null then
v_select_sql := v_select_sql || ' where ' || i_where;
end if;
if i_order is not null then
v_select_sql := v_select_sql || ' order by ' || i_order;
end if;
open o_cur_data for v_select_sql;
elsif i_curpage = 1 then
--查询第一页
v_select_sql := 'select ' || i_tablecolumn || ' from ' ||
i_tablename;
if i_where is not null then
v_select_sql := v_select_sql || ' where ' || i_where ||
' and rownum<=:page_size';
else
v_select_sql := v_select_sql || ' where rownum<=:page_size';
end if;

if i_order is not null then
v_select_sql := v_select_sql || ' order by ' || i_order;
end if;
open o_cur_data for v_select_sql using i_pagesize;
else
--查询指定页
v_select_sql := ' select ' || i_tablecolumn || ' from ' ||
i_tablename;

if i_where is not null then
v_select_sql := v_select_sql || ' where ' || i_where;
end if;

if i_order is not null then
v_select_sql := v_select_sql || ' order by ' || i_order;
end if;

v_select_sql := 'select /*+ first_rows(' || i_pagesize ||
') */ * from ' || '(select a.*, rownum rn ' ||
' from (' || v_select_sql || ') a ' ||
' where rownum <= :end_row) ' ||
' where rn>=:start_row';
open o_cur_data for v_select_sql
using i_curpage * i_pagesize,((i_curpage - 1) * i_pagesize) + 1;
end if;
else
open o_cur_data for 'select ' || i_tablecolumn || ' from ' || i_tablename || ' where 1!=1';
end if;

end sp_page;
...全文
163 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuejiyong0619 2012-12-06
  • 打赏
  • 举报
回复
引用 4 楼 yeness 的回复:
好漂亮的过程。。。
只对单表查询还行,多表就有问题了....
CSMSDN 2012-12-06
  • 打赏
  • 举报
回复
引用 13 楼 yeness 的回复:
引用 11 楼 CSMSDN 的回复:select top 50 * from News where id not in(select top 50*当前页数 id from News) 就知道能学到一些奇怪的东西。
奇怪吗?都用了几年了啊
xuan.ye 2012-12-06
  • 打赏
  • 举报
回复
好漂亮的过程。。。
xuejiyong0619 2012-12-06
  • 打赏
  • 举报
回复
问题决解后 见者有分
xuejiyong0619 2012-12-06
  • 打赏
  • 举报
回复
别沉啊 顶起啊....问题决解 见者有分
z0418511123 2012-12-06
  • 打赏
  • 举报
回复
顶哈,你调试下撒。
xuan.ye 2012-12-06
  • 打赏
  • 举报
回复
引用 11 楼 CSMSDN 的回复:
select top 50 * from News where id not in(select top 50*当前页数 id from News)
就知道能学到一些奇怪的东西。
xuejiyong0619 2012-12-06
  • 打赏
  • 举报
回复
就这个存储过程 先创建一个视图,在查视图就没问题了...
CSMSDN 2012-12-06
  • 打赏
  • 举报
回复
select top 50 * from News where id not in(select top 50*当前页数 id from News)
xuejiyong0619 2012-12-06
  • 打赏
  • 举报
回复
引用 9 楼 CSMSDN 的回复:
太长了,试试NOT IN 或者 beform and 分页
能拿段来看看吗
CSMSDN 2012-12-06
  • 打赏
  • 举报
回复
太长了,试试NOT IN 或者 beform and 分页
xuejiyong0619 2012-12-06
  • 打赏
  • 举报
回复
引用 7 楼 weiyz2011 的回复:
写的真心乱,看不明白,顶一贴吧
能分享一个也可以的》。。
weiyz2011 2012-12-06
  • 打赏
  • 举报
回复
写的真心乱,看不明白,顶一贴吧
xuan.ye 2012-12-06
  • 打赏
  • 举报
回复
v_select_sql := 'select /*+ first_rows(' || i_pagesize || ') */ * from ' || '(select a.*, rownum rn ' || ' from (' || v_select_sql || ') a ' || ' where rownum <= :end_row) ' || ' where rn>=:start_row'; --------------------------- 过程的意思就是代码写的太罗嗦了,根本都没法阅读,估计最后一句有问题

62,242

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧