Det finns många sätt att implementera STORED PROCEDURE
som du behöver. Du kan till exempel använda ROW_NUMBER
konstruktion inuti CTE SQL-sats.
Om du använder SQL Server 2012 kan du använda OFFSET
och FETCH
efter ORDER BY
för att implementera paginering (se här
). Om SQL-satsen kommer att vara väldigt nära motsvarande MySQL- eller PostgreSQL-satser som använder OFFSET
och LIMIT
. Microsoft Entity Framework använder förresten Entity SQL Language
har nära konstruktion (SKIP
och LIMIT
). Förmodligen OFFSET
och FETCH
skulle vara att föredra om du använder SQL Server 2012 eller högre.
Eftersom du inkluderade SQL Server 2008-taggen i din fråga skulle jag inte använda nya SQL Server 2012-konstruktioner i mitt svar.
Ett annat bra sätt skulle vara att använda sp_executesql
som låter dig konstruera en SQL-sats som en sträng med parametrar. Det gör det möjligt att återanvända exekveringsplaner vilket är mycket viktigt för bästa prestanda. Tillvägagångssättet låter dig utöka koden för din STORED PROCEDURE
för att implementera filtrering på serversidan (sökning).
Jag ser det behovet av att implementera sidnumrering i SQL-satsen som innehåller ID för de returnerade data (PersonId
i ditt fall). Så jag bestämmer mig för att föreslå att du använder SELECT TOP
på ett förenklat sätt i kombination med LEFT OUTER JOIN
.
Du STORED PROCEDURE
dbo.GetExtraPerson
kan ha ytterligare två parametrar av typen int
:@skip
och @pageSize
. I fallet med @skip
är lika med 0
STORED PROCEDURE
kan bara köra
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
Om @skip
är inte lika med 0
då kan motsvarande SQL-sats vara följande
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
Den fullständiga koden för dbo.GetExtraPerson
kan handla om följande
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
Proceduren ovan returnerar dessutom det totala antalet poster och du kan använda den för att tilldela totalRecords
värde.
Om du skulle använda ovanstående kod i kombination med sp_executesql
du kan enkelt ändra koden så att den inkluderar ORDER BY
i alla SELECT TOP
satser så att de returnerade värdena motsvarar sorteringsordningen som begärts av användaren i jqGrid.