Pagination using Stored Procedure
There are different approach on how to do pagination, but the I personally uses the dynamic sql pagination using subquery, and this I think is very efficient when doing a pagination in which all the fields to be filtered and sorted are all in the same table:
EXEC ( 'SELECT ' + @sqlQuery +
' WHERE [ID] IN ' +
' (SELECT TOP ' + @strPageSize + ' [ID] FROM ' + @strBaseTable + @strFilter +
@Connector + ' [ID] NOT IN ' + '
(SELECT TOP ' + @strSkippedRoW + ' [ID] FROM ' + @strBaseTable + @strFilter + @SortBy + ') '
+ @SortBy + ') ' + @SortBy)
Example we have our SalesOrderTable which comprises of SalesID, Date, ItemID, WholeSalerID, CustomerID and the other table we have are Item Table, Wholesaler Table, CustomerTable . In this example lets take in mind these are the number of records per table:
SalesOrderTable = 2,300,000 | ItemTable = 670,000 | WholeSaler Table = 310,000 | Customer Table = 900,000
What if the user wanted the data sorted using ItemName, CustomerName, WholeSaler Name which is on different table, in order to achive this we are going to use JOINS right??. using the dynamic subquery will take forever. I came up with more optimized approach which runs less than 8 secs..
1. Checks the orderby statement. If the sorting is based on fields that is on the same table or fields that are located in different table.
SET @strBaseTable = ( CASE
WHEN (@SortBy IS NOT NULL AND @SortBy!='') THEN
(CASE
WHEN ( @SortByFilter='ID'
OR @SortByFilter='SalesOrderTable.WholeSalerTableCode'
OR @SortByFilter= 'SalesOrderTable.HPCode'
OR @SortByFilter='SalesOrderTable.ITEM'
OR @SortByFilter='QTY'
OR @SortByFilter='OEDate' )
THEN ' SalesOrderTable'
WHEN @SortByFilter= 'a.CNAME' THEN ' SalesOrderTable INNER JOIN dbo.CustomerTable a ON dbo.SalesOrderTable.WholeSalerTableCode = a.CustomerTable '
WHEN @SortByFilter= 'a.CustomerTablePRV' THEN ' SalesOrderTable INNER JOIN dbo.CustomerTable a ON dbo.SalesOrderTable.WholeSalerTableCode = a.CustomerTable '
WHEN @SortByFilter= 'a.CustomerTableCITY' THEN ' SalesOrderTable INNER JOIN dbo.CustomerTable a ON dbo.SalesOrderTable.WholeSalerTableCode = a.CustomerTable '
WHEN @SortByFilter= 'b.CNAME' THEN ' SalesOrderTable INNER JOIN dbo.CustomerTable b ON dbo.SalesOrderTable.HPCode = b.CustomerTable '
WHEN @SortByFilter= 'b.CustomerTablePRV' THEN ' SalesOrderTable INNER JOIN dbo.CustomerTable b ON dbo.SalesOrderTable.HPCode = b.CustomerTable '
WHEN @SortByFilter= 'b.CustomerTableCITY' THEN ' SalesOrderTable INNER JOIN dbo.CustomerTable b ON dbo.SalesOrderTable.HPCode = b.CustomerTable '
WHEN @SortByFilter= 'ITEMDES' THEN ' SalesOrderTable INNER JOIN dbo.ItemTable ON dbo.SalesOrderTable.ITEM = dbo.ItemTable.ITEM '
ELSE ' SalesOrderTable '
END)
ELSE ' SalesOrderTable '
END )
2. Inserts only the ID with proper sorting to the temp table. I use #temp table because the filtering is dynamic.
--- Inserts all ID to #TempTable with sorting
SET @sql1 = 'INSERT INTO #TempTable ([ID])' +
' SELECT SalesOrderTable.[ID] FROM ' + @strBaseTable + @strFilter + @SortBy
EXEC @sql1
SET @rowCount = @@rowcount
3. Finally Get the proper data by linking all tables + temp table's ID and ROW
--- Retrieves All Information Needed
SELECT
@rowCount AS RecordCount,
dbo.SalesOrderTable.[ID],
a.CustomerTablePRV AS WholeSalerTablePrv,
a.CustomerTableCITY AS WholeSalerTableCity,
dbo.SalesOrderTable.WholeSalerTableCode,
a.CNAME AS WholeSalerTableName,
b.CustomerTablePRV AS HPPrv,
b.CustomerTableCITY AS HPCity,
dbo.SalesOrderTable.HPCode,
b.CNAME AS HPName,
dbo.SalesOrderTable.ITEM,
dbo.ItemTable.ITEMDES,
dbo.SalesOrderTable.QTY,
dbo.SalesOrderTable.OEDate,
dbo.SalesOrderTable.CFM,
dbo.SalesOrderTable.SalesID,
dbo.SalesOrderTable.InpDate
FROM dbo.SalesOrderTable
INNER JOIN dbo.CustomerTable a ON dbo.SalesOrderTable.WholeSalerTableCode = a.CustomerTable
INNER JOIN dbo.CustomerTable b ON dbo.SalesOrderTable.HPCode = b.CustomerTable
INNER JOIN dbo.ItemTable ON dbo.SalesOrderTable.ITEM = dbo.ItemTable.ITEM
INNER JOIN #TempTable t ON dbo.SalesOrderTable.[ID] = t.[ID]
WHERE (t.ROW >= @Start) AND (t.ROW <= @END)
Conclusion:
I do many test with the given scenario and I think this is the fastest approach I've ever had.
Legacy Comments
Tek Boy
2005-07-17 |
re: Pagination using Stored Procedure Any chance you could post the full stored procedure code? |