blogs.conchango.com

welcome to the conchango blogging site
Welcome to blogs.conchango.com Sign in | Join | Help
in Search

Rory Street's Blog

Do you want fries with that?

Paging filtering,searching and sorting in one stored procedure

Putting all the above into one stored procedure has often been a TSQL dynamic nightmare putting together various bits of SQL strings and executing them. Looking around the web I have found various examples but not for all of what I wanted to do in one procedure. There were examples for paging, filtering and sorting but all as separate examples. Since I finally managed to put these all together I thought I'd blog about it, more for my own reference than anything else. But if it works for you and you have any improvements or suggestions I would love to hear from you.

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

-- =============================================
-- Author:        Rory Street
-- Modified date: 10 Jan 2008
-- Description:    Get Products with optional keyword search sorting and paging.
--
-- =============================================
ALTER PROCEDURE [dbo].[GetProductsWithPaging]
    @StartRowIndex int = 0,
    @MaximumRows int = 10,
    @SortCol varchar(100),
    @SortDir varchar(5),
    @AmountFrom decimal(38,11)=null,
    @AmountTo decimal(38,11)=null,
    @KeyWordSearch varchar(200)=null

WITH EXECUTE AS CALLER
AS
BEGIN

SET NOCOUNT ON;
with TableCTE as
(
    SELECT TOP 500 ProductSKU,ProductTitle,ProductDescription,Price,Category
    (ROW_NUMBER() OVER (Order By
    CASE WHEN @SortCol='ProductTitle' AND @SortDir='DESC' THEN ProductTitle END DESC,
        CASE WHEN @SortCol='ProductTitle' AND @SortDir='ASC' THEN ProductTitle END ASC,

        CASE WHEN @SortCol='ProductDescription' AND @SortDir='DESC' THEN ProductDescription END DESC,
        CASE WHEN @SortCol='ProductDescription' AND @SortDir='ASC' THEN ProductDescription END ASC,

        CASE WHEN @SortCol='Price' AND @SortDir='DESC' THEN Price END DESC,
        CASE WHEN @SortCol='Price' AND @SortDir='ASC' THEN Price END ASC,

        CASE WHEN @SortCol='Category' AND @SortDir='DESC' THEN Category END DESC,
        CASE WHEN @SortCol='Category' AND @SortDir='ASC' THEN Category END ASC,

    )) AS Row
    FROM tblProducts
    WHERE
    ((@KeyWordSearch is null) or (ProductDescription like @KeyWordSearch))
    AND
    ((@AmountFrom is null) or (Price >= @AmountFrom ))   
    AND
    ((@AmountTo is null) or (Price <= @AmountTo ))   
)   
select * from TableCTE
WHERE
        Row
    BETWEEN
        @StartRowIndex +1 
    AND
        @StartRowIndex + @MaximumRows   

END

How it works
The thing I like about the above example is it does not use dynamically created SQL. I have deliberately used a basic example above of a simple product table that I wish to sort, filter and search from my product page. To make things a bit more interesting my product page is actually a WCF client (don't worry you can still call this procedure directly without WCF). As you can understand it doesn't make sense to download all of the data when using WCF and then trying to page and sort the data. You would create an interface that would accept paging and sorting and this stored procedure works pretty nicely with that type of concept. The stored procedure uses the Row_Number internal function to assign each rows with a unique sequential number based on the column we are sorting by which is handled by the CASE statements which works out which column we wish to search by using the @SortCol parameter. 

Paging is done by using the @StartRowIndex and @MaximumRows parameters. So for example if you wanted to page through your data with 10 records per page. Page ones settings would be @StartRowIndex=0  and @MaximumRows=11 for page two the settings would be @StartRowIndex=10  and @MaximumRows=11. Now you're probably wondering why I make the maximum amount of rows 11? The reason for this is that when I load the data on the client I will only display 10 of the rows if I get back 11 though, I know there is another page with at least 1 record so I can show my "Next Page" button on the client.

Note
This example will only work with SQL Server 2005 as it uses a CTE method.

Published 29 January 2008 21:54 by rory.street
Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
(optional)
(required) 
Submit
Powered by Community Server (Personal Edition), by Telligent Systems