August 16, 2004 at 8:32 am
I want to create a Procedure with an input parameter e.g.
1 returns first 20 rows,
21 returns rows 21 to 40
41 returns rows 41 to 60
etc
How would I do this? I thought of having a subquery which excluded the top n rows. But would not accept a variable with the TOP clause.
August 16, 2004 at 6:26 pm
Try this one (not my script)
http://www.sqlservercentral.com/scripts/contributions/1220.asp
according to BOL, set rowcount will take a variable as its parameter.
August 16, 2004 at 9:40 pm
Stefan,
This is similar to the procedure that I use although my inputs are a little different (easy for you to modify, if you want). Instead of inputing a row number, I input the number of rows per page and the page number I want to return. Did it that way so it can be a little flexible with user settings and all. This particular procedure targets the Products table from the Northwinds database (comes with every MS-SQL installation) which has a total of 77 records in it.
I do have to warn you that it will slow down for huge tables because of the "running count" calculation. That calculation uses a "correlated subquery" (makes reference outside itself) as a derived table. It will get slower at a rate of ((X2+X)/2)-X. Let's put it this way... for tables with over 10 thousand records, it'll get sluggish. Here's the code with comments... of course, you should convert it into a stored procedure. And, you may have to change ProductID equations to the real primary key of your table and change the ORDER BY to the correct sort order of how you want the data to be displayed. Let me know if it works for you.
--===== Declare the variables that would be =====
------- used for procedure inputs
DECLARE @RowsPerPage INT
DECLARE @PageToReturn INT
--===== Declare the local variables =====
DECLARE @MyCount INT
--===== Setup to test (change the values) =====
------- Note that these would be inputs when
-- changed to a stored procedure. Comment
-- these out for production procedure.
SET @RowsPerPage = 10
SET @PageToReturn = 20
--===== Gumby proof the inputs =====
------- Check min rows per page
IF @RowsPerPage < 1
SET @RowsPerPage = 1
-------Check max rows per page
IF @RowsPerPage > 100
SET @RowsPerPage = 100
------- Check min page
IF @PageToReturn < 1 SET @PageToReturn = 1
------- Check max page
SELECT @MyCount = (SELECT COUNT(*) FROM Products)
IF @PageToReturn > @MyCount/@RowsPerPage
SET @PageToReturn = @MyCount/@RowsPerPage
--===== Set the page limit for returns
SET ROWCOUNT @RowsPerPage
--===== All set, get the page worth of data =====
SELECT *
FROM Products
WHERE ProductID IN
--This is a derived table that calculates
--a running count and returns only those
--IDs, even if they are not evenly incremented,
--that are on the page to return. The TOP
--statment is necessary to allow the ORDER BY
--in a sub-query and needs only be as large
--as the largest number of rows you ever intend
--to display on a single page
(
SELECT TOP 100 t2.ProductID
FROM Products t2
WHERE (
SELECT COUNT(*)
FROM Products t1
WHERE t1.ProductID <= t2.ProductID
) >= @PageToReturn * @RowsPerPage
ORDER BY t2.ProductID
)
ORDER BY ProductID
--Note that TOP n cannot have a variable for "n" which
--is why we had to go through all this stuff.
--Jeff Moden
Change is inevitable... Change for the better is not.
August 17, 2004 at 5:01 am
Many thanks for the replies. I did manage to work it out using a dynamic query but the examples provided are likely to be much more efficient so I have rewritten the code.
The query I have is quite complex but as I can use a primary field in descending order and adapted version of the first example works great for me!
Thanks again
Viewing 4 posts - 1 through 3 (of 3 total)
You must be logged in to reply to this topic. Login to reply