SQL - Retrieve data pagewise

拈花ヽ惹草 提交于 2019-12-11 10:34:57

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!