`
quningstudy
  • 浏览: 53195 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

学习用存储过程实现分页

阅读更多
Sql代码
/*  
名称:spAll_ReturnRows  
输入:  
输出:  
调用:  
  EXEC spAll_ReturnRows 'SELECT  * FROM 表名', 页号, 返回记录数, '主键', '排序字段' 
  spAll_ReturnRows 'SELECT  * FROM all_Categories',2,10,'[ID]','[ID]' 
说明:[百万级]通用存储过程.分页存储过程..返回指定返回条数、指定页数的记录  
 
*/  
 
CREATE PROCEDURE dbo.spAll_ReturnRows  
(  
@SQL nVARCHAR(4000),  
@Page int,  
@RecsPerPage int,  
@ID VARCHAR(255),  
@Sort VARCHAR(255)  
)  
AS 
 
DECLARE @Str nVARCHAR(4000)  
 
SET @Str='SELECT   TOP '+CAST(@RecsPerPage AS VARCHAR(20))+' * FROM ('+@SQL+') T WHERE T.'+@ID+' NOT IN   
(SELECT   TOP '+CAST((@RecsPerPage*(@Page-1)) AS VARCHAR(20))+' '+@ID+' FROM ('+@SQL+') T9 ORDER BY '+@Sort+') ORDER BY '+@Sort  
 
PRINT @Str  
 
EXEC sp_ExecuteSql @Str  
GO  
 
/* 

/*
名称:spAll_ReturnRows
输入:
输出:
调用:
  EXEC spAll_ReturnRows 'SELECT  * FROM 表名', 页号, 返回记录数, '主键', '排序字段'
  spAll_ReturnRows 'SELECT  * FROM all_Categories',2,10,'[ID]','[ID]'
说明:[百万级]通用存储过程.分页存储过程..返回指定返回条数、指定页数的记录

*/

CREATE PROCEDURE dbo.spAll_ReturnRows
(
@SQL nVARCHAR(4000),
@Page int,
@RecsPerPage int,
@ID VARCHAR(255),
@Sort VARCHAR(255)
)
AS

DECLARE @Str nVARCHAR(4000)

SET @Str='SELECT   TOP '+CAST(@RecsPerPage AS VARCHAR(20))+' * FROM ('+@SQL+') T WHERE T.'+@ID+' NOT IN
(SELECT   TOP '+CAST((@RecsPerPage*(@Page-1)) AS VARCHAR(20))+' '+@ID+' FROM ('+@SQL+') T9 ORDER BY '+@Sort+') ORDER BY '+@Sort

PRINT @Str

EXEC sp_ExecuteSql @Str
GO

/* 名称:spAll_DeleteNoneUnique
输入:要查询的表名和字段列表
输出:
调用:
说明:实现千万级数据的分页显示!--可以在5秒内获取1448万条记录里的第1200页的100条记录,雄不?
*/

Sql代码
CREATE PROCEDURE GetRecordFromPage  
    @tblName      varchar(255),       -- 表名  
    @fldName      varchar(255),       -- 字段名  
    @PageSize     int = 10,           -- 页尺寸  
    @PageIndex    int = 1,            -- 页码  
    @IsCount      bit = 0,            -- 返回记录总数, 非 0 值则返回  
    @OrderType    bit = 0,            -- 设置排序类型, 非 0 值则降序  
    @strWhere     varchar(1000) = ''  -- 查询条件 (注意: 不要加 where)  
AS 
 
declare @strSQL   varchar(6000)       -- 主语句  
declare @strTmp   varchar(100)        -- 临时变量  
declare @strOrder varchar(400)        -- 排序类型  
 
if @OrderType != 0  
begin 
    set @strTmp = "<(select min" 
    set @strOrder = " order by [" + @fldName +"] desc" 
end 
else 
begin 
    set @strTmp = ">(select max" 
    set @strOrder = " order by [" + @fldName +"] asc" 
end 
 
set @strSQL = "select top " + str(@PageSize) + " * from [" 
    + @tblName + "] where [" + @fldName + "]" + @strTmp + "([" 
    + @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " [" 
    + @fldName + "] from [" + @tblName + "]" + @strOrder + ") as tblTmp)" 
    + @strOrder  
 
if @strWhere != '' 
    set @strSQL = "select top " + str(@PageSize) + " * from [" 
        + @tblName + "] where [" + @fldName + "]" + @strTmp + "([" 
        + @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " [" 
        + @fldName + "] from [" + @tblName + "] where " + @strWhere + " " 
        + @strOrder + ") as tblTmp) and " + @strWhere + " " + @strOrder  
 
if @PageIndex = 1  
begin 
    set @strTmp = "" 
    if @strWhere != '' 
        set @strTmp = " where " + @strWhere  
 
    set @strSQL = "select top " + str(@PageSize) + " * from [" 
        + @tblName + "]" + @strTmp + " " + @strOrder  
end 
 
if @IsCount != 0  
    set @strSQL = "select count(*) as Total from [" + @tblName + "]" 
 
exec (@strSQL)  
 
GO 

CREATE PROCEDURE GetRecordFromPage
    @tblName      varchar(255),       -- 表名
    @fldName      varchar(255),       -- 字段名
    @PageSize     int = 10,           -- 页尺寸
    @PageIndex    int = 1,            -- 页码
    @IsCount      bit = 0,            -- 返回记录总数, 非 0 值则返回
    @OrderType    bit = 0,            -- 设置排序类型, 非 0 值则降序
    @strWhere     varchar(1000) = ''  -- 查询条件 (注意: 不要加 where)
AS

declare @strSQL   varchar(6000)       -- 主语句
declare @strTmp   varchar(100)        -- 临时变量
declare @strOrder varchar(400)        -- 排序类型

if @OrderType != 0
begin
    set @strTmp = "<(select min"
    set @strOrder = " order by [" + @fldName +"] desc"
end
else
begin
    set @strTmp = ">(select max"
    set @strOrder = " order by [" + @fldName +"] asc"
end

set @strSQL = "select top " + str(@PageSize) + " * from ["
    + @tblName + "] where [" + @fldName + "]" + @strTmp + "(["
    + @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
    + @fldName + "] from [" + @tblName + "]" + @strOrder + ") as tblTmp)"
    + @strOrder

if @strWhere != ''
    set @strSQL = "select top " + str(@PageSize) + " * from ["
        + @tblName + "] where [" + @fldName + "]" + @strTmp + "(["
        + @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
        + @fldName + "] from [" + @tblName + "] where " + @strWhere + " "
        + @strOrder + ") as tblTmp) and " + @strWhere + " " + @strOrder

if @PageIndex = 1
begin
    set @strTmp = ""
    if @strWhere != ''
        set @strTmp = " where " + @strWhere

    set @strSQL = "select top " + str(@PageSize) + " * from ["
        + @tblName + "]" + @strTmp + " " + @strOrder
end

if @IsCount != 0
    set @strSQL = "select count(*) as Total from [" + @tblName + "]"

exec (@strSQL)

GO





几乎每一个WEB应用都会用到分页,因此,将其做得通用高效就变得非常重要了,根据自己的想法用存储过程做了一个分页的存储过程,与大家分享,希望能够通过讨论得到更好的解决方案。

  之所以用存储过程,是因为以后需要修改的话不需要修改程序代码,只需要修改存储过程的代码。但这个例子是在存储过程里动态生成的SQL语句,不知道会不会因此失去存储过程一次编译和快速的特点。代码如下:



Sql代码
--1、首先建立一个包,用户创建一个游标类型  
create or replace package pkg_query as 
  type cur_query is ref cursor;  
end pkg_query;  
 
--2、创建存储过程  
 
CREATE OR REPLACE PROCEDURE prc_query  
       (p_tableName        in  varchar2,   --表名  
        p_strWhere         in  varchar2,   --查询条件  
        p_orderColumn      in  varchar2,   --排序的列  
        p_orderStyle       in  varchar2,   --排序方式  
        p_curPage          in out Number,  --当前页  
        p_pageSize         in out Number,  --每页显示记录条数  
        p_totalRecords     out Number,     --总记录数  
        p_totalPages       out Number,     --总页数  
        v_cur              out pkg_query.cur_query)   --返回的结果集  
IS 
   v_sql VARCHAR2(1000) := '';      --sql语句  
   v_startRecord Number(4);         --开始显示的记录条数  
   v_endRecord Number(4);           --结束显示的记录条数  
BEGIN 
   --记录中总记录条数  
   v_sql := 'SELECT TO_NUMBER(COUNT(*)) FROM ' || p_tableName || ' WHERE 1=1';  
   IF p_strWhere IS NOT NULL or p_strWhere <> '' THEN 
       v_sql := v_sql || p_strWhere;  
   END IF;  
   EXECUTE IMMEDIATE v_sql INTO p_totalRecords;  
     
   --验证页面记录大小  
   IF p_pageSize < 0 THEN 
       p_pageSize := 0;  
   END IF;  
     
   --根据页大小计算总页数[Page]  
   IF MOD(p_totalRecords,p_pageSize) = 0 THEN 
       p_totalPages := p_totalRecords / p_pageSize;  
   ELSE 
       p_totalPages := p_totalRecords / p_pageSize + 1;  
   END IF;  
     
   --验证页号  
   IF p_curPage < 1 THEN 
       p_curPage := 1;  
   END IF;  
   IF p_curPage > p_totalPages THEN 
       p_curPage := p_totalPages;  
   END IF;  
     
   --实现分页查询  
   v_startRecord := (p_curPage - 1) * p_pageSize + 1;  
   v_endRecord := p_curPage * p_pageSize;  
   v_sql := 'SELECT * FROM (SELECT A.*, rownum r FROM ' ||  
            '(SELECT * FROM ' || p_tableName;  
   IF p_strWhere IS NOT NULL or p_strWhere <> '' THEN 
       v_sql := v_sql || ' WHERE 1=1' || p_strWhere;  
   END IF;  
   IF p_orderColumn IS NOT NULL or p_orderColumn <> '' THEN 
       v_sql := v_sql || ' ORDER BY ' || p_orderColumn || ' ' || p_orderStyle;  
   END IF;  
   v_sql := v_sql || ') A WHERE rownum <= ' || v_endRecord || ') B WHERE r >= ' 
            || v_startRecord;  
   DBMS_OUTPUT.put_line(v_sql);  
   OPEN v_cur FOR v_sql;  
END prc_query; 

--1、首先建立一个包,用户创建一个游标类型
create or replace package pkg_query as
  type cur_query is ref cursor;
end pkg_query;

--2、创建存储过程

CREATE OR REPLACE PROCEDURE prc_query
       (p_tableName        in  varchar2,   --表名
        p_strWhere         in  varchar2,   --查询条件
        p_orderColumn      in  varchar2,   --排序的列
        p_orderStyle       in  varchar2,   --排序方式
        p_curPage          in out Number,  --当前页
        p_pageSize         in out Number,  --每页显示记录条数
        p_totalRecords     out Number,     --总记录数
        p_totalPages       out Number,     --总页数
        v_cur              out pkg_query.cur_query)   --返回的结果集
IS
   v_sql VARCHAR2(1000) := '';      --sql语句
   v_startRecord Number(4);         --开始显示的记录条数
   v_endRecord Number(4);           --结束显示的记录条数
BEGIN
   --记录中总记录条数
   v_sql := 'SELECT TO_NUMBER(COUNT(*)) FROM ' || p_tableName || ' WHERE 1=1';
   IF p_strWhere IS NOT NULL or p_strWhere <> '' THEN
       v_sql := v_sql || p_strWhere;
   END IF;
   EXECUTE IMMEDIATE v_sql INTO p_totalRecords;
  
   --验证页面记录大小
   IF p_pageSize < 0 THEN
       p_pageSize := 0;
   END IF;
  
   --根据页大小计算总页数[Page]
   IF MOD(p_totalRecords,p_pageSize) = 0 THEN
       p_totalPages := p_totalRecords / p_pageSize;
   ELSE
       p_totalPages := p_totalRecords / p_pageSize + 1;
   END IF;
  
   --验证页号
   IF p_curPage < 1 THEN
       p_curPage := 1;
   END IF;
   IF p_curPage > p_totalPages THEN
       p_curPage := p_totalPages;
   END IF;
  
   --实现分页查询
   v_startRecord := (p_curPage - 1) * p_pageSize + 1;
   v_endRecord := p_curPage * p_pageSize;
   v_sql := 'SELECT * FROM (SELECT A.*, rownum r FROM ' ||
            '(SELECT * FROM ' || p_tableName;
   IF p_strWhere IS NOT NULL or p_strWhere <> '' THEN
       v_sql := v_sql || ' WHERE 1=1' || p_strWhere;
   END IF;
   IF p_orderColumn IS NOT NULL or p_orderColumn <> '' THEN
       v_sql := v_sql || ' ORDER BY ' || p_orderColumn || ' ' || p_orderStyle;
   END IF;
   v_sql := v_sql || ') A WHERE rownum <= ' || v_endRecord || ') B WHERE r >= '
            || v_startRecord;
   DBMS_OUTPUT.put_line(v_sql);
   OPEN v_cur FOR v_sql;
END prc_query;

3、JAVA代码里取出结果集

  

Java代码
String sql= "{ call prc_query(?,?,?,?,?,?,?,?,?) }";  
 
  CallableStatement call = con.prepareCall(sql);  
 
  // ……中间数据设置及注册省略  
 
  call.registerOutParameter(9, OracleTypes.CURSOR);  
 
  // 取出结果集  
 
  (ResultSet) call.getObject(9); 
分享到:
评论

相关推荐

    asp.net 用存储过程实现分页(附代码)

    在ASP.NET中,使用存储过程实现分页是一种高效且可维护的方法。通过创建存储过程来处理分页逻辑,然后在.NET代码中调用该过程,可以轻松实现数据分页展示。同时,结合分页控件,可以快速构建用户友好的分页界面。...

    存储过程分页实现实例源码

    存储过程分页实现实例源码 源码描述: Filename: PeterPageList * Description: 主要运用sql存储过程进行分页实现,在进行分页实现,需要注意一下事项, * 在项目的根目录下面有一个db文件夹,请认真阅读,里面包含...

    效率高的分页存储过程实现的分页

    标题 "效率高的分页存储过程实现的分页" 提到的是一种优化数据检索的技术。在ASP.NET开发中,GridView控件是常用的数据展示工具,它可以方便地与数据库交互,支持各种操作如查询、排序、选择、删除和批量操作。然而...

    存储过程实现分页小例子

    本资源提供的"存储过程实现分页例子"是一个很好的学习点,展示了如何利用存储过程来实现数据库查询的分页功能。下面将详细解释这个主题。 首先,存储过程是预编译的SQL语句集合,存储在数据库服务器中,可以被多次...

    ASPNET存储过程自定义分页详解

    本教程将深入讲解如何利用存储过程实现自定义分页,以提高性能并优化用户体验。ASP.NET、C#、SQL以及DBA技能在此过程中扮演着核心角色。 首先,我们需要理解什么是存储过程。存储过程是预编译的SQL语句集合,存储在...

    利用存储过程分页的示例

    通过上述分析可以看出,利用存储过程实现分页查询不仅可以有效提升查询效率,还能确保代码的健壮性和安全性。开发者可以根据具体的业务需求调整存储过程中的参数配置,灵活应对不同的查询场景。此外,通过对存储过程...

    c#调用分页存储过程

    分页存储过程则是专门用于实现分页查询的存储过程,它接收两个参数,通常是开始行号和每页的记录数,然后返回指定范围内的数据。 在C#中,我们可以使用ADO.NET库来调用这些存储过程。以下是一个简单的示例: ```...

    毕业设计-源码Java调用Oracle存储过程实现分页功能

    在这个毕业设计项目中,我们主要探讨的是如何使用Java语言调用Oracle数据库的存储过程来实现分页功能,这在Web应用程序中非常常见,尤其是在处理大数据量时,为了提高用户体验,分页是一种有效的数据展示方式。...

    asp.net SQL存储过程分页

    在ASP.NET中,我们通常使用SqlDataSource控件配合存储过程实现分页。首先,我们需要创建一个存储过程,该过程接收两个参数:当前页号和每页显示的记录数。然后,在存储过程中使用`OFFSET`和`FETCH NEXT`子句(对于...

    c# bs,cs都能使用的存储过程分页代码

    Access虽然通常被认为适合小型应用,但它包含了对存储过程的支持,这使得在它上面实现分页成为可能。项目的压缩包中包含的"Pager"很可能是一个类库或者示例代码,用于演示如何在C#中调用存储过程进行分页。 在配置...

    sql2000存储过程和分页学习

    在提供的压缩包"sql2000学习"中,可能包含了关于如何在SQL Server 2000中创建和使用存储过程,以及如何在没有`ROW_NUMBER()`函数支持的情况下实现分页查询的教程和示例。通过深入学习这些材料,你可以更好地理解和...

    Oracle分页+.cs代码+存储过程+Aspnetpager分页控件

    Oracle数据库在处理大数据量时,分页查询是一个非常重要的功能,它可以提高网页加载速度,减少...通过学习和实践,开发者可以掌握在Oracle环境中高效地实现分页查询的方法,从而提升Web应用程序的性能和用户体验。

    利用存储过程分页

    利用存储过程实现分页是一种高效且安全的方法,它不仅可以提高数据检索的速度,还能优化资源使用,尤其适合数据量较大的场景。通过上述存储过程的解析,我们不仅了解了其实现细节,还学习到了如何在实际项目中应用这...

    存储过程分页实现实例源码 v1.0.zip

    存储过程分页实现实例源码描述: Filename: PeterPageList Description: 主要运用sql存储过程进行分页实现,在进行分页实现,需要注意一下事项, 在项目的根目录下面有一个db文件夹,请认真阅读,里面包含测试...

    基于存储过程+分页控件+分页类的无敌分页模式

    总结来说,"基于存储过程+分页控件+分页类的无敌分页模式"是一种强大的数据管理技术,它结合了数据库优化、用户界面控制和后端逻辑,实现了在大量数据场景下的高效分页。理解并掌握这一模式,对于任何处理大数据的IT...

    web三层无存储过程分页Demo

    在IT行业中,Web应用开发通常遵循一定的架构模式,以实现高效、...开发者可以通过这个Demo学习到如何在业务逻辑层构建动态SQL,如何在前端和后端之间有效地通信,以及如何在没有存储过程的情况下实现高性能的分页查询。

    c#编写无存储过程简单分页程序

    本教程将深入讲解如何使用C#编写一个不依赖存储过程的简单分页程序。虽然标题提及了存储过程,但我们将主要关注无存储过程的解决方案,因为这种方法允许更高的灵活性和更好的数据库无关性。 1. **理解分页概念**: ...

    万能存储过程分页,搞效率分页

    压缩包中的"万能存储过程分页"可能包含了实现这些策略的示例代码,通过学习和理解这些示例,可以更好地掌握高效分页的方法。如果你在理解和使用过程中遇到问题,可以通过提供的QQ联系方式寻求帮助,以便获得更具体的...

    一个梦想的三层架构+存储过程后台分页+AspNetPager前台分页的经典例子

    在这个例子中,开发人员可能使用了存储过程来实现后台的分页逻辑,返回特定页码的数据集。然后,AspNetPager控件在前端接收这些数据并展示给用户,提供导航链接以切换不同的页面。开发人员可能在BLL层调用了数据库的...

    一个基于MSSQL 2005 实现的存储过程Procedure 分页处理技术高级技巧例子源码

    总之,这个"CustomPaging.sql"文件很可能是提供了一个利用存储过程实现分页处理的示例,通过学习这个例子,我们可以更好地理解和应用MSSQL 2005中的存储过程以及分页技术,从而在实际项目中提升数据查询的效率和用户...

Global site tag (gtag.js) - Google Analytics