![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
I need to do a query and limit it to returning 10 rows at a time. I can't rely on dynamic cursors or anything like that because I can't keep a cursor open between each query. I know I can use "SELECT TOP 10" in my SQL statement to get the first 10. But after that, is there any easy way to get rows 11 to 20 (the next 10)? If my query had a simple ORDER BY I know one way I could solve the problem. For example, if it was "ORDER BY ID", then I would just include "WHERE ID > X" (X would be the highest ID returned in the previous query). However, my ORDER BY includes 4 fields, so I think I would need something pretty messy like this: WHERE FIELD1 > X OR (FIELD1 = X AND FIELD2 > X) OR (FIELD1 = X AND FIELD2 = X AND FIELD3 > X).... etc... etc... And I think it would get pretty long to include all of the actual cases. I'm writing a winsock server that uses ADO to read from an Access 2000 database and return certain data to clients. I have too many clients to keep open cursors just incase they request the next 10 records. I do have the option of switching the database, if there is an easier way to do this type of query using MSSQL, or a newer version of Access. I'd prefer to stay with Access or MSSQL though. Let me know if you need more higher-level details. |
#3
| |||
| |||
|
#4
| |||
| |||
|
|
I need to do a query and limit it to returning 10 rows at a time. I can't rely on dynamic cursors or anything like that because I can't keep a cursor open between each query. I know I can use "SELECT TOP 10" in my SQL statement to get the first 10. But after that, is there any easy way to get rows 11 to 20 (the next 10)? If my query had a simple ORDER BY I know one way I could solve the problem. For example, if it was "ORDER BY ID", then I would just include "WHERE ID > X" (X would be the highest ID returned in the previous query). However, my ORDER BY includes 4 fields, so I think I would need something pretty messy like this: WHERE FIELD1 > X OR (FIELD1 = X AND FIELD2 > X) OR (FIELD1 = X AND FIELD2 = X AND FIELD3 > X).... etc... etc... And I think it would get pretty long to include all of the actual cases. I'm writing a winsock server that uses ADO to read from an Access 2000 database and return certain data to clients. I have too many clients to keep open cursors just incase they request the next 10 records. I do have the option of switching the database, if there is an easier way to do this type of query using MSSQL, or a newer version of Access. I'd prefer to stay with Access or MSSQL though. Let me know if you need more higher-level details. |
#5
| |||
| |||
|
#6
| ||||
| ||||
|
|
It sounds like you have a web based client application. |
|
If a customer wants to look at a list of books that start with the letter "B" you can select the top 10 rows from a set where Books Like 'B%' Select Top 10 * From tbl1 Where Books Like 'B%' Order By RowID |
|
Then store the highest RowID from this set and store that value in a variable in the client app -- I will use intRowID for the variable. Then when the customer wants to look at the next 10 items your sql will look like this: Select Top 10 * from tbl1 Where Books Like 'B%' And RowID > intRowID Order By RowID |
|
Another option that would be even easier (in the long run) would be to step up your whole project to ASP.Net. |
#7
| |||
| |||
|
|
es... (AT) surfbest (DOT) net wrote: I need to do a query and limit it to returning 10 rows at a time. I can't rely on dynamic cursors or anything like that because I can't keep a cursor open between each query. There probably is a better way but what the heck. I'm using DAO, not ADO. I created a function called GetID(). It basically opens a table, moves to the "next 10" first record. It then gets the ids for the 10 records (primary key...in my case an autonumber) of this group and returns to the sub Get10s() the 10 id numbers. Anyway, here's my sample routines....with minimal error checking Function GetID(lngNum As Long) As String Dim rst As Recordset Dim strID As String Dim intCnt As Integer Set rst = CurrentDb.OpenRecordset("Table1", dbOpenSnapshot) rst.MoveFirst rst.Move lngNum - 1 |
#8
| |||
| |||
|
#9
| |||
| |||
|
|
One other trick would be to use TempDB, but that requires a server based database. First you select your Top 10 * where Author like ? and book like ? and yearPublished = ? Order By RowID This set will contain only the records that meet your criteria but still get ordered by RowID Then you store that result in a #tmp table in TempDB Create Table #tmp1(Author varchar(50), Title varchar(50)... RowID int) Now you can order this set any way you like and you can still pick out the max RowID. So for the next selection you can start from max(RowID) + 1 As you can see, there are plenty of options for your web app and plenty of tools. Access just doesn't happen to be the tool of choice for these kinds of operations. Java is also quite popular because it is not proprietary like .Net. But for EASE Of USE for more sophisticated operations like yours -- as long as you are using Microsoft technology, nothing can beat .Net with sql Server (specifically VB.Net -- ASP.Net with VB.Net). I could go on, but that would be a topic for a .Net forum. Rich |
#10
| |||||
| |||||
|
|
On Nov 27, 2:09 pm, Salad <o... (AT) vinegar (DOT) com> wrote: es... (AT) surfbest (DOT) net wrote: I need to do a query and limit it to returning 10 rows at a time. I can't rely on dynamic cursors or anything like that because I can't keep a cursor open between each query. There probably is a better way but what the heck. I'm using DAO, not ADO. I created a function called GetID(). It basically opens a table, moves to the "next 10" first record. It then gets the ids for the 10 records (primary key...in my case an autonumber) of this group and returns to the sub Get10s() the 10 id numbers. Anyway, here's my sample routines....with minimal error checking Function GetID(lngNum As Long) As String Dim rst As Recordset Dim strID As String Dim intCnt As Integer Set rst = CurrentDb.OpenRecordset("Table1", dbOpenSnapshot) rst.MoveFirst rst.Move lngNum - 1 I think those 3 lines above would be too slow in my case. Lets assume "Table1" has 100,000 records, and you need the last 10. Either the call to OpenRecordset, or that call to Move, is going to be really slow. |
|
think it would be the call to OpenRecordset since it makes a snapshot of the entire table to work with. If you switched to a dynamic (keyset?) recordset, then I think it would be the call to Move that would be slow because it would take a long time to locate that record number. Is that not correct? |
|
your recordset is sorted? In my case my recordset has an ORDER BY with 4 fields. |
|
think it would help, I still think it will take a long time to locate (Move to) record 99,990. |
|
minus 1 is, there should be a way I can use that to my advantage (but hopefully without a super long SQL statement). |
![]() |
| Thread Tools | |
| Display Modes | |
| |