You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改针对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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:55:47