【问题标题】:Paging data and get row count with out considering the page number in stored procedure在不考虑存储过程中的页码的情况下分页数据并获取行数
【发布时间】:2017-04-08 02:12:36
【问题描述】:

我使用的是 SQL Server 2012。我需要在我的存储过程中进行分页。在客户端(网页)中,我需要获得请求页面的存储过程的结果,并且我需要在不考虑在该条件下设置页数的页码的情况下获得行数。

例如,当我的 SubscribeId 为 12345674 时,我需要运行这个存储过程来查询第二页的十行。

Create Procedure TestSelectBill  
    (@PageNumber int = 1 ,  
     @RowCount int = 10  ,
     @SubscribeId Int = 0)  
As  
Begin  
    Select *  
    From billing.BillMaster As BM  
    Where (Bm.SubscribeId = @SubscribeId)  
    Order by SubscribeId  
        Offset (@PageNumber - 1) * @RowCount Rows 
        Fetch Next @RowCount Rows Only;  
End  

我必须像这样执行这个存储过程:

Execute TestSelectBill  
        @PageNumber = 2, @RowCount int = 10, @SubscribeId = 12345674

想象一下,对于这个SubscribeId = 123456574,我在billing.BillMaster 中有105 行。现在我需要向最终用户显示 10 行作为结果,我必须让他选择 1 到 11 之间的一页。

这意味着我需要知道此条件SubscribeId = 123456574 存在多少行。

我可以像下面的代码一样更改我的存储过程来返回行数:

Create Procedure TestSelectBill  
    (@PageNumber int = 1,  
     @RowCount int = 10,
     @SubscribeId Int = 0)  
As  
Begin  
    DECLARE @ROW_COUNT INT = 0

    -- Find Row Count for this condition
    Select   
        @ROW_COUNT = COUNT(*)  
    From 
        billing.BillMaster As BM  
    Where  
        (Bm.SubscribeId = @SubscribeId)  

    -- Select Result
    SELECT
        Row_Count = @ROW_COUNT,    
        *  
    FROM
        billing.BillMaster As BM  
    WHERE
        (Bm.SubscribeId = @SubscribeId)  
    ORDER BY
        SubscribeId  
        OFFSET ( @PageNumber - 1 ) * @RowCount ROWS  
        FETCH NEXT @RowCount ROWS ONLY;  
End  

但是如你所见,我必须写两次我的选择,这不好,因为这个存储过程的修改和维护会非常复杂。

另外,我可以将我的结果保存到临时表中,然后像下面的代码一样使用它:

CREATE Procedure TestSelectBill  
    (@PageNumber int = 1,  
     @RowCount int = 10,
     @SubscribeId Int = 0)  
As  
Begin  
    DECLARE @ROW_COUNT INT = 0

    -- Main Select 
    SELECT                      
        *  
    FROM 
        billing.BillMaster As BM  
    INTO 
        #T
    WHERE
        (Bm.SubscribeId = @SubscribeId)  

    -- Find Row Count for this condituion
    SELECT @ROW_COUNT = COUNT(*)  
    FROM #T

    -- Select Result
    SELECT
        Row_Count = @ROW_COUNT, 
        *  
    FROM
        #T
    ORDER BY 
        SubscribeId  
        OFFSET (@PageNumber - 1) * @RowCount ROWS  
        FETCH NEXT @RowCount ROWS ONLY;  
End  

但是正如你所看到的,我使用的是物理临时表,当我在主选择中有大量数据而没有分页时,它可能会非常慢。

谁能告诉我最好的方法?

【问题讨论】:

    标签: tsql sql-server-2012 data-paging


    【解决方案1】:
    -- First solution use count with window function CREATE Procedure TestSelectBill (@PageNumber int = 1, @RowCount int = 10, @SubscribeId Int = 0) As Begin SELECT COUNT(*) OVER(ORDER BY (SELECT NULL)) AS row_count , * FROM billing.BillMaster As BM WHERE (Bm.SubscribeId = @SubscribeId) ORDER BY SubscribeId OFFSET (@PageNumber - 1) * @RowCount ROWS FETCH NEXT @RowCount ROWS ONLY; End GO -- Second solution: use dynamic sql with multiple result Create Procedure TestSelectBill @PageNumber int = 1, @RowCount int = 10, @SubscribeId Int = 0 As Begin DECLARE @params NVARCHAR(max) = '@PageNumber int, @RowCount int, @SubscribeId int' DECLARE @where NVARCHAR(max) = N' WHERE Bm.SubscribeId = @SubscribeId' DECLARE @stmt NVARCHAR(max) = N'SELECT COUNT(*) as row_cnt FROM billing.BillMaster As BM ' DECLARE @stmt_rowcount NVARCHAR(max) = N'SELECT * FROM billing.BillMaster As BM ' DECLARE @order_by NVARCHAR(max) = ' ORDER BY SubscribeId OFFSET (@PageNumber - 1) * @RowCount ROWS FETCH NEXT @RowCount ROWS ONLY;' SET @stmt += @where + @order_by SET @stmt_rowcount += @where -- First result set (rowcount) EXEC [sys].[sp_executesql] @stmt = @stmt_rowcount, @params = @params, @SubscribeId = @SubscribeId, @PageNumber = @PageNumber, @RowCount = @RowCount -- Second result set (data) IF @@ERROR = 0 BEGIN EXEC [sys].[sp_executesql] @stmt = @stmt, @params = @params, @SubscribeId = @SubscribeId, @PageNumber = @PageNumber, @RowCount = @RowCount END End GO

    【讨论】:

      【解决方案2】:

      您可以创建一个临时表,其中的标识列每插入一行就递增 1,然后读取该列的最大值以获取行数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-20
        • 1970-01-01
        相关资源
        最近更新 更多