Sql Server 存储过程分页
在企业级项目开发中,分页查询,获取某一类数据的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
SQL Server 2012 及以上版本使用OFFSET/FETCH NEXT实现分页查询效率更高 ,
请参考 http://www.cnblogs.com/downmoon/archive/2012/04/19/2456451.html
成在管理,败在经验;嬴在选择,输在不学! 贵在坚持!
个人作品
BIMFace.SDK.NET
开源地址:https://gitee.com/NAlps/BIMFace.SDK
系列博客:https://www.cnblogs.com/SavionZhang/p/11424431.html
系列视频:https://www.cnblogs.com/SavionZhang/p/14258393.html
技术栈
1、AI、DeepSeek、MiniMax、通义千问
2、Visual Studio、.NET Core/.NET、MVC、Web API、RESTful API、gRPC、SignalR、Java、Python
3、jQuery、Vue.js、Bootstrap、ElementUI
4、数据库:分库分表、读写分离、SQLServer、MySQL、PostgreSQL、Redis、MongoDB、ElasticSearch、达梦DM、GaussDB、OpenGauss
5、架构:DDD、ABP、SpringBoot、jFinal
6、环境:跨平台、Windows、Linux
7、移动App:Android、IOS、HarmonyOS、微信小程序、钉钉、uni-app、MAUI
8、分布式、高并发、云原生、微服务、Docker、CI/CD、DevOps、K8S;Dapr、RabbitMQ、Kafka、RPC、Elasticsearch
欢迎关注作者头条号 张传宁IT讲堂,获取更多IT文章、视频等优质内容。
出处:www.cnblogs.com/SavionZhang
作者:张传宁 技术顾问、培训讲师、微软MCP、系统架构设计师、系统集成项目管理工程师、科技部创新工程师。
专注于企业级通用开发平台、工作流引擎、自动化项目(代码)生成器、SOA 、DDD、 云原生(Docker、微服务、DevOps、CI/CD);PDF、CAD、BIM 审图等研究与应用。
多次参与电子政务、图书教育、生产制造等企业级大型项目研发与管理工作。
熟悉中小企业软件开发过程:可行调研、需求分析、架构设计、编码测试、实施部署、项目管理。通过技术与管理帮助中小企业实现互联网转型升级全流程解决方案。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如有问题,可以通过邮件905442693@qq.com联系。共同交流、互相学习。
如果您觉得文章对您有帮助,请点击文章右下角【推荐】。您的鼓励是作者持续创作的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?