實現數據分頁查詢的方案相當多,前台和後台都有很多好方法,這些好方法都有一個共同的特點:在實現分頁的同時,考慮了網絡資源的占有問題。本文要討論的是使用SQL Server存儲過程的實現方法。
引子
在含有ID主鍵(且ID連續)的Tab表中,查找第51行到第100行數據,對應的SQL語句為:
SLECET*FROME tab WHERE ID BETWEEN 51 AND 100
如果ID不連續,或者主鍵為其他,則可以用下SQL語句實現同樣的功能:

SELECT TOP 50 * FROM tab WHERE ID NOT IN (SELECT TOP 50 ID FROM tab)
或是

SELECT TOP 50 * FROM tab WHERE ID>@lastpage_endidi
如果用變量參數控制輸入行,則使用以下語句:

SET ROWCOUNT@pagesize


SELECT * FROM tab WHERE ID>@lastpage_endid
問題
對於沒有主鍵的表,可能存在大量重復的記錄,很多SQL Server使用者喜歡用下面的語句:

SELECT IDENTITY(INT,1,1) AS ID,* INTO #T FROM tab


SELECT * FROM #T WHERE ID BETWEEN 51 AND 100
上面的方法非常笨拙,而且相當耗資源。
分析
對於這種沒有主鍵的表,要實現分頁查詢,筆者認為最好的方法是加一個IDENTITY屬性的主鍵,然後使用文本開頭使用的兩種方法,效率要高得多。在原表中加入IDENTITY屬性的語句如下:

ALTER TABLE tab ADD ID INT IDENTITY PRIMARY KEY
並不是所有用戶都有修改表的權限,下面介紹一種通用的方法:使用SQL Server 提供的儲存過程sp_cursoropen。具體用法如下:

exec sp_cursoropen @P1 output,@sqlstr


exec sp_cursorfetch @P1,16,@begincol,@pagesize


exec sp_cursorclose @P1
其中第一句的@P1為生成的游標ID,@sqlstr為定義游標的SLELECT字符串;第二句中@begincol為起始行數,@pagesize為輸出行數;第三句sp_cursorclose意即關閉游標。
解決
以下是筆者編寫的儲存過程,通過傳入表名,分頁取出第N頁數據。

Create proc getpage


(@tablename varchar (255), @page count int=1,@pagesize int=99999999)--@tablename為表名


as


begin


set nocount on


declare @P1 int


declare @sqlstr nvarchar(400)


set @pagecount =(@pagecount-1)*@pagecount+1


set @sqlstr=’select * from ’+@tablename


exec sp_cursoropen @P1 output,@sqlstr


exec sp_cursorfetch @P1,16,@pagecount,@pagesize

exec sp_cursorclose @P1


end
調用方法

exec getpage’tab’,10,100


--表名tab ,第10頁,每頁100行。
進階
以上存儲過程比較通用,不過如果適當修改一下,把@sqlstr當作轉入參數,就更靈活了,實現方法如下:

Create proc getpage


(@sqlstr nvarchar (4000),@pagecont int=1,@pagesize int=99999999)


as


begin


set nocount on


declare @P1 int


set @pagecount =(@pagecount-1)*@pagecount+1


exec sp_cursoropen @P1 output,@sqlstr


exec sp_cursorfetch @P1,16,@pagecount,@pagesize


exec sp_cursorclose @P1


end
調用方法:

exec getpage’SELECT * FROM tab WHERE條件 ’,10,100