一个关于Oracle分页的实现方案

版权所有(c) 2007 Dorian Deng。署名 共享 非商用。
转载请注明出处:http://www.cnblogs.com/doriandeng/archive/2007/10/05/914834.html

前言:

在使用数据库进行项目的开发过程中,往往需要对查询结果进行分页处理,但由于每个数据库管理系统的实现不同,所使用的方法也不相同,本文展示了一个在使用Oracle数据库管理系统时的一个分页方案。 

注意:

在此展现的是一种方法,并不是一个通用的分页存储过程。 

环境:

OSMicrosoft® Windows Server 20003

DBMSOracle9i Enterprise Edition Release 9.2.0.3.0 

数据表:

方案中假设数据库中存在如下的示例数据库:

Create table authors(

Au_id varchar2( 11 ) primary key ,

Au_lname varchar2( 40 ) not null ,

Au_fname varchar2( 20 ) not null ,

Phone varchar2( 12 ) not null ,

Address varchar2( 4 ) null ,

City varchar2( 20 ) null ,

Zip char( 6 ) null

)

存储过程:

CREATE OR REPLACE PACKAGE DIVPAGE as
/*******************************************************************
*
*
作者:Dorian Deng
* 创建日期:2006-05-05
* 说明:
* 用于记录总页数和当前页的最小和最大记录号
*
********************************************************************/

procedure getPageRownum

(

 recordCount in number ,

 pageSize in number ,

 pageIndex in number ,

 pageCount out number ,

 pageMinRownum out number ,

 pageMaxRownum out number

);

end;

/

CREATE OR REPLACE PACKAGE BODY DIVPAGE as
/*******************************************************************
*
*
作者:Dorian Deng
* 创建日期:2006-05-05
* 说明:
* 用于记录总页数和当前页的最小和最大记录号
*
********************************************************************/

procedure getPageRownum

(

 recordCount in number ,

 pageSize in number ,

 pageIndex in number ,

 pageCount out number ,

 pageMinRownum out number ,

 pageMaxRownum out number

)

as

begin

 pageCount := ceil( recordCount / pageSize ) ;

 pageMaxRownum := pageIndex * pageSize ;

 pageMinRownum := pageMaxRownum - pageSize + 1 ;

end getPageRownum;

end;

/

CREATE OR REPLACE PACKAGE AUTHORSPACKAGE as
/*******************************************************************
*
*
作者:Dorian Deng
* 创建日期:2006-05-05
* 说明:
* 用于记录总页数和当前页的最小和最大记录号
*
********************************************************************/

type t_cursor is ref cursor ;

procedure SelectAuthors

(

 zip_in in char ,

 pageIndex in number ,

 pageSize in number ,

 pageCount out number ,

 AuthorsList out t_cursor

);

end AUTHORSPACKAGE ;

/

CREATE OR REPLACE PACKAGE BODY  AUTHORSPACKAGE as
/*******************************************************************
*
*
作者:Dorian Deng
* 创建日期:2006-05-05
* 说明:
* 用于记录总页数和当前页的最小和最大记录号
*
********************************************************************/

procedure SelectAuthors

(

 zip_in in char ,           --查询的条件

 pageIndex in number ,           --页码,以1开始

 pageSize in number ,           --每页记录数

 pageCount out number ,           --总页数

 AuthorsList out t_cursor           --当前页记录值

)

as

recordCount number ;

pageMinRownum number ;

pageMaxRownum number ;

begin

 select count( * ) into recordCount from ( select Au_id from authors ) ;

 DIVPAGE.getPageRownum( recordCount , pageSize , pageIndex ,

      pageCount , pageMinRownum , pageMaxRownum ) ;

 open AuthorsList for

    select * from ( --本级查询得出排序的结果集的rownum

select rownum rn , Au_id ,

          Au_lname ,

          Au_fname ,

          Phone ,

          Address ,

          City ,

          Zip

          from (

--本级查询按给定条件得出结果集,如果使用了order by,其rownum可能乱序,

--所以需要外一级的查询,同时直接使用zip_in参数,可防止SQL注入

select Au_id , 

Au_lname , Au_fname , Phone , Address ,City ,Zip

                      from authors where zip = zip_in order by au_lname ) )

          where rn between pageMinRownum and pageMaxRownum ;

end ;

end AUTHORSPACKAGE ;

参考:

1.一种分页的通用存储过程

create or replace package DotNet is 

 -- Author : good_hy

 -- Created : 2004-12-13 13:30:30

 -- Purpose :

 TYPE type_cur IS REF CURSOR;     --定义游标变量用于返回记录集   

 PROCEDURE DotNetPagination(     

 Pindex in number,                --分页索引  

 Psql in varchar2,                --产生datasetsql语句

 Psize in number,                 --页面大小

 Pcount out number,               --返回分页总数

 v_cur out type_cur               --返回当前页数据记录

 ); 

 procedure DotNetPageRecordsCount(

 Psqlcount in varchar2,           --产生datasetsql语句                           

 Prcount   out number             --返回记录总数

 );

end DotNot;

create or replace package body DotNet is

--**************************************************************** 

PROCEDURE DotNetPagination(

 Pindex in number,

 Psql in varchar2,

 Psize in number

 Pcount out number,

 v_cur out type_cur

)

AS 

 v_sql VARCHAR2(1000);

 v_count number; 

 v_Plow number;

 v_Phei number;

Begin

 ------------------------------------------------------------取分页总数

 v_sql := 'select count(*) from (' || Psql || ')';

 execute immediate v_sql into v_count;

 Pcount := ceil(v_count/Psize);

 ------------------------------------------------------------显示任意页内容

 v_Phei := Pindex * Psize + Psize;

 v_Plow := v_Phei - Psize + 1;

 --Psql := 'select rownum rn,t.* from cd_ssxl t' ;            --要求必须包含rownum字段

 v_sql := 'select * from (' || Psql || ') where rn between ' || v_Plow || ' and ' || v_Phei ;

 open v_cur for v_sql;

End DotNetPagination; 

--******************************************************** 

procedure DotNetPageRecordsCount(

 Psqlcount in varchar2,

 Prcount   out number

 )

 as

   v_sql varchar2(1000);

   v_prcount number;

 begin

   v_sql := 'select count(*) from (' || Psqlcount || ')';

   execute immediate v_sql into v_prcount;

   Prcount := v_prcount;                  --返回记录总数

    end DotNetPageRecordsCount; 

--************************************************************* 

end DotNot;

posted @ 2007-10-05 17:40  Dorian Deng  阅读(2684)  评论(0编辑  收藏  举报