Sometimes you cannot or do not want to use an object-relational mapping tool. When not using an OR-mapper like Hibernate or Oracle Toplink you have to deal with database specifics. One common case especially for web applications is limiting the result set to a number of items that fit nicely on a web. You then often want to allow the users to navigate between these “pages” of items aka “paging”.
This type of functionality became part of SQL only as of SQL2008 in the following form:
SELECT * FROM t WHERE ... ORDER BY c OFFSET start_row FETCH count ONLY
Since most popular database management systems (DBMSes) do not yet implement this syntax you have to implement paging in propriatory ways.
My experience with an Oracle DBMS and the frustrating and comparatively long time it took to find the correct™ solution inspired me to write this post. Now I want to present you the syntax for some widely used DBMSes which we encounter frequently in our projects.
- MySQL, H2 and PostgreSQL (< 8.4 which will also implement the SQL2008 standard) use the same syntax:
SELECT * FROM t WHERE ... ORDER BY c LIMIT count OFFSET start
- Oracle is where the fun begins. There is actually no easy and correct way of doing this. So you will end up with a mess like:
SELECT col1 FROM (SELECT col1, ROWNUM r FROM (SELECT col1 FROM table ORDER BY col1)) WHERE r BETWEEN start AND end
- DB2 AFAIK uses the syntax proposed in SQL2008 but correct me if I am wrong because we do not yet work with DB2 databases.
- As we did not need paging with MS SQLServer as of now I did not bother to look for a solution yet. Hints are very welcome.
With all solutions the ORDER BY clause is critical because SQL does not guarantee the order of the returned rows.
Wikipedia delivers some additional and special case information but does not really explain the general, real world case the specific DBMSes.
I hope that I raised some awareness about database specifics and perhaps saved you some time trying to find a solution the problem using your favorite DBMS.