Sql Server 存储过程分页

【2014-09-05】

  在企业级项目开发中,分页查询,获取某一类数据的List列表,这一功能是最普遍也是最重要的功能。其做法有很多种,例如ORM中自定义分页查询,一般情况下是拼接强类型的查询条件,然后转换成sql语句,查出出分页结果。在ORM转换过程中会稍微损失性能,效率会降低。对于百万级以上的大数据量,要求查询界面显示速度快,此时手动写存储过程,并且在存储过程中分页是最佳选择。下面给出具体的示例与说明:

=============================================
-- Author:        XXX
-- Create date: XXX
-- Description:    XXX
-- =============================================
ALTER PROCEDURE [dbo].[SP_GetRptNoCooperation]
    @custId NVARCHAR(30) --客户编号
     ,
    @custNam NVARCHAR(100) --客户名称
     ,
    @stopWorkingDateStart DATETIME -- 停止合作日期_起
     ,
    @stopWorkingDateEnd DATETIME -- 停止合作日期_止
     ,
    @crtDtStart DATETIME -- 申报日期_起
     ,
    @crtDtEnd DATETIME -- 申报日期_止
     ,
    @pageSize INT --单页记录条数
     ,
    @pageIndex INT --当前页左索引
     ,
    @totalRowCount INT OUTPUT --输出总记录条数
