在SQL Server 2012及以上版本中,OFFSET FETCH子句是官方推荐的分页实现方式,相比传统的ROW_NUMBER()函数分页,语法更简洁,逻辑更清晰。将OFFSET FETCH子句和存储过程结合,通过动态传入页码和每页条数参数,就能实现通用的分页查询功能。

OFFSET FETCH子句基础用法
OFFSET FETCH子句需要和ORDER BY子句配合使用,基本语法如下:
-- 跳过前10条数据,取接下来的10条 SELECT column1, column2 FROM table_name ORDER BY sort_column OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
其中OFFSET后面的数值表示要跳过的行数,FETCH NEXT后面的数值表示要返回的行数。这两个数值都支持使用变量赋值,这也是实现动态传参的基础。
动态传参的核心逻辑
要实现动态传参,需要定义两个输入参数:@page_index表示当前页码(从1开始),@page_size表示每页显示的条数。然后通过计算将页码转换为OFFSET需要的跳过行数:
跳过行数 = (@page_index - 1) * @page_size
为了避免传入非法参数导致查询异常,需要对参数做基础校验,比如页码不能小于1,每页条数不能小于1。
完整存储过程实现示例
以下是一个查询用户表的分页存储过程示例,支持动态传入页码和每页条数:
-- 创建用户表分页查询存储过程
CREATE PROCEDURE proc_user_page
@page_index INT, -- 当前页码,从1开始
@page_size INT, -- 每页条数
@total_count INT OUTPUT -- 输出总记录数
AS
BEGIN
-- 参数校验
IF @page_index < 1
SET @page_index = 1;
IF @page_size < 1
SET @page_size = 10;
-- 计算跳过的行数
DECLARE @offset_rows INT;
SET @offset_rows = (@page_index - 1) * @page_size;
-- 查询总记录数
SELECT @total_count = COUNT(1) FROM user_info WHERE status = 1;
-- 分页查询数据
SELECT user_id, user_name, age, create_time
FROM user_info
WHERE status = 1
ORDER BY create_time DESC
OFFSET @offset_rows ROWS
FETCH NEXT @page_size ROWS ONLY;
END
GO
调用该存储过程的示例如下:
-- 声明总记录数变量 DECLARE @total INT; -- 查询第2页,每页15条数据 EXEC proc_user_page @page_index = 2, @page_size = 15, @total_count = @total OUTPUT; -- 输出总记录数 SELECT @total AS total_record;
注意事项
- ORDER BY子句是OFFSET FETCH的必填项,如果不需要特定排序,可以使用ORDER BY (SELECT NULL)来避免排序开销。
- 如果查询的表数据量较大,建议在排序字段上建立索引,提升分页查询的执行效率。
- 如果使用的是SQL Server 2008及以下版本,不支持OFFSET FETCH子句,需要改用ROW_NUMBER()函数实现分页。
- 输出总记录数的操作可以放在分页查询之前,避免分页查询影响总记录数的统计结果。
SQL存储过程分页查询OFFSET_FETCH动态传参修改时间:2026-07-17 00:12:28