当前位置: 首页 > news >正文

SQLSERVER分页存储过程

在 SQL Server 中,分页存储过程用于高效查询大量数据中的某一页记录(如网页中的分页展示)。以下是一个通用的分页存储过程实现,支持动态表名、排序、条件筛选,并返回总记录数,适用于大多数场景。

分页存储过程实现

该存储过程使用 ROW_NUMBER() 函数(兼容 SQL Server 2005+)实现分页,同时返回当前页数据和总记录数,方便前端计算总页数。

CREATE PROCEDURE usp_GetPagedData@TableName NVARCHAR(100),        -- 要查询的表名或视图名@OrderBy NVARCHAR(100),          -- 排序字段(如 'ID DESC, Name ASC')@PageIndex INT = 1,              -- 页码(默认第1页)@PageSize INT = 10,              -- 每页记录数(默认10条)@Where NVARCHAR(1000) = '',      -- 查询条件(如 'Status = 1 AND CreateTime > ''2023-01-01''')@TotalCount INT OUTPUT           -- 输出参数:总记录数
AS
BEGINSET NOCOUNT ON; -- 不返回计数信息,提升性能
​BEGIN TRY-- 拼接查询总记录数的SQLDECLARE @CountSql NVARCHAR(1000) = 'SELECT @Total = COUNT(*) FROM ' + @TableName + CASE WHEN @Where <> '' THEN ' WHERE ' + @Where ELSE '' END;
​-- 执行总记录数查询EXEC sp_executesql @CountSql, N'@Total INT OUTPUT', @Total = @TotalCount OUTPUT;
​-- 计算分页起始位置(ROW_NUMBER()从1开始)DECLARE @StartRow INT = (@PageIndex - 1) * @PageSize + 1;DECLARE @EndRow INT = @PageIndex * @PageSize;
​-- 拼接分页查询SQL(使用ROW_NUMBER()实现)DECLARE @PagedSql NVARCHAR(2000) = 'WITH PagedData AS (SELECT *, ROW_NUMBER() OVER (ORDER BY ' + @OrderBy + ') AS RowNum FROM ' + @TableName + CASE WHEN @Where <> '' THEN ' WHERE ' + @Where ELSE '' END + ')SELECT * FROM PagedData WHERE RowNum BETWEEN ' + CAST(@StartRow AS NVARCHAR) + ' AND ' + CAST(@EndRow AS NVARCHAR) + 'ORDER BY RowNum';
​-- 执行分页查询并返回结果EXEC sp_executesql @PagedSql;END TRYBEGIN CATCH-- 捕获并返回错误信息SELECT ERROR_NUMBER() AS ErrorNumber,ERROR_MESSAGE() AS ErrorMessage,ERROR_LINE() AS ErrorLine;END CATCH
END

存储过程参数说明

参数名类型说明
@TableNameNVARCHAR(100)必需,要查询的表名或视图名(如 'Customers'
@OrderByNVARCHAR(100)必需,排序条件(如 'ID DESC''CreateTime ASC, Name DESC'
@PageIndexINT可选,页码(默认 1,即第一页)
@PageSizeINT可选,每页记录数(默认 10 条)
@WhereNVARCHAR(1000)可选,查询条件(无需加 WHERE 关键字,如 'Status = 1'
@TotalCountINT OUTPUT输出参数,返回符合条件的总记录数(用于计算总页数)

使用示例

假设查询 Orders 表中,状态为 1(已付款)的订单,按创建时间倒序排列,查询第 2 页,每页 20 条记录:

DECLARE @Total INT; -- 接收总记录数
​
-- 调用分页存储过程
EXEC usp_GetPagedData@TableName = 'Orders',@OrderBy = 'CreateTime DESC',@PageIndex = 2,@PageSize = 20,@Where = 'Status = 1',@TotalCount = @Total OUTPUT;
​
-- 输出总记录数
PRINT '总记录数:' + CAST(@Total AS NVARCHAR);

执行后会返回两个结果:

  1. 第 2 页的 20 条订单数据;

  2. 总记录数(通过 @Total 输出)。

优化与注意事项

  1. 性能优化

    • 确保 @OrderBy 中使用的字段有索引(如 CreateTime 字段建立索引),避免全表扫描。

    • 对于超大表(千万级以上),可考虑使用OFFSET FETCH(SQL Server 2012+ 支持),语法更简洁:

      SELECT * FROM Orders
      WHERE Status = 1
      ORDER BY CreateTime DESC
      OFFSET (@PageIndex - 1) * @PageSize ROWS
      FETCH NEXT @PageSize ROWS ONLY;
  2. 安全注意

    • 该存储过程使用动态 SQL,存在 SQL 注入风险。生产环境中需验证 @TableName@OrderBy 等参数的合法性(如检查表名是否存在于系统表 sys.tables 中)。

  3. 复杂查询

    • 若需关联多表查询,可先创建视图,再对视图使用该存储过程。

  4. 总记录数

    • 总记录数 @TotalCount 可用于前端计算总页数(总页数 = CEILING(总记录数 / 每页条数))。

通过该存储过程,可灵活实现各种场景下的分页查询,兼顾兼容性和易用性。根据实际业务需求,可进一步扩展参数(如返回字段筛选、关联查询等)。

http://www.dtcms.com/a/357951.html

相关文章:

  • 【YOLO11小目标改进】多尺度前馈网络(MSFN)代码
  • 第 8 篇:量化交易之tradeUI和webserverUI 区别?
  • 学习Python中Selenium模块的基本用法(11:弹窗处理)
  • LangGraph结构化输出详解:让智能体返回格式化数据
  • Docker核心概念与镜像仓库操作指南
  • AIGC应用与实践- 实验1:采用Markdown转换成WORD文档方式
  • 基于SpringBoot的流浪动物领养系统【2026最新】
  • Java函数式编程之【流(Stream)性能优化】
  • Docker(自写)
  • Netty 心跳与链路保活机制详解:保证高并发环境下的稳定连接
  • Web 聊天室消息加解密方案详解
  • Java面试-spring boot框架
  • 音视频学习(六十):H264中的PPS
  • 【C语言】字符函数与字符串函数实战:用法原理 + 模拟实现
  • VMware 设置 Ubuntu 虚拟机桥接模式完整教程
  • 音视频学习(六十二):H264中的SEI
  • 【Qt开发】按钮类控件(一)-> QPushButton
  • Ethan独立开发新品速递 | 2025-08-30
  • 【读书笔记】《最好的告别》
  • Git 安装与国内加速(配置 SSH Key + 镜像克隆)
  • 系统质量属性
  • 【瑞吉外卖】手机号验证码登录(用QQ邮件发送代替)
  • wpf之附加属性
  • 学习嵌入式第四十一天
  • 【电力电子】MCP602运算放大器测交流电压(120VAC/230VAC),带直流偏置2.5V,比例:133.5:1
  • 【杂谈】-混沌理论能否赋予机器差异化思考能力?
  • 华为 HarmonyOS 代表未来
  • 初学者如何学习项目管理
  • Citrix 零日漏洞自五月起遭积极利用
  • 爱普生L3255打印机故障记录