2016-11-23 8 views
0

SQL Server 2012を使用しています。ストアドプロシージャでページングを行う必要があります。クライアント側(Webページ)では、リクエストされたページのストアドプロシージャの結果を取得する必要があります。また、その条件のページ数を設定するページ番号を考慮せずに行数を取得する必要があります。ストアドプロシージャのページ番号を考慮したページングデータと行数の取得

例えば、私はこのように、このストアドプロシージャを実行する必要があり、私た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 

あるときに、2ページ目の10行を照会するために、このストアドプロシージャを実行する必要があります。

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

これはのためにbilling.BillMasterに105行あることを想像してみてください。結果として私のエンドユーザに10行を表示する必要があり、1から11の間で1ページを選択させる必要があります。

これは、この条件の行数がどれくらいあるかを知る必要があることを意味します。

私は数える行を返すために、以下のコードのように私のストアドプロシージャを変更することができます。

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 

しかし、あなたは、私は私の選択2回を記述する必要があり、これの変更やメンテナンスが保存されたので、それは良くないです見るようにプロシージャは非常に複雑になります。

また、私は一時テーブルに私の結果を保存し、以下のコードのようなものを使用することができます:

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 

しかし、この方法で見ることができるように、私は非常に遅くなることが物理的な一時テーブルを使用しています私が主セレクトに多くのデータを持っているときに、ページングを外に出す。

誰も私にその最善の方法を教えてもらえますか?

答えて

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 


 
+0

あなたの最初の解決策は私には良いことです。ありがとう –

0

挿入された各行に対して1ずつ増分するID列を持つ一時表を作成し、その列の最大値を読み取って行数を取得できます。

関連する問題