问题
I have a stored procedure which returns a list of contacts. Since there are many contacts, and for performance reasons, I wish to retrieve the contacts in a page-wise manner, whereby only 20 contacts are fetched in the each instance.
A button on my form will allow me to go to the next page, and once the button is clicked, I go and fetch the next 20 contacts.
Here's my stored proc;
CREATE PROCEDURE [dbo].[GetAllContacts] (@searchVal VARCHAR(500))
AS
BEGIN
SELECT DISTINCT ( Id ) AS Id,
FirstName,
LastName,
Address,
Tel_no
FROM tblContact
WHERE ( FirstName LIKE ( '%' + @searchVal + '%' )
OR LastName LIKE ( '%' + @searchVal + '%' ) )
ORDER BY LastName
END
How do I split the query and how do I retrieve the next 20 contacts for the 2nd page and 3rd 20 contacts for the 3rd page?
I'm using MS SQL Server 2012.
回答1:
You can use a common table expression in conjunction with the ROW_NUMBER() function
ALTER PROCEDURE [dbo].[GetAllContacts]
@searchVal VARCHAR(500),
@page INT = NULL,
@perPage INT = NULL
AS
DECLARE @Start INT, @End INT
SET @page = ISNULL(@page, 1)
SET @perPage = ISNULL(@perPage, 10)
SET @start = CASE WHEN @page = 1 THEN 0 ELSE (@page - 1) * @perPage END + 1
SET @end = CASE WHEN @page = 1 THEN @perPage ELSE (@page * @perPage) END
;WITH [Contacts] AS (
SELECT [Id]
, [FirstName] , [LastName]
, [Address] , [Tel_no]
, ROW_NUMBER( ) OVER (ORDER BY LastName) AS [Index]
FROM [tblContact]
WHERE ([FirstName] LIKE ('%'+ @searchVal +'%')
OR [LastName] LIKE ('%'+ @searchVal +'%'))
), [Counter] AS (SELECT COUNT(*) AS [Count] FROM [Contacts])
SELECT [Id]
, [FirstName] , [LastName]
, [Address] , [Tel_no]
, @page AS CurrentPage
, @perPage AS PageSize
,CEILING(CAST([Counter].[Count] AS DECIMAL(18,2))/@perPage) AS TotalPages
FROM Contacts, [Counter]
WHERE [Index] >= @start AND [Index] <= @end
You could then call this by passing in the your search term, with page you want to display and the number of entries you want on each page
EXEC [dbo].[GetAllContacts] 'Smith', 3, 20
That will return the 3rd page of contacts that have a first name or last name that contains the word 'Smith'
Example: http://sqlfiddle.com/#!6/bb8ae/2
回答2:
Try this one -
CREATE PROCEDURE [dbo].[GetAllContacts]
(
@searchVal VARCHAR(500)
, @from INT
, @row_count INT = 20
)
AS
BEGIN
SELECT DISTINCT (Id) AS Id
, FirstName
, LastName
, address
, Tel_no
FROM tblContact
WHERE FirstName LIKE '%' + @searchVal + '%'
OR LastName LIKE '%' + @searchVal + '%'
ORDER BY LastName
OFFSET @from ROWS
FETCH NEXT @row_count ROWS ONLY;
END
Example -
EXEC GetAllContacts @searchVal = ''
, @from = 0
, @row_count = 20
EXEC GetAllContacts @searchVal = ''
, @from = 20
, @row_count = 20
EXEC GetAllContacts @searchVal = ''
, @from = 40
, @row_count = 20
回答3:
I found it (By using an orderedIndex );
ALTER PROCEDURE [dbo].[GetAllContacts] (@searchVal varchar(500)
, @CurrentPage int
, @PageSize int)
AS
BEGIN
DECLARE @RESULTS TABLE (
orderedIndex int IDENTITY(1,1) PRIMARY KEY
, Id bigint NOT NULL
, FirstName nvarchar(30) NULL
, LastName nvarchar(30) NULL
, Address nvarchar(130) NULL
, Tel_no nvarchar(15) NULL )
SET @CurrentPage = ISNULL(@CurrentPage, 1)
SET @PageSize = ISNULL(@PageSize, 10)
INSERT INTO @RESULTS (Id, FirstName, LastName, Address,Tel_no)
Select distinct(Id) as Id
, FirstName
, LastName
, Address
, Tel_no
from tblContact
Where (FirstName like ('%'+ @searchVal +'%') OR LastName like ('%'+ @searchVal +'%'))
Order by LastName
-- Get result on separate pages
SELECT Id
, FirstName
, LastName
, Address
, Tel_no
, (SELECT COUNT(*) FROM @RESULTS) AS NbResults
, @CurrentPage AS CurrentPage
, @PageSize AS PageSize
, FLOOR(CEILING(Cast((SELECT COUNT(*) FROM @RESULTS) as decimal(18,2))/ @PageSize)) as TotalPages
FROM @RESULTS
WHERE orderedIndex BETWEEN 1 + ((@CurrentPage - 1) * @PageSize) AND (@CurrentPage) * @PageSize
END
来源:https://stackoverflow.com/questions/18996633/sql-retrieve-data-pagewise