2

私はSQLが苦手ですが、多くのレコードを持つストアドプロシージャでjqGridのページングを行う必要があります。私のasp.net mvc3コントローラーコードは次のとおりです。

[HttpPost]
    public JsonResult GetExtraPersons(int cId, long pId, JQGridSettings gridSettings)
    {
        List<ExtraPerson> extraPersons = new List<ExtraPerson>();            
        ExtraPersonViewModel extraPersonViewModel = new ExtraPersonViewModel();
        extraPersonViewModel.CampId = cId;
        extraPersonViewModel.ReferencePatientId = pId;

        extraPersons = ExtraPersonService.GetExtraPersons(extraPersonViewModel.CampId, extraPersonViewModel.ReferencePatientId);

        int pageIndex = gridSettings.pageIndex;
        int pageSize = gridSettings.pageSize;
        int totalRecords = extraPersons.Count;
        int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);

        int startRow = (pageIndex - 1) * pageSize;
        int endRow = startRow + pageSize;

        var jsonData = new
        {
            total = totalPages,
            page = pageIndex,
            records = totalRecords,
            rows =
            (
              extraPersons.Select(e => new
              {
                  Id = e.ExtraPersonId,                
                  FirstName = e.FirstName,
                  LastName = e.LastName,
                  MobilePhone = e.MobileNumber,
                  Email = e.EmailId,
                  PersonalNumber = e.PersonNumber,
                  Diabetes = e.Diabetes, 
                  BloodPressure = e.BloodPressure,
              })
            ).ToArray()
        };
        return Json(jsonData);
    }

次のように、SQL Server 2008のストアドプロシージャと同様に、

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetExtraPerson] 
(
@CampId INT,
@ReferencePatientId BIGINT
)


AS  

BEGIN  
SET NOCOUNT ON         

SELECT  

PERS.PersonId,  
PERS.FirstName,  
PERS.LastName,  
PERS.MobileNumber,
PERS.EmailId,
PERS.PersonNumber,
E.ExtraPersonId,
E.Diabetes,
E.BloodPressure

FROM  
ExtraPerson E  
INNER JOIN Person PERS  
ON PERS.PersonId=E.PersonId  



WHERE E.CampId=@CampId AND ReferencePatientId=@ReferencePatientId AND E.IsDeleted = 0
END

現在、jqGrid はページングを除いて正常に動作しています。例: 15 件のレコードがある場合、最初のページには 10 件のレコードが表示され、残りは 2 ページ目にありますが、そこに移動できません。jqgridのページングを行う方法を教えてください。

4

1 に答える 1

2

必要なものを実装する方法はたくさんSTORED PROCEDUREあります。たとえばROW_NUMBER、CTE SQL ステートメント内で構造を使用できます。

SQL Server 2012 を使用している場合はOFFSET、 and FETCHafterを使用しORDER BYてページネーションを実装できます (こちらを参照)。OFFSETこの場合、SQL ステートメントは、 およびを使用する対応する MySQL または PostgreSQL ステートメントに非常によく似ていますLIMIT。ところで、Microsoft Entity Framework は、近い構文 ( and ) を持つEntity SQL Languageを使用します。SQL Server 2012 以降を使用している場合は、おそらく推奨される方法です。SKIPLIMITOFFSETFETCH

質問に SQL Server 2008 タグが含まれているため、回答では新しい SQL Server 2012 構造を使用しません。

もう 1 つの良い方法はsp_executesql、SQL ステートメントをパラメーター付きの文字列として作成できるようにすることです。最高のパフォーマンスを得るために非常に重要な実行計画を再利用できます。STORED PROCEDUREこのアプローチにより、サーバー側のフィルタリング (検索) を実装するためにコードを拡張できます。

返されたデータのIDを含むSQLステートメントにページネーションを実装する必要があることがわかりました(PersonIdあなたの場合)。SELECT TOPそこで、 と組み合わせて使用​​する簡略化された方法を使用することをお勧めしますLEFT OUTER JOIN

typeとの 2つSTORED PROCEDURE dbo.GetExtraPersonの追加パラメーターを指定できます。が等しい場合は、そのまま実行できますint@skip@pageSize@skip0STORED PROCEDURE

