I am using FIRST and SKIP (Firebird SQL) for recordset paging to reduce the time it takes for my records to travel from the server to the client.
This works great because instead of sending thousands of records across the wire to be paged by my ASP code, only the 10, 20, 50 etc. records that are selected will be sent.
In order to calculate how many records to skip, I need to get a count of how many records are in the recordset. That means I am running a SQL statement to get the recordcount and then another SQL statement to actually get the records. There must be a way to combine these statements? Currently, I am only getting the recordcount on the first run but this won't account for newly updated transactions.
<%
'Records per page
recordsPerPage = Request("recordsPerPage")
If recordsPerPage = "" Then recordsPerPage = 10
'Current page
currentPage = Request("currentPage")
If currentPage = "" Then currentPage = 1
' Create and Open Database/Recordset Object
Call dbConn(objConn)
Call openRS(objRS)
objRS.CursorLocation = 3
objRS.CacheSize = recordsPerPage
' How many records in recordset? This is what I would like to replace/combine with following SQL statement
' Only runs on the first time through but doesn't account for new transactions
If Request("howManyRecords") = "" Then
objRS.Open "Select COUNT(AGPDR) AS howManyRecords From TABLEA", objConn
howManyRecords = objRS("howManyRecords")
objRS.Close
Else
howManyRecords = Request("howManyRecords")
End If
'Calculate records to skip
totalPages = (howManyRecords/recordsPerPage)
temp = fix(totalPages)
if totalPages-temp <> 0 then totalPages = temp+1 else totalPages=temp
numSkip = (currentPage * recordsPerPage) - recordsPerPage
If CINT(numSkip) > CINT(howManyRecords) then numSkip = howManyRecords - recordsPerPage
' Open database and retrieve records
strSQL = "Select FIRST " &CINT(recordsPerPage)& " SKIP " &CINT(numSkip)& " FIELD1, FIELD2, FIELD3 "
strSQL = strSQL & "FROM TABLEA"
objRS.Open strSQL, objConn
Do While Not objRS.EOF
%>
<tr><td colspan="3"></td></tr>
<tr>
<td><b><%=FIELD1%></a></b></td>
<td><b><%=FIELD2%></a></b></td>
<td><b><%=FIELD3%></a></b></td>
</tr>
<!-- The dropdown box for selecting the number of records to display -->
<select name="recordsPerPage" onchange="MovePage.submit()">
<option value="10">10</option>
<option value="20">20</option>
<option value="50">50</option>
</select>
<%
'Display Next / Prev buttons
If currentPage > 1 then
'Show previous buttons
Response.Write("<INPUT TYPE=BUTTON VALUE=<< ONCLICK=""document.location.href='thisPage.asp?currentPage=1&recordsPerPage="&recordsPerPage&"&howManyRecords="&howManyRecords&"';""> ")
Response.Write("<INPUT TYPE=BUTTON VALUE=< ONCLICK=""document.location.href='thisPage.asp?currentPage="¤tPage-1&"&recordsPerPage="&recordsPerPage&"&howManyRecords="&howManyRecords&"';""> ")
End If
If CInt(currentPage) <> CInt(totalPages) then
'Show next buttons
Response.Write("<INPUT TYPE=BUTTON VALUE=> ONCLICK=""document.location.href='thisPage.asp?currentPage="¤tPage+1&"&recordsPerPage="&recordsPerPage&"&howManyRecords="&howManyRecords&"';""> ")
Response.Write("<INPUT TYPE=BUTTON VALUE=>> ONCLICK=""document.location.href='thisPage.asp?currentPage="&totalPages&"&recordsPerPage="&recordsPerPage&"&howManyRecords="&howManyRecords&"';""> ")
End If
%>
Go To Page
<select name="currentPage" onchange="MovePage.submit()">
<%
' Dynamically generate page numbers
For i = 1 to totalPages
If i = CInt(currentPage) Then y = "selected" else y = ""
Response.Write "<OPTION " &y& " VALUE="&i&">" & i & "</OPTION>"
Next
%>
</select>
"I am only getting the recordcount on the first run but this won't account for newly updated transactions" - actually you won't see the new updates/insert/deletes until the transaction making those changes does a commit and then your code does a commit. Unless you are connection with autocommit on, which would be unusual.
There is no way to combine the count of rows & the rows themselves unless you use a stored procedure something like this
CREATE PROCEDURE myproc(EMP_U INTEGER)
RETURNS (recs int)
AS
select count(*) from mytable where col1 = :emp_u into :recs;
suspend; /* returns 1 row */
FOR select emp_u from mytable where col1 = :emp_u into :recs
DO
BEGIN
suspend; /* returns 1 row at a time */
end
end
is this the only solution you see to calculate how many records to skip? is there a way to put the recordcount into a variable and then use it in the same SQL statement?
in the same sql statement - no, but the approach above will only require one statement to execute it - select * from myproc(34) and could equally well be passed the first and skip parameters as well
Ready to showcase your work, publish content or promote your business online? With Squarespace’s award-winning templates and 24/7 customer service, getting started is simple. Head to Squarespace.com and use offer code ‘EXPERTS’ to get 10% off your first purchase.
There is no way to combine the count of rows & the rows themselves unless you use a stored procedure something like this
CREATE PROCEDURE myproc(EMP_U INTEGER)
RETURNS (recs int)
AS
select count(*) from mytable where col1 = :emp_u into :recs;
suspend; /* returns 1 row */
FOR select emp_u from mytable where col1 = :emp_u into :recs
DO
BEGIN
suspend; /* returns 1 row at a time */
end
end