AS
BEGIN

    DECLARE @RowStart INT; --定义分页起始位置
    DECLARE @RowEnd INT; --定义分页结束位置

    DECLARE @Sql NVARCHAR(MAX); --拼接SQL语句

    DECLARE @SqlSelectResult NVARCHAR(MAX); --Sql查询结果语句
                                --
    DECLARE @SqlCount NVARCHAR(MAX); --Sql Count计数语句

    IF @pageIndex > 0
    BEGIN
        SET @pageIndex = @pageIndex -1;
        SET @RowStart = @pageSize * @pageIndex + 1;
        SET @RowEnd = @RowStart + @pageSize - 1;
    END
    ELSE
    BEGIN
        SET @RowStart = 1;
        SET @RowEnd = 999999;
    END

    IF ISNULL(@pageSize, 0) <> 0
       AND @pageSize <> 0
    BEGIN
        SET @sql =
            ‘With CTE_RptNoCooperation as (
            SELECT ROW_NUMBER () OVER (ORDER BY rnc.CrtDt DESC)  AS RowNumber
                    ,rnc.Id
                    ,rnc.CustId --客户编号
                    ,rnc.StopWorkingDate --停止合作日期(最后一次发货日期)
                    ,rnc.Arrears --截止申报日期的总欠
                    ,rnc.CheckAccount --对账情况(是否对清、对至几月份)
                    ,rnc.Communication --前期沟通处理情况(是否有退货/业务沟通催款情况/报法务室/出律师函或公函等)
                    ,rnc.MaySituation --XXXX年X月跟踪情况
                    ,rnc.JuneManagerSuggest --XXXX年X月部区经理意见
                    ,rnc.JunefinancialOpinion --财务审计部意见
                    ,rnc.CEOInstruct --总裁批示
                    ,rnc.CrtDt --创建日期
                    ,rnc.CrtBy --创建人id
                    ,rnc.UpdateDt --修改日期
                    ,rnc.UpdateBy --修改人id
                    ,ci.CustNam --客户名称
                    ,ai2.AreaNam --区域名称,省份
            FROM   RptNoCooperation     AS rnc
                   LEFT JOIN CustInfo   AS ci
                        ON  rnc.CustId = ci.CustId
                   LEFT JOIN AreaInfo   AS ai
                        ON  ci.AreaCode = ai.AreaCode
                   INNER JOIN AreaInfo  AS ai2
                        ON  ai.PareaCode = ai2.AreaCode
            WHERE  1 = 1 ‘;--此处CTE表达式右括号不写,在后面根据条件判断,追加
    END
    ELSE
    BEGIN
        SET @sql =
            ‘SELECT rnc.Id
                    ,rnc.CustId --客户编号
                    ,rnc.StopWorkingDate --停止合作日期(最后一次发货日期)
                    ,rnc.Arrears --截止申报日期的总欠
                    ,rnc.CheckAccount --对账情况(是否对清、对至几月份)
                    ,rnc.Communication --前期沟通处理情况(是否有退货/业务沟通催款情况/报法务室/出律师函或公函等)
                    ,rnc.MaySituation --XXXX年X月跟踪情况
                    ,rnc.JuneManagerSuggest --XXXX年X月部区经理意见
                    ,rnc.JunefinancialOpinion --财务审计部意见
                    ,rnc.CEOInstruct --总裁批示
                    ,rnc.CrtDt --创建日期
                    ,rnc.CrtBy --创建人id
                    ,rnc.UpdateDt --修改日期
                    ,rnc.UpdateBy --修改人id
                    ,ci.CustNam --客户名称
                    ,ai2.AreaNam --区域名称,省份
            FROM   RptNoCooperation     AS rnc
                   LEFT JOIN CustInfo   AS ci
                        ON  rnc.CustId = ci.CustId
                   LEFT JOIN AreaInfo   AS ai
                        ON  ci.AreaCode = ai.AreaCode
                   INNER JOIN AreaInfo  AS ai2
                        ON  ai.PareaCode = ai2.AreaCode
            WHERE  1 = 1 ‘;
    END

    IF ISNULL(@custId,‘‘) <> ‘‘
    BEGIN
        --根据客户id查询
        SET @Sql = @Sql + ‘ AND rnc.CustId = ‘‘‘ + @custId + ‘‘‘‘;
    END

    IF ISNULL(@custNam,‘‘) <> ‘‘
    BEGIN
        --根据客户名称 模糊查询
        SET @Sql = @Sql + ‘ AND ci.CustNam like ‘‘%‘ + @custNam + ‘%‘‘‘;
    END

    IF ISNULL(@stopWorkingDateStart,‘‘) <> ‘‘
    BEGIN
        --停止合作日期_起
        SET @stopWorkingDateStart = @stopWorkingDateStart + ‘ 00:00:00.000‘;
        SET @Sql = @Sql + ‘ AND rnc.StopWorkingDate >= ‘‘‘ + @stopWorkingDateStart  + ‘‘‘‘;
    END

    IF ISNULL(@stopWorkingDateEnd,‘‘) <> ‘‘
    BEGIN
        --停止合作日期_止
        SET @stopWorkingDateEnd = @stopWorkingDateEnd + ‘ 23:59:59.999‘
        SET @Sql = @Sql + ‘ AND rnc.StopWorkingDate <= ‘‘‘ + @stopWorkingDateEnd + ‘‘‘‘;
    END

    IF ISNULL(@crtDtStart,‘‘) <> ‘‘
    BEGIN
        --申请日期_起
        SET @crtDtStart = @crtDtStart + ‘ 00:00:00.000‘;
        SET @Sql = @Sql + ‘ AND rnc.CrtDt >= ‘‘‘ + @crtDtStart  + ‘‘‘‘;
    END

    IF ISNULL(@crtDtEnd,‘‘) <> ‘‘
    BEGIN
        --申请日期_止
        SET @crtDtEnd = @crtDtEnd + ‘ 23:59:59.999‘
        SET @Sql = @Sql + ‘ AND rnc.CrtDt <= ‘‘‘ + @crtDtEnd + ‘‘‘‘;
    END

    IF ISNULL(@pageSize, 0) <> 0
       AND @pageSize <> 0
       BEGIN
       SET @Sql = @Sql + ‘) ‘;

       SET @SqlCount = @Sql + ‘ SELECT @Temp = COUNT(*) FROM CTE_RptNoCooperation;‘;

       SET @SqlSelectResult = @Sql + ‘ SELECT * FROM CTE_RptNoCooperation
                           WHERE RowNumber Between ‘ + Convert(varchar(10),@RowStart) +
                           ‘ And ‘ + Convert(varchar(10),@RowEnd) + ‘;‘;

        --Print (@SqlSelectResult);

        --EXEC (@SqlSelectResult);
        EXEC sp_executesql @SqlSelectResult;
        EXEC sp_executesql @SqlCount,N‘@Temp int output‘,@totalRowCount output ;                   

       END
     ELSE
         BEGIN
             SET @Sql = @sql + ‘ order by rnc.CrtDt DESC ‘;
             SET @totalRowCount = 0;
        --Print (@Sql);
        EXEC (@Sql);
         END

END
GO
时间: 2024-11-11 05:04:11

Sql Server 存储过程分页的相关文章

sql server存储过程分页,行变列

CREATE PROCEDURE [dbo].[PROC_GetPriviousAndNextDetailContent]@Index varchar(20),--表主键@Table varchar(100),--从哪个表获取数据@Columns varchar(100),--需要获取哪些字段@OrderStr varchar(100),--排序字段及方式@Where1    varchar(100),--row_number中的初步过滤条件@Where2 varchar(100)--当前要查询