SELECT TOP (@pageSize) PERS.PersonId
    ,PERS.FirstName
    ,PERS.LastName
    ,PERS.MobileNumber
    ,PERS.EmailId
    ,PERS.PersonNumber
    ,E.ExtraPersonId
    ,E.Diabetes
    ,E.BloodPressure
FROM ExtraPerson E  
    INNER JOIN Person PERS ON PERS.PersonId=E.PersonId  
WHERE E.CampId=@CampId AND ReferencePatientId=@ReferencePatientId AND E.IsDeleted=0

@skipが等しくない場合0、対応する SQL ステートメントは次のようになります。

WITH GetAll AS (
    SELECT PERS.PersonId
        ,PERS.FirstName
        ,PERS.LastName
        ,PERS.MobileNumber
        ,PERS.EmailId
        ,PERS.PersonNumber
        ,E.ExtraPersonId
        ,E.Diabetes
        ,E.BloodPressure
    FROM ExtraPerson E  
        INNER JOIN Person PERS ON PERS.PersonId=E.PersonId  
    WHERE E.CampId=@CampId AND ReferencePatientId=@ReferencePatientId AND E.IsDeleted=0
),GetFirst AS (
    SELECT TOP (@skip) *
    FROM GetAll
    ORDER BY Name
),GetNext AS (
    SELECT TOP (@pageSize) a.*
    FROM GetAll AS a
        LEFT OUTER JOIN GetFirst AS f ON f.Id=a.Id
    WHERE f.Id IS NULL
    ORDER BY Name
)
SELECT * FROM GetNext 

の完全なコードはdbo.GetExtraPerson次のようになります

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE dbo.GetExtraPerson 
    @CampId int,
    @ReferencePatientId bigint,
    @skip int,
    @pageSize int
AS
BEGIN
    DECLARE @records int;
    SET NOCOUNT ON;

    SET @records = (SELECT COUNT(*)
                    FROM ExtraPerson E  
                        INNER JOIN Person PERS ON PERS.PersonId=E.PersonId  
                    WHERE E.CampId=@CampId
                        AND ReferencePatientId=@ReferencePatientId
                        AND E.IsDeleted=0);

    IF @skip <= 0
        SELECT TOP (@pageSize) PERS.PersonId
            ,PERS.FirstName
            ,PERS.LastName
            ,PERS.MobileNumber
            ,PERS.EmailId
            ,PERS.PersonNumber
            ,E.ExtraPersonId
            ,E.Diabetes
            ,E.BloodPressure
        FROM ExtraPerson E  
            INNER JOIN Person PERS ON PERS.PersonId=E.PersonId  
        WHERE E.CampId=@CampId AND ReferencePatientId=@ReferencePatientId
            AND E.IsDeleted=0
    ELSE
        WITH GetAll AS (
            SELECT PERS.PersonId
                ,PERS.FirstName
                ,PERS.LastName
                ,PERS.MobileNumber
                ,PERS.EmailId
                ,PERS.PersonNumber
                ,E.ExtraPersonId
                ,E.Diabetes
                ,E.BloodPressure
            FROM ExtraPerson E  
                INNER JOIN Person PERS ON PERS.PersonId=E.PersonId  
            WHERE E.CampId=@CampId AND ReferencePatientId=@ReferencePatientId
                AND E.IsDeleted=0
        ),GetFirst AS (
            SELECT TOP (@skip) *
            FROM GetAll
            ORDER BY Name
        ),GetNext AS (
            SELECT TOP (@pageSize) a.*
            FROM GetAll AS a
                LEFT OUTER JOIN GetFirst AS f ON f.Id=a.Id
            WHERE f.Id IS NULL
            ORDER BY Name
        )
        SELECT * FROM GetNext;

    RETURN @records;
END
GO

上記の手順は、さらにレコードの総数を返し、それを使用してtotalRecords値を割り当てることができます。

上記のコードを と組み合わせて使用​​する場合sp_executesql、コードを簡単に変更しORDER BYてすべてのSELECT TOPステートメントに含めることができるため、返される値は jqGrid でユーザーが要求した並べ替え順序に対応します。

于 2013-08-18T12:39:39.047 に答える