Има много начини за внедряване на STORED PROCEDURE
които ви трябват. Например можете да използвате ROW_NUMBER
конструкция вътре в израза CTE SQL.
Ако използвате SQL Server 2012, можете да използвате OFFSET
и FETCH
след ORDER BY
за прилагане на страниране (вижте тук
). В случая SQL изразът ще изглежда много близък до съответните MySQL или PostgreSQL оператори, които използват OFFSET
и LIMIT
. Между другото Microsoft Entity Framework използва Entity SQL Language
с близка конструкция (SKIP
и LIMIT
). Вероятно OFFSET
и FETCH
би било предпочитан начин, ако използвате SQL Server 2012 или по-нова версия.
Тъй като сте включили маркера на SQL Server 2008 във вашия въпрос, не бих използвал нови конструкции на SQL Server 2012 в моя отговор.
Още един добър начин би бил да използвате sp_executesql
което ви позволява да конструирате SQL израз като низ с параметри. Позволява повторно използване на планове за изпълнение, което е много важно за най-добра производителност. Подходът ви позволява да разширите кода на вашата STORED PROCEDURE
за прилагане на филтриране (търсене) от страна на сървъра.
Виждам, че трябва да се приложи страниране в SQL израза, който съдържа ID на върнатите данни (PersonId
във вашия случай). Затова решавам да ви предложа да използвате опростен начин, който използва SELECT TOP
в комбинация с LEFT OUTER JOIN
.
Вие STORED PROCEDURE
dbo.GetExtraPerson
може да има два допълнителни параметъра от тип int
:@skip
и @pageSize
. В случай на @skip
е равно на 0
STORED 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 [email protected] AND [email protected] 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 [email protected] AND [email protected] 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 [email protected]
AND [email protected]
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 [email protected] AND [email protected]
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 [email protected] AND [email protected]
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.