sql-server-2008 – 如何在存储过程中为jqGrid进行分页?
我不擅长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条记录,剩下的是第二页,但我不能去. 解决方法有许多方法可以实现您需要的STORED PROCEDURE.例如,您可以在CTE SQL语句中使用ROW_NUMBER构造.如果使用SQL Server 2012,则可以在ORDER BY之后使用OFFSET和FETCH来实现分页(请参阅here).在这种情况下,SQL语句看起来非常接近使用OFFSET和LIMIT的相应MySQL或PostgreSQL语句.顺便说一下,Microsoft Entity Framework使用Entity SQL Language具有紧密结构(SKIP和LIMIT).如果您使用SQL Server 2012或更高版本,可能OFFSET和FETCH将是首选方式. 因为您在问题中包含SQL Server 2008标记,所以我不会在我的答案中使用新的SQL Server 2012结构. 另一个好方法是使用sp_executesql,它允许您将SQL语句构造为带参数的字符串.它允许重用执行计划,这对于最佳性能非常重要.该方法允许您扩展STORED PROCEDURE的代码以实现服务器端过滤(搜索). 我看到需要在SQL语句中实现包含返回数据的ID(在您的情况下为PersonId)的分页.所以我决定建议你使用SELECT TOP结合LEFT OUTER JOIN的简化方法. 您存储的过程dbo.GetExtraPerson可以有两个类型为int的附加参数:@skip和@pageSize.如果@skip等于0,则STORED PROCEDURE可以执行 SELECT TOP (@pageSize) PERS.PersonId,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,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,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,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结合使用,则可以轻松修改代码以在所有SELECT TOP语句中包含ORDER BY,以便返回的值与jqGrid中用户请求的排序顺序相对应. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |