分頁|資料|資料庫 一:一個老生常談的問題。
我們知道,記錄集分頁是資料庫處理中十分常見的問題。而當我們設計到網路資料庫,就是說要考慮傳輸頻寬問題時,分頁問題就每每困擾著每一個資料庫程式設計人員。
二:分頁問題的解決方案匯總
說起解決的方案,每個資料庫設計人員可能都會舉出許多方法。但細分後,可以歸為三類。一:Ado紀錄集分頁、二:專儲記錄集分頁、三、資料庫遊標分頁。
一:著名的ADO紀錄集分頁。
說到著名,因為這個可能是最簡單和常見的分頁方法了。(可能也是用的最多的)就是利用ADO內建的分頁功能來實現分頁。
具體流程為,資料庫根據查詢語句返回一個完整的紀錄集。然後到用戶端後有用戶端的遊標進行分頁。他們大多數由ADO內建的Recordset對象就可以實現了。可能涉及到的屬性有:
recordset.pagesize:每頁輸出紀錄集的大小
recordset.AbsolutePage: 當前輸出的頁 (有以上的兩個屬性其實就可以完成分頁輸出了)
recordset.pagecount: 目前的總頁數。
這種方法好不好呢,有的人說是十分好,也有人說效率不高。其實這的根據實際的應用狀況來確定,如果是單機資料庫,或者是區域網路環境,或者資料庫紀錄較少,則他都是很好的分頁方法,而且如果不涉及到網路和更新較少的環境裡,則他可以說是最好的分頁方法。因為它可以先產生一個緩衝記錄集,以後的幾頁紀錄都可以不通過資料庫來取即可。但是,如果涉及到網路,或者是更新頻繁。他就不是很實用的了。
列舉程式。(我們都用網路問題來考慮)
nowpage=Request("nowpage") '當前的輸出頁
if nowpage="" or nowpage<1 then nowpage=1
set rs=server.CreateObject("adodb.recordset")
rs.CursorType=1
sql="select * from table1 "
rs.open sql,strconn (strconn為串連欄位,已定義過)
rs.PageSize=20 '當前頁的大小
if cint(nowpage)>rs.pagecount then nowpage=rs.pagecount
rs.AbsolutePage=nowpage
'然後輸出當前一頁的紀錄
'.............
還可以提供一下程式屬性設定。
首頁:nowpage=1
前頁:nowpage=nowpage-1
下頁:nowpage=nowpage+1
尾頁:nowpage=rs.pagecount
總紀錄數:rs.recordcount
總頁數:rs.pagecount
二:轉儲紀錄集分頁。
這種方法誕生於網路時代,就是利用伺服器端的強大處理過程,先將目標資料庫存到一個臨時的資料庫裡,並且加上一個自增欄位來進行劃分頁面,最後將所需固定數目的紀錄集傳回。
優點是:只需互動一次,而且返回固定一頁的紀錄集。
缺點是:如果紀錄集增大時則每次都需建立一個臨時紀錄集,也比較耗時間,但減少了網路傳輸量。
例子:
(
取自 Worx 英文版的<<Professional Active Server Pages 3.0>>
ISBN1861002610
關鍵地方我已作了中文翻譯
)
CREATE PROCEDURE usp_PagedAuthors
@iPage int,
@iPageSize int
AS
BEGIN
-- disable row counts
SET NOCOUNT ON
-- declare variables
DECLARE @iStart int -- start record
DECLARE @iEnd int -- end record
DECLARE @iPageCount int -- total number of pages
-- create the temporary table
--建立暫存資料表。
CREATE TABLE #PagedAuthors (
--這個自增欄位十分關鍵,就是靠他來完成分頁標示。
ID int IDENTITY,
au_id varchar(11) NOT NULL ,
au_lname varchar(40) NOT NULL ,
au_fname varchar(20) NOT NULL ,
phone char(12) NOT NULL ,
address varchar(40) NULL ,
city varchar(20) NULL ,
state char(2) NULL ,
zip char(5) NULL ,
contract bit NOT NULL
)
-- populate the temporary table
--先轉存到上面的這個紀錄集。
INSERT INTO #PagedAuthors (au_id, au_lname, au_fname,
phone, address, city, state, zip, contract)
SELECT au_id, au_lname, au_fname,
phone, address, city, state, zip, contract
FROM authors
-- work out how many pages there are in total
SELECT @iPageCount = COUNT(*)
FROM authors
SELECT @iPageCount = CEILING(@iPageCount / @iPageSize) + 1
-- check the page number
IF @iPage < 1
SELECT @iPage = 1
IF @iPage > @iPageCount
SELECT @iPage = @iPageCount
-- calculate the start and end records
SELECT @iStart = (@iPage - 1) * @iPageSize
SELECT @iEnd = @iStart + @iPageSize + 1
-- select only those records that fall within our page
--這條sql語句就是選取固定的紀錄集。
SELECT au_id, au_lname, au_fname,
phone, address, city, state, zip, contract
FROM #PagedAuthors
WHERE ID > @iStart
AND ID < @iEnd
DROP TABLE #PagedAuthors
-- turn back on record counts
SET NOCOUNT OFF
-- Return the number of records left
RETURN @iPageCount
END
而輸出端可以用最快類型的ADO"火線游標"順次輸出就可
<%
Dim cmdAuthors
Dim rsData
Dim iPage
Dim iLastPage
Dim sQuote
sQuote = Chr(34)
' get the requested data
If Request.QueryString("PAGE") = "" Then
iPage = 1
Else
iPage = CInt(Request.QueryString("PAGE"))
If iPage < 1 Then
iPage = 1
End If
End If
' create the objects
Set cmdAuthors = Server.CreateObject("ADODB.Command")
Set rsAuthors = Server.CreateObject("ADODB.Recordset")
With cmdAuthors
.ActiveConnection = strConn
.CommandText = "usp_PagedAuthors"
.CommandType = adCmdStoredProc
.Parameters.Append .CreateParameter("RETURN_VALUE", adInteger, _
adParamReturnValue)
.Par