如何修改针对Users表的自定义分页存储过程以返回总记录数
没问题,我帮你调整这个分页存储过程,让它同时返回当前页的10条数据和符合查询条件的总记录数。下面是修改后的完整代码,我会顺带解释关键改动点,方便你理解:
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[zsp_GetUsersAdministratorPanel] @StartRowIndex INT, @MaxRows INT = 10, -- 保留默认页大小为10 @OrderByField NVARCHAR(200), @Asc BIT, @SearchValue NVARCHAR(200), -- 假设原存储过程的搜索参数是这个,你可以根据实际参数名调整 @TotalRecords INT OUTPUT -- 新增输出参数,用来返回总记录数 AS BEGIN SET NOCOUNT ON; -- 第一步:计算符合条件的总记录数,务必和分页查询的过滤逻辑完全一致 SELECT @TotalRecords = COUNT(*) FROM Users WHERE -- 这里替换成你原存储过程中的实际过滤条件,比如用户名/邮箱模糊搜索 (@SearchValue IS NULL OR UserName LIKE '%' + @SearchValue + '%' OR Email LIKE '%' + @SearchValue + '%') -- 如果有其他过滤条件(比如状态、角色),一定要同步加上 -- 第二步:执行分页查询,返回当前页数据 WITH PaginatedUsers AS ( SELECT *, ROW_NUMBER() OVER ( ORDER BY -- 用CASE处理动态排序,避免SQL注入风险 CASE WHEN @Asc = 1 THEN CASE @OrderByField WHEN 'UserName' THEN UserName WHEN 'Email' THEN Email WHEN 'CreateTime' THEN CONVERT(NVARCHAR(50), CreateTime) -- 可以扩展更多支持排序的字段 ELSE UserName -- 默认排序字段 END END ASC, CASE WHEN @Asc = 0 THEN CASE @OrderByField WHEN 'UserName' THEN UserName WHEN 'Email' THEN Email WHEN 'CreateTime' THEN CONVERT(NVARCHAR(50), CreateTime) ELSE UserName END END DESC ) AS RowNum FROM Users WHERE -- 完全复用上面的过滤条件,保证总记录数和分页数据的匹配逻辑一致 (@SearchValue IS NULL OR UserName LIKE '%' + @SearchValue + '%' OR Email LIKE '%' + @SearchValue + '%') ) SELECT * EXCEPT (RowNum) -- 排除生成的RowNum字段,返回原表结构的用户数据 FROM PaginatedUsers WHERE RowNum BETWEEN @StartRowIndex AND (@StartRowIndex + @MaxRows - 1) ORDER BY RowNum; END GO
关键改动说明:
- 新增输出参数:添加了
@TotalRecords INT OUTPUT,调用存储过程时可以直接获取总记录数,方便前端计算总页数。 - 同步过滤逻辑:总记录数的查询和分页查询使用完全相同的WHERE条件,确保总记录数是真正符合查询要求的数量,不会出现偏差。
- 安全的动态排序:用CASE语句处理动态排序字段和升降序,避免了直接拼接SQL带来的SQL注入风险,比字符串拼接更安全可靠。
- 可选的替代方案:如果你不想用OUTPUT参数,也可以返回两个结果集——把总记录数的查询改成
SELECT COUNT(*) AS TotalRecords FROM ...,这样调用时会先得到总记录数,再得到分页数据。
调用示例:
DECLARE @Total INT; -- 调用存储过程,传入参数并接收总记录数 EXEC [dbo].[zsp_GetUsersAdministratorPanel] @StartRowIndex = 1, @MaxRows = 10, @OrderByField = 'UserName', @Asc = 1, @SearchValue = 'admin', @TotalRecords = @Total OUTPUT; -- 查看总记录数 SELECT @Total AS TotalRecords;
小提示:如果Users表数据量很大,COUNT(*)可能会有性能问题,可以考虑给过滤条件中用到的字段(比如UserName、Email)添加合适的非聚集索引来优化查询速度。
内容的提问来源于stack exchange,提问作者User987
相关产品推荐
相关产品推荐