SQL SERVER 通用分页存储过程

SQL SERVER 通用分页存储过程 从SQLSERVER 2005开始,提供了Row_Number()函数,利用函数生成的Index来处理分页,按照正常的逻辑思维都是传pageIndex和pageSize来完成分页,昨天前端和我沟通,他们使用jQuery.DataTable.js插件,而且经过了公司底层的封装,pageIndex需要变动一下,变成pageIndex*pageSize来传. 也就是说按每页显示30条算,第一次传0,第二次传30这样来计算,我也是醉了. 1.传pageIndex和

SQL Server 2008 分页存储过程

在用的,已经不知道出处了,如果有侵权请告诉我,我立刻删掉. USE [ActivaOnlineSupport] GO /****** Object: StoredProcedure [dbo].[PROCE_PAGECHANGE] Script Date: 08/13/2014 13:45:17 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[PROCE_PAGECHANGE] ( @

Sql Server 存储过程中查询数据无法使用 Union(All)

原文:Sql Server 存储过程中查询数据无法使用 Union(All) 微软Sql Server数据库中,书写存储过程时,关于查询数据,无法使用Union(All)关联多个查询. 1.先看一段正常的SQL语句,使用了Union(All)查询: SELECT ci.CustId --客户编号 , ci.CustNam --客户名称 , ci.ContactBy --联系人 , ci.Conacts --联系电话 , ci.Addr -- 联系地址 , ci.Notes --备注信息 , ai

Sql Server 数据分页

1.引言 在列表查询时由于数据量非常多,一次性查出来会非常慢,就算一次查出来了,也不能一次性显示给客户端,所以要把数据进行分批查询出来,每页显示一定量的数据,这就是数据要分页. 2.常用的数据分页方法 我们经常会碰到要取n到m条记录,就是有分页思想,下面罗列一下一般的方法. 我本地的一张表 tbl_FlightsDetail,有300多W记录,主键 FlightsDetailID(Guid),要求按照FlightsDetailID排序 取 3000001 到3000010 之间的10条记录,也是

SQL Server 存储过程(转载)

SQL Server 存储过程 Transact-SQL中的存储过程,非常类似于Java语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这样就可以提高存储过程的性能. Ø 存储过程的概念 存储过程Procedure是一组为了完成特定功能的SQL语句集合,经编译后存储在数据库中,用户通过指定存储过程的名称并给出参数来执行. 存储过程中可以包含逻辑控制语句和数据操纵语句,它可以接受参数.输出参数.返回单个或多个结果集以及返回值. 由于存储

浅谈SQL Server数据库分页

数据库分页是老生常谈的问题了.如果使用ORM框架,再使用LINQ的话,一个Skip和Take就可以搞定.但是有时由于限制,需要使用存储过程来实现.在SQLServer中使用存储过程实现分页的已经有很多方法了.之前在面试中遇到过这一问题,问如何高效实现数据库分页.刚好上周在业务中也遇到了这个需求,所以在这里简单记录和分享一下. 一 需求 这里以SQLServer的示例数据库NorthWind为例,里面有一张Product表,现在假设我们的需求是要以UnitPrice降序排列,并且分页,每一页10条

SQL Server 存储过程(转)

SQL Server 存储过程 Transact-SQL中的存储过程,非常类似于Java语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这样就可以提高存储过程的性能. Ø 存储过程的概念 存储过程Procedure是一组为了完成特定功能的SQL语句集合,经编译后存储在数据库中,用户通过指定存储过程的名称并给出参数来执行. 存储过程中可以包含逻辑控制语句和数据操纵语句,它可以接受参数.输出参数.返回单个或多个结果集以及返回值. 由于存储

SQL Server存储过程的使用

存储过程概述 简单来说,存储过程就是一条或者多条sql语句的集合,可视为批处理文件,但是其作用不仅限于批处理. 基本概念: SQL Server中的存储过程是使用T_SQL编写的代码段.它的目的在于能够方便的从系统表中查询信息, 或者完成与更新数据库表相关的管理任务和其他的系统管理任务.T_SQL语句是SQL Server数据库与应用程序之间的编程接口. 存储过程就是SQL Server为了实现特定任务,而将一些需要多次调用的固定操作语句编写成程序段,这些程序段存储在服务器上, 有数据库服务器通