in

CodeSmith Community

Your Code. Your Way. Faster!

Paging and Custom Stored Procedure Example

Last post 04-27-2008 3:35 AM by vjerko. 3 replies.
Page 1 of 1 (4 items)
Sort Posts: Previous Next
  • 05-08-2007 3:32 PM

    • Junto
    • Top 500 Contributor
    • Joined on 01-30-2007
    • Posts 12
    • Points 390

    Paging and Custom Stored Procedure Example

    Hi,

    Would anyone like to share an example of a custom stored procedure that:

    • Supports paging, and
    • Returns a TList not a dataset, and
    • INNER JOINS on one or more sub tables so a WHERE search can target the sub tables

    I have the following, which is an exact copy of the same generated GetPaged SP for a table called "Company", but with two INNER JOINS across tables that are related by foreign keys:

    ALTER PROCEDURE [dbo].[_Company_SearchGetPaged]
    (
    @WhereClause varchar (2000) = null ,
    @OrderBy varchar (2000) = null ,
    @PageIndex int = null ,
    @PageSize int = null
    )
    AS

    BEGIN

    DECLARE @PageLowerBound int
    DECLARE @PageUpperBound int

    -- Set the page bounds
    SET @PageLowerBound = @PageSize * @PageIndex
    SET @PageUpperBound = @PageLowerBound + @PageSize

    IF (@OrderBy is null or LEN(@OrderBy) < 1)
    BEGIN
    -- default order by to first column
    SET @OrderBy = '[CompanyID]'
    END

    -- SQL Server 2005 Paging
    declare @SQL as nvarchar(4000)
    SET @SQL = 'WITH PageIndex AS ('
    SET @SQL = @SQL + ' SELECT'
    IF @PageSize > 0
    BEGIN
    SET @SQL = @SQL + ' TOP ' + convert(nvarchar, @PageUpperBound)
    END

    SET @SQL = @SQL + ' ROW_NUMBER() OVER (ORDER BY ' + @OrderBy + ') as RowIndex'
    SET @SQL = @SQL + ', [Company].[CompanyID]'
    SET @SQL = @SQL + ', [Company].[AccountID]'
    SET @SQL = @SQL + ', [Company].[CompanyName]'
    SET @SQL = @SQL + ', [Company].[ContactName]'
    SET @SQL = @SQL + ', [Company].[DateCreated]'
    SET @SQL = @SQL + ', [Company].[PhoneNumber]'
    SET @SQL = @SQL + ', [Company].[Website]'
    SET @SQL = @SQL + ', [Company].[EmailAddress]'
    SET @SQL = @SQL + ', [Company].[AddressID]'
    SET @SQL = @SQL + ', [Company].[Active]'
    SET @SQL = @SQL + ' FROM dbo.[Company]'

    SET @SQL = @SQL + ' INNER JOIN [Subscription] ON [Subscription].CompanyID = [Company].CompanyID'
    SET @SQL = @SQL + ' INNER JOIN [Tag] ON [Tag].TagID = [Subscription].TagID'

    IF LEN(@WhereClause) > 0
    BEGIN
    SET @SQL = @SQL + ' WHERE ' + @WhereClause
    END

    SET @SQL = @SQL + ' ) SELECT'
    SET @SQL = @SQL + ' [CompanyID],'
    SET @SQL = @SQL + ' [AccountID],'
    SET @SQL = @SQL + ' [CompanyName],'
    SET @SQL = @SQL + ' [ContactName],'
    SET @SQL = @SQL + ' [DateCreated],'
    SET @SQL = @SQL + ' [PhoneNumber],'
    SET @SQL = @SQL + ' [Website],'
    SET @SQL = @SQL + ' [EmailAddress],'
    SET @SQL = @SQL + ' [AddressID],'
    SET @SQL = @SQL + ' [Active]'
    SET @SQL = @SQL + ' FROM PageIndex'
    SET @SQL = @SQL + ' WHERE RowIndex > ' + convert(nvarchar, @PageLowerBound)

    IF @PageSize > 0
    BEGIN
    SET @SQL = @SQL + ' AND RowIndex <= ' + convert(nvarchar, @PageUpperBound)
    END

    SET @SQL = @SQL + ' ORDER BY ' + @OrderBy
    exec sp_executesql @SQL

    -- get row count
    SET @SQL = 'SELECT COUNT(*) as TotalRowCount'
    SET @SQL = @SQL + ' FROM dbo.[Company]'

    SET @SQL = @SQL + ' INNER JOIN [Subscription] ON [Subscription].CompanyID = [Company].CompanyID'
    SET @SQL = @SQL + ' INNER JOIN [Tag] ON [Tag].TagID = [Subscription].TagID'

    IF LEN(@WhereClause) > 0
    BEGIN
    SET @SQL = @SQL + ' WHERE ' + @WhereClause
    END

    exec sp_executesql @SQL

    END

    The generated method that .netTiers generates returns a void:

    public virtual void SearchGetPaged( System.String whereClause, System.String orderBy, System.Int32? pageIndex, System.Int32? pageSize, int start, int pageLength)

    How on earth do you get the data out from this method??? I'm able to do the following, but can't assign the result to TList<Company> and bind the data to the GridView because the method does't return anything:

    DataRepository.CompanyProvider.SearchGetPaged("Tag.Name LIKE '%software%'", null, GridViewSearch.PageIndex, GridViewSearch.PageSize);

    Any suggestions, or even better code examples from people who have solved this problem are most welcome!

    Please help, I'm really stuck. Should I be using a view instead for this kind of thing? I can get this to work without the paging, but with 1000's of records a lack of paging is going to cause me some serious problems!

    Thanks in advance.

    Ben

    • Post Points: 35
  • 05-08-2007 4:07 PM In reply to

    • swin
    • Top 10 Contributor
    • Joined on 06-14-2006
    • London, UK
    • Posts 921
    • Points 34,675

    Re: Paging and Custom Stored Procedure Example

    Ben,

    Problem is caused by using dynamic sql - codesmith can't determine the output.

    see here for a workaround - http://community.codesmithtools.com/forums/permalink/23552/24140/ShowThread.aspx#24140

    hth

    swin

    -------------------------------------------------
    Member of the .NetTiers team
    -------------------------------------------------
    • Post Points: 5
  • 05-10-2007 10:42 AM In reply to

    • Junto
    • Top 500 Contributor
    • Joined on 01-30-2007
    • Posts 12
    • Points 390

    Re: Paging and Custom Stored Procedure Example

    I have had some success in solving this problem. The ORDER BY still eludes me, but I think a series of CASE WHEN statements would work (although ugly):

    ALTER PROCEDURE [dbo].[_Company_SearchGetPaged]
    (
    @WhereClause varchar (2000) = null ,
    @PageIndex int = null ,
    @PageSize int = null
    )
    AS

    BEGIN

    -- SQL Server 2005 Paging
    WITH PageIndex AS (
    SELECT ROW_NUMBER() OVER (ORDER BY CompanyName) AS
    RowIndex
    ,
    [Company].[CompanyID],
    [Company].[AccountID],
    [Company].[CompanyName],
    [Company].[ContactName],
    [Company].[DateCreated],
    [Company].[PhoneNumber],
    [Company].[Website],
    [Company].[EmailAddress],
    [Company].[AddressID],
    [Company].[Active]
    FROM dbo.[Company]
    INNER JOIN [Subscription] ON [Subscription].CompanyID = [Company].CompanyID
    INNER JOIN [Tag] ON [Tag].TagID = [Subscription].TagID
    WHERE Tag.[Name] IN (SELECT [Value] FROM dbo.Split(@WhereClause,','))
    GROUP BY
    [Company].[CompanyID],
    [Company].[AccountID],
    [Company].[CompanyName],
    [Company].[ContactName],
    [Company].[DateCreated],
    [Company].[PhoneNumber],
    [Company].[Website],
    [Company].[EmailAddress],
    [Company].[AddressID],
    [Company].[Active]
    )
    SELECT
    [CompanyID],
    [AccountID],
    [CompanyName],
    [ContactName],
    [DateCreated],
    [PhoneNumber],
    [Website],
    [EmailAddress],
    [AddressID],
    [Active]
    FROM PageIndex
    WHERE RowIndex BETWEEN (@PageIndex - 1) * @PageSize + 1 and @PageIndex*@PageSize
    ORDER BY CompanyName

    -- get row count
    SELECT COUNT(DISTINCT Company.CompanyID)
    FROM dbo.[Company]
    INNER JOIN [Subscription] ON [Subscription].CompanyID = [Company].CompanyID
    INNER JOIN [Tag] ON [Tag].TagID = [Subscription].TagID
    WHERE Tag.[Name] IN (SELECT [Value] FROM dbo.Split(@WhereClause,','))

    END

    The Split function is quite well explained here: http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=50648

    Hopefully this helps anyone else undertaking paging with custom stored procedures. This returns a TList<Company> as required.

    Regards

    Ben

    • Post Points: 35
  • 04-27-2008 3:35 AM In reply to

    • vjerko
    • Top 500 Contributor
    • Joined on 04-27-2008
    • Posts 10
    • Points 50

    Re: Paging and Custom Stored Procedure Example

    Well.. i have done the same - except there will be no search bar in the nettiers grid, and there will be no where clause. I don't see the way to implement this without dynamic sql.

    Just one note for readers (i lost too much time on this) - u need to refresh code smith cache by clicking tables collection and selecting the same again)

    And yes.. i think it would be the best to impletemnt some xml configuration file. You would put a class path and nettiers would generate method wrapper. Like, it would be cool to have ability to have wrapped methods like stats or something like that in some different layer not related to table, like @@CPU_BUSY, or some utility like deleting old records. Well, dynamic SQL is must have and this is big disadvantage.

    • Post Points: 5
Page 1 of 1 (4 items)
Copyright © 2008 CodeSmith Tools, LLC
Powered by Community Server (Commercial Edition), by Telligent Systems