Hej å glad midsommar! Hello, hello i midsommar aftons natten .... Jag föreslår att du gör 'paging' i databasen istället för i recordsetet. Om du t ex endast vill ha 10 rader ur en tabell med 100 000 rader är det ju faktiskt ganska onödigt (för att inte säga oanvändbart) att hämta alla raderna. Kolla länken nedan för att se hur man kan göra detta i databasen istället:10 nästa->
Jag börjar med att lista de tio poster i mitt recordset, såväl allt lugnt! Men jag vill även med hjälp av pillänkar kunna lista nästa tio samt de tio posterna före. Hur gör jag smidigast för att lösa detta. Alltså hur förflyttar jag mig i recordsetet, finns det något smart sätt för att kunna possitionera sig i recordsetet?
Tack!Sv: 10 nästa->
Ok, då börjar vi den "lååååånga" vandringen mot en recordset delning eller som det brukar kallas, PAGING.
För att dela upp ett recordset på flera sidor är det ett par saker vi först måste veta innan vi kan gå vidare.
Dessa saker är:
1: Hur många poster från recordsetet som ska visas per sida
2: Vilken sida som ska visas
Nu vet vi vad som behövs för att kunna bläddra oss framåt och bakåt i recordsetet.
Anta att vi nu har en databas, en enkel gästbok, med denna tabell och fält:
[TBL_INLAGG]
- FLD_ID
- FLD_NAMN
- FLD_INLAGG
- FLD_DATUM
Vi börjar med att skapa connection objektet och ett standard ADODB.Recordset för att kunna lista alla poster.
OBS!! har tagit bort all html-kod nästan för den är ovidkommande för detta inlägg.
visaInlagg.asp
================
<%
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & Server.MapPath("/db-dir/db-file.mdb")
strSQL = "SELECT FLD_NAMN, FLD_INLAGG, FLD_DATUM " & _
"FROM TBL_INLAGG " & _
"ORDER BY FLD_DATUM DESC"
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.Open strSQL, objConn
If objRS.EOF Then
Response.Write "Inga poster hittades"
Else
Do Until objRS.EOF
strNamn = objRS("FLD_NAMN")
strInlagg = objRS("FLD_INLAGG")
dteDatum = objRS("FLD_DATUM")
Response.Write "<P>Namn: " & strNamn & "<BR>" & _
"Datum: " & dteDatum & "<BR>" & _
"Inlägg:<BR>" & strInlagg & "</P>"
objRS.MoveNext
Loop
End If
objRS.Close
Set objRS = Nothing
objConn.Close
Set objConn = Nothing
%>
Koden ovan listar alla poster från databasen sorterade efter datum, fallande, på en och samma sida.
Vi går nu vidare med att plocka in de variabler som vi behöver för att kunna kontrollera recordsetet så att endast n-antal poster visas per sida och vilken sida som ska visas.
För att kunna kontrollera vilken sida vi är på behöver vi skicka med en QueryString som vi kan fånga upp som talar om vilken sida som ska visas. Jag kommer att kalla den QueryStringen för - page.
Överst på sidan lägger vi nu till detta:
'## -- vilken sida ska visas --
intPage = Request.QueryString("page")
'## -- kontrollera att det finns något i intPage
'## Om det inte finns någon qs så ska första sidan visas --
If intPage = "" then intPage = 1
'## -- hur många poster ska visas per sida --
intPageSize = 10
Vi går vidare och manipulerar lite med recordset objektet.
Kommer att använda mig av ett par extra metoder som finns i ADODB.Recordset objektet:
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.CacheSize = intPageSize
'## -- hur många poster per sida ska visas --
objRS.PageSize = intPageSize
'## -- märk här att jag öppnar recordsetet statiskt, readonly --
objRS.Open strSQL, objConn, 3, 1
If Not objRS.EOF Then
'## -- vilken sida i recordsetet ska visas --
objRS.AbsolutePage = intPage
End If
'## -- hur många sidor innehåller recordsetet --
intTotalPages = objRS.PageCount
Om vi nu kör koden så kommer ni att se att alla poster fortfarande kommer att visas.
Vi behöver även ändra denna rad:
Do Until objRS.EOF
till dessa:
Do Until objRS.EOF or intCount >= intPageSize
intCount = intCount + 1
Det jag nu la till är en räknare som håller koll på hur många poster som visats.
Nu kommer det att listas poster antingen till intCount har räknats upp till intPageSize eller om det inte finns fler poster att visas.
Om vi nu kör så kommer endast, i detta fall, 10 poster att visas eftersom jag har satt intPageSize = 10
Det vi nu behöver är själva bläddrings länkarna som styr oss genom recordsetet/sidorna.
För dessa gjorde jag 2 olika subbar, en som styr länkningen till nästa sida och den andra som styr länkningen till föregående sida.
Märk att det är på dessa länkar jag lägger in min QueryString - page för att kunna kontrollera vilken sida som ska visas, nästa eller föregående.
Dessa subbar läggs in överst på sidan.
<%
'## -- skriver ut en länk till nästa sida om sidan som ska visas
'## är 1 eller större men skriver inte ut en länk till
'## sidan om det är sista sidan som ska visas --
Sub nextPage(ByVal iWichPage, ByVal iTotalPages, ByVal sLinkTo)
If CInt(iWichPage) >= 1 AND CInt(iWichPage) < CInt(iTotalPages) Then
Response.Write ""?page=" & iWichPage + 1 & """>Nästa >>"
Else
Response.Write "Nästa >>"
End If
End Sub
'## -- skriver ut en länk till föregående sida om sidan som ska visas
'## inte är större än första sidan --
Sub prevPage(ByVal iWichPage, ByVal sLinkTo)
If iWichPage > 1 Then
Response.Write ""?page=" & iWichPage - 1 & """><< Föregående"
Else
Response.Write "<< Föregående"
End If
End Sub
%>
DEt vi nu behöver göra för att få fram dessa länkar där vi vill ha dem är att anropa dessa två subbar och passa in variablerna för vilken sida som ska visas, hur många sidor det finns i recordsetet och till vilken sida som själva länken ska gå till, (samma sida).
<%
Call prevPage(intPage, "min_sida.asp")
'## -- skriv ut en separator mellan länkarna --
Response.Write " | "
Call nextPage(intPage, intTotalPages, "min_sida.asp")
%>
Nu borde hela din kod se ut något så här:
<%
Option Explicit
Response.Buffer = TRUE
'===============================================================================
'## -- funktioner och subbar startar här --
'===============================================================================
'## -- skriver ut en länk till nästa sida om sidan som ska visas
'## är 1 eller större men skriver inte ut en länk till
'## sidan om det är sista sidan som ska visas --
Sub nextPage(ByVal iWichPage, ByVal iTotalPages, ByVal sLinkTo)
If CInt(iWichPage) >= 1 AND CInt(iWichPage) < CInt(iTotalPages) Then
Response.Write ""?page=" & iWichPage + 1 & """>Next >>"
Else
Response.Write "Next >>"
End If
End Sub
'## -- skriver ut en länk till föregående sida om sidan som ska visas
'## inte är större än första sidan --
Sub prevPage(ByVal iWichPage, ByVal sLinkTo)
If iWichPage > 1 Then
Response.Write ""?page=" & iWichPage - 1 & """><< Previous"
Else
Response.Write "<< Previous"
End If
End Sub
'===============================================================================
'## -- funktioner och subbar slutar här --
'===============================================================================
Dim strConnString, strSQL, strNamn, strScriptName, strInlagg
Dim dteDatum
Dim objConn, objRS
Dim intPage, intPageSize, intTotalRecords, intTotalPages
Dim intCount
'===============================================================================
'## -- till vilken sida ska pagingen gå till --
strScriptName = Request.ServerVariables("SCRIPT_NAME")
'## -- kolla vilken sida som ska visas --
intPage = Request.QueryString("page")
If intPage = "" Then intPage = 1
'## -- hur många poster ska visas på varje sida --
intPageSize = 10
%>
<HTML>
<HEAD>
<TITLE>Paging - hur gör man en sådan?</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</HEAD>
<BODY bgcolor="#FFFFFF" text="#000000">
<%
'## -- provider & sökväg till db, DSN etc. --
strConnString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & Server.MapPath("/paging/guest1.mdb")
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConnString
'## -- sql-fråga för att hämta poster från databasen --
strSQL = "SELECT FLD_NAMN, FLD_INLAGG, FLD_DATUM " & _
"FROM TBL_INLAGG " & _
"ORDER BY FLD_DATUM DESC"
'## -- skapa ett recordset och returnera alla poster --
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.CacheSize = intPageSize
'## -- hur många poster ska varje sida innehålla --
objRS.PageSize = intPageSize
objRS.Open strSQL, objConn, 3, 1
If Not objRS.EOF Then
'## -- vilken sida i recordsetet ska visas --
objRS.AbsolutePage = intPage
End If
'## -- hur många sidor består recordsetet av --
intTotalPages = objRS.PageCount
If objRS.EOF Then
Response.Write "Inga poster hittades."
Else
Do Until objRS.EOF or intCount >= intPageSize
intCount = intCount + 1
strNamn = objRS("FLD_NAMN")
strInlagg = objrS("FLD_INLAGG")
dteDatum = objRS("FLD_DATUM")
'## -- printa ut till användaren --
Response.Write "<P>Namn: " & strNamn & ",<BR>Datum: " & dteDatum & _
"Inlägg:<BR>" & strInlagg & "</P>"
objRS.MoveNext
Loop '## -- nästa post att visa --
End If
'## -- clean up --
objRS.Close
Set objRS = Nothing
objConn.Close
Set objConn = Nothing
response.write "<p align=""center""><B>Page navigation:</B><BR>"
'## -- skriv ut föregående --
Call prevPage(intPage, strScriptName)
Response.Write " | "
'## -- skriv ut nästa --
Call nextPage(intPage, intTotalPages, strScriptName)
%>
</BODY>
</HTML>
Hoppsan, va inte meningen med att det skulle bli en heeeel artikel av detta inlägg, men .... fick lite tid över då det var nattning av ungarna som härjat runt en hel del nu under kvällen. =P
Notera att detta är skrivet direkt ur huvudet och ej kollat att det funkar, men det bööör funka.
Hoppas att allt detta svammel hjälper dig lite på traven.
cya,
PatrikB a.k.a mrWize
PS ... har en fullt fungeradne paging för de som kör chilliASP! oxå ... DSSv: 10 nästa->
http://hedgate.editthispage.com/2001/04/30