Click here to Skip to main content
Click here to Skip to main content

Paging GridView with ROW_NUMBER()

By , 5 Feb 2006
 

Sample Image - PagingGridView.jpg

Introduction

Searching on the web, I found a lot of useful articles about this new feature of SQL Server 2005 and among them I mention the Jason Witty’s article - that was a starting point for me. We have been waiting for a long time for this new feature of SQL Server 2005. I don’t want to compare this new kind of ASP .NET paging with the well-known paging using temporary table, RowCount method or Cursor method, used with SQL Server 2000, but rather how simple is to paging a GridView in this way and to customize it. I don't use the built-in mechanism for paging of GridView web control.

I wrote this sample, because I needed to add custom paging for a grid view that allows easily changing the page size and go directly to a page number without passing throughout each page, one by one. In the past, I already used this kind of paging with data grid. To change it from datagrid to gridview I cut and paste the code and the job is done. Code behind is really a rudimentary one and is very easily to understand.

Code

In the Size button click event, we set the current page number and the page size and the we bind the GridView to display the data:

PageNum = 1;
PageSize = Convert.ToInt16(PageSizeTxt.Text);
BindGridView();
In the Go button event click, where we go to a page number:
        if (GoToPageTxt.Text != "")
        {
            int maxPage  = Convert.ToInt32(TotalPages.Text);
            int goToPage = Convert.ToInt32(GoToPageTxt.Text);

            if (goToPage <= maxPage)
            {
                PageNum = goToPage;
                BindGridView();
            }
        }
Here is the GridView HTML code:
<asp:GridView  ID="GridView1" runat="server" AutoGenerateColumns="False" >
       <Columns>
              <asp:BoundField DataField="RowNumber" HeaderText="RowNumber" />
              <asp:BoundField DataField="Name" HeaderText="Name" />
              <asp:BoundField DataField="SalesYTD" HeaderText="SalesYTD" />
              <asp:BoundField DataField="PostalCode" HeaderText="PostalCode" />
       </Columns>               
</asp:GridView>

I built the stored procedure with a SQL Server 2005 Books Online example. As you can see, it returns the ROW_NUMBER for the salespeople in AdventureWorks database, based on the year-to-date sales. My intention is not to explain how ROW_NUMBER() works, because it's already done in SQL Server 2005 Books Online or in many articles on the web, but how to pass the parameters to a stored procedure for customizing paging using ROW_NUMBER(). I just included the Microsoft query into my stored procedure and the paging works very well. Finally, the query returns the total number of records to calculate how many pages we can display. The stored procedure script is shown below:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

CREATE PROCEDURE [dbo].[sp_GridView_RowNumber]
(
    @PageNum int,
    @PageSize int,
    @TotalRowsNum int output
)
AS

BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Use ROW_NUMBER function
    WITH Salespeople_AdventureWorks As
    (
        SELECT 'RowNumber' = ROW_NUMBER() OVER(ORDER BY SalesYTD DESC), 
               'Name' = c.FirstName + ' ' + c.LastName, s.SalesYTD, a.PostalCode
        FROM Sales.SalesPerson s JOIN Person.Contact c on s.SalesPersonID = c.ContactID
        JOIN Person.Address a ON a.AddressID = c.ContactID
        WHERE ((TerritoryID IS NOT NULL) AND (s.SalesYTD <> 0))
    )

    -- Query result
    SELECT * 
    FROM Salespeople_AdventureWorks
    WHERE RowNumber BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize             
    ORDER BY SalesYTD DESC

    -- Returns total records number
    SELECT @TotalRowsNum = count(*) 
    FROM Sales.SalesPerson s JOIN Person.Contact c on s.SalesPersonID = c.ContactID
    JOIN Person.Address a ON a.AddressID = c.ContactID
    WHERE ((TerritoryID IS NOT NULL) AND (s.SalesYTD <> 0))
END
The source code includes the solution in Visual Studio 2005 and the script for the stored procedure. You have to change your connection string in the code to run the sample.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Socrate1
Web Developer
Canada Canada
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionInvalid column name 'rownum' errormemberauxcom27 Feb '07 - 1:29 
please help
 
my query is:
select row_number() over (order by EmployeeID) as rownum
from Employees
where rownum = 1
 
and this is the error:
Msg 207, Level 16, State 1, Line 4
Invalid column name 'rownum'.
GeneralFantastic Example, Thank you!!! [modified]membergreat_scandinavian1 Feb '07 - 20:53 
This example is very easy to massage and get to work!!
 
As feedback then I replaced the very expensive ...count()... SQL statement with a much faster one:
 
.
.
.
-- Returns total records number
SELECT @TotalRowsNum = rows
FROM sysindexes
WHERE id = OBJECT_ID('YourTableName') AND indid < 2
.
.
.
 
Above is lightning fast compare to the shown statement and scale well with the size of the table. Otherwise a very nice example that saved me hours of work.
 
Thank you Cool | :cool:
 

 
-- modified at 3:04 Friday 2nd February, 2007
QuestionSqlDataAdaptermembermaxtoroq4 Jan '07 - 16:54 
The SqlDataAdapter has an overload for the Fill method that takes a startRecord and maxRecords parameters. Isn't that much easier?
GeneralAll well and good, but...memberRob_Ehle11 Oct '06 - 7:30 
This works well with small amounts of data, but when your table has millions of records this really degrgates as you page farther into the page count.
 
I did find that if your OVER clause has the tables primary key as its order by then speed is acceptable. But then you are locked to one sort pattern.
 
The temperary table still out performs this with large ammounts of data.
 
Rob
GeneralNot a good solutionmemberkolbis4 Jul '06 - 19:25 
Hi,
What will happen when you need to implement serveral grids in the application?
You will have to implement for each, the navigation bar you created.
Sniff | :^)
 
"to code or not to code?" this is the question..
 
kolbis
GeneralRe:memberSocrate129 Jul '06 - 14:05 
Hi,
 
When we have several grids in the application we have to implement a custom control.
In this way we have to implement navigation in one place for all the grids.
 
The idea behind this article is not how to create a navigation bar, but rather how to avoid a temporary table in SQL Server by using ROW_NUMBER function.
 
Thanks
GeneralIncorrect syntax near the keyword 'WITH'membersasire186 Feb '06 - 2:49 
hi
why the procedure gives me the following error.Iam unable to rectify it
Server: Msg 156, Level 15, State 1, Procedure sp_GridView_RowNumber, Line 16
Incorrect syntax near the keyword 'WITH'.
Server: Msg 195, Level 15, State 1, Procedure sp_GridView_RowNumber, Line 18
'ROW_NUMBER' is not a recognized function name.
 
kindly explain what is wrong with the procedure
thanks
 
sasi
GeneralRe: Incorrect syntax near the keyword 'WITH'memberSocrate16 Feb '06 - 5:17 
Hi Sasi,
 
This is because you don't use the SQL Server 2005. I run the stored procedure with the SQL Server 2005 Standard Edition and it's okay.
 
I hope this help you,
 
Bye

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 5 Feb 2006
Article Copyright 2006 by Socrate1
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid