如何在Oracle存储过程中实现分页

如何在Oracle存储过程中实现分页,第1张

我以前写过一个
PLSQL通用 分页 Function,可以参考一下我的博客:
>

sql语句如下:

分页1

SELECT

FROM (Select ROWNUM AS ROWNO, T

    from 表名 T(别名)

   where 表字段 between to_date('20060501', 'yyyymmdd') and  to_date('20060731', 'yyyymmdd')

    AND ROWNUM <= 20) TABLE_ALIAS

WHERE TABLE_ALIASROWNO >= 10;

经过测试,此方法成本最低,只嵌套一层,速度最快,即使查询的数据量再大,也几乎不受影响,速度依然

分页2:

SELECT

FROM (SELECT TT, ROWNUM AS ROWNO

    FROM (Select t

        from 表名 T(别名)

        where flight_date between to_date('20060501', 'yyyymmdd') and

           to_date('20060531', 'yyyymmdd')

        ORDER BY FACT_UP_TIME, flight_no) TT(别名二)

   WHERE ROWNUM <= 20) TABLE_ALIAS

where TABLE_ALIASrowno >= 10;

经过测试,此方法随着查询范围的扩大,速度也会越来越慢,

 

oracle是按rowmum分页的 查rownum ,rownum> 或者rownum<
然后你在jdbc算这个开始 结束值 传递给sql,
jdbc分页就是一次全全查出来,但是只返回要显示的个数,触发一次时间从list里边取一下
Hibernate有两个方法,一个可以设置开始位置,一个可以设置查询条数

select from (select t rownum row_id form (select from 表名) t ) where row_id>=1 and row_id<=10
这条SQL语句就可以实现分页查询,当然光有SQL还是不行,用以下的PHP 函数就可实现分页了。
/分页函数/
function page($page,$total,$phpfile,$pagesize=10,$pagelen=10,$str='')
{
$pagecode = '';//定义变量,存放分页生成的HTML
$page = intval($page);//避免非数字页码
$total = intval($total);//保证总记录数值类型正确
if(!$total) return array();//总记录数为零返回空数组
$pages = ceil($total/$pagesize);//计算总分页
//处理页码合法性
if($page<1) $page = 1;
if($page>$pages) $page = $pages;
//计算查询偏移量
$offset = $pagesize($page-1)+1;
//页码范围计算
$init = 1;//起始页码数
$max = $pages;//结束页码数
$pagelen = ($pagelen%2)$pagelen:$pagelen+1;//页码个数
$pageoffset = ($pagelen-1)/2;//页码个数左右偏移量
//生成html
$pagecode='<div class="page">';
$pagecode="<span>共"$total"条信息 第"$page"页/共"$pages"页</span>\n";//第几页,共几页
//如果是第一页,则不显示第一页和上一页的连接
if($page!=1){
$pagecode="<a href=\"{$phpfile}page=1&$str\"> 首页 </a> ";//第一页
$pagecode="<a href=\"{$phpfile}page="($page-1)"&$str\"> 上页 </a> ";//上一页
}
//分页数大于页码个数时可以偏移
if($pages>$pagelen)
{
//如果当前页小于等于左偏移
if($page<=$pageoffset)
{
$init=1;
$max = $pagelen;
}else
{
//如果当前页大于左偏移
//如果当前页码右偏移超出最大分页数
if($page+$pageoffset>=$pages+1)
{
$init = $pages-$pagelen+1;
}else{
//左右偏移都存在时的计算
$init = $page-$pageoffset;
$max = $page+$pageoffset;
}
}
}
//生成html
for($i=$init;$i<=$max;$i++)
{
if($i==$page)
{
$pagecode='<span><font color = red><b>'$i'</b></font></span>';
} else {
$pagecode="<a href=\"{$phpfile}page={$i}&$str\"> $i </a>";
}
}
if($page!=$pages)
{
$pagecode="<a href=\"{$phpfile}page="($page+1)"&$str\"> 下页 </a>";//下一页
$pagecode="<a href=\"{$phpfile}page={$pages}&$str\"> 末页</a>";//最后一页
}
$pagecode='</div>';
$onset = $offset + $pagesize -1;
return array('pagecode'=>$pagecode,'sqllimit'=>' and row_id between '$offset' and '$onset);
}
使用方法如下:
1,首先查询最大数据条数
$sql="select count() co_unt from 表名";
$st = OCIParse($conn, $sql);//分析指令
OCIExecute($st); //执行指令
$row=oci_fetch_array($st);
$counts=$row['CO_UNT'];
if($counts>0){
$page=isset($_GET['page'])$_GET['page']:1;
$getpageinfo = page($page,$counts,$phpfile,$chahaoString,10,15);
$pagesql=$getpageinfo['sqllimit'];//组合完整的SQL语句
$pagenav=$getpageinfo['pagecode'];//分页显示的样式代码
$sql="select from (select t rownum row_id form (select from 表名) t ) where 1=1 "$pagesql
}

