Reputation: 463
I'm working on a custom DAL and am now dealing with automatic result pagination. The DAL generates dynamic queries based on our models, like:
Model.All() --> generates "select * from mytable"
Model.Filter ("d=@0", "arg0value") --> generates "select * from mytable where d=@0"
...
I don't want to add extra parameters to our filter functions, nor specialized functions for paginating (well, if it's avoidable, of course). Instead, I'd like to paginate the results changing the query before it gets executed. Something like...
var resultset = Model.Filter ("d=@0, "arg0value"); // "select * from mytable where d=@0"
resulset = resultset.Paginate (1, 25); // this should paginate the query before loading any objects
In Oracle it's easy, using the ROWNUM pseudocolumn and wrapping the old query.
select * from (my old sql) where rownum between 20 and 40
In Sql Server (2005) there's nothing like ROWNUM. I've seen there is the ROW_NUMBER function, but it requires knowing the inners of the query, as you need to pass an "OVER (ORDER BY xxxx)" clause.
select row_number() over (order By <?????>) as rownum, dv.* from (my old sql) as dv where rownum between 20 and 40
So, is there a way to perform this in Sql Server without adding specific parameters/functions to our models?
Thanks!
Edit
As @Dems says, I could parse the query and add the ORDER BY based on the output fields, but: first, I don't want the overhead of parsing, and second, if the query is of type "select *", I can't extract the fields.
Upvotes: 3
Views: 308
Reputation: 86735
If you're writing your own data access layer, and you want to apply ROW_NUMBER() only knowing the query's output field names (rather than it's internals)...
SELECT
*
FROM
(
SELECT
ROW_NUMBER() OVER (ORDER BY field1, field2, field3) AS row_id,
*
FROM
(
<your-query>
)
AS unordered_data
)
AS ordered_data
WHERE
row_id BETWEEN x AND y
Upvotes: 3