原始记录

select t t rowid from t_stu t

order by t s_birthday desc

返回

STU_ID S_NAME C_ID S_BIRTHDAY

S 李四   C

S 张    C

S 张    C

S 张    C

S 张    C

Oracle分页查询

第一种 两层嵌套查询(网上流行的一种错误)

select from

(

select rownum r t from t_stu t

)

where r beeen and order by s_birthday desc

返回

R STU_ID S_NAME C_ID S_BIRTHDAY

S 李四   C

S 张三丰 C

S 张三   C

说明 上面的结果可能与你的不一样 因为Oracle在没有order by的情况 是随机选取记录的 前 名的记录应该是

STU_ID S_NAME C_ID S_BIRTHDAY

S 李四   C

S 张    C

S 张    C

第二种 换用三层嵌套查询

select b from

(select rownum r a from

(select t from t_stu t order by s_birthday desc )a

)b

where b r beeen and

返回

R STU_ID S_NAME C_ID S_BIRTHDAY

S 李四   C

S 张    C

S 张    C

正确!

所以Oracle分布查询一定要用三层嵌套 步骤如下

第三层 分页过滤

select b

from (

第二层 给定行号

select rownum r a from (

第一层 排序

select from 表 order by 字段

) a

where rownum<=最大行

)b

where b r beeen 最小行 and 最大行

关键点 先排序 后给行号 两个步骤要分开!

为了程序的通用性 对任意数据集都能分页 利用子查询改为如下结构

第三层 分页过滤

select b

from (

第二层 给定行号

select rownum r a from (

第一层 排序

select from (一个已经排序的数据集)

) a

where rownum<=最大行

)b

where b r beeen 最小行 and 最大行

如上面的查询改为

第三层 分页过滤

select b

from (

第二层 给定行号

select rownum r a from (

第一层 排序

select from (select t from t_stu t order by s_birthday desc)

) a

where rownum<=最大行

)b

where b r beeen 最小行 and 最大行

或者其它查询语句

第三层 分页过滤

select b

from (

第二层 给定行号

select rownum r a from (

第一层 排序

select from (select t from   新闻表 t order by 发贴日期 desc)

) a

where rownum<=最大行

)b

where b r beeen 最小行 and 最大行

原始数据数据脚本(请在命令窗口中粘贴以下语句即可)

prompt PL/SQL Developer import file

prompt Created on 年 月 日 星期一 by Administrator

set feedback off

set define off

prompt Dropping T_STU

drop table T_STU cascade constraints;

prompt Creating T_STU

create table T_STU

(

STU_ID     CHAR( )

S_NAME     CHAR( )

C_ID       CHAR( )

S_BIRTHDAY DATE

S_SEX       CHAR( )

)

;

prompt Disabling triggers for T_STU

alter table T_STU disable all triggers;

prompt Loading T_STU

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张三   C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 李四   C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张三丰 C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

insert into T_STU (STU_ID S_NAME C_ID S_BIRTHDAY S_SEX)

values ( S 张    C to_date( dd mm yyyy ) null);

mit;

prompt records loaded

prompt Enabling triggers for T_STU

alter table T_STU enable all triggers;

set feedback on

set define on

lishixinzhi/Article/program/Oracle/201311/18196

1把星都换成需要的字段名试一下。
2索引顺序排列正确(这个你查一下,索引不是建 了就可以。查询时有顺序的,四年前的项目,改变顺序后,时间由35s 提升到6-8s,具体的记不清了,只记得有这么回事。)
回去以后试一下你的SQL,只有数据多才出现这个问题吗?字段长度大约都多少?

SELECT
FROM (SELECT ROW_, ROWNUM ROWNUM_
FROM (SELECT
FROM tablename
) ROW_)
WHERE ROWNUM_ > 100
AND ROWNUM_ <= 120
根据你的假设,得到如上代码,其中的 100,120 是第5页的数据量,这个需要在java中控制第几页,不知道能不能解决您的问题


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13381275.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-25
下一篇 2023-07-25

发表评论

登录后才能评论

评论列表(0条)

保存