在實際開發的過程中如果記錄數非常的龐大,如果直接用SQL語句查詢並填充到DataTable中,將是一件非常恐怖的事情。而且對網站性能,服務器性能消耗很大。
兩個常犯的錯誤:
1)在現實數據時,查詢時會將所有的滿足條件的數據全部填充到DataTable中,然后在程序中根據條件顯示其中的一部分數據。
2)在統計數據時,在獲取符合條件的記錄條數時也是通過將所有滿足條件的數據全部填充到DataTable中,然后通過DataTable實例Rows.Count屬性來獲取記錄條數。
這樣做的結果就是效率極低,如果數據量太大,可能造成自己需要的數據長久的無法顯示,所以顯示數據是應該使用分頁查詢。分頁查詢就是每次只返回所需要的數據,而不用每次都從數據庫中把數據全部提出來,這樣可以降低程序與數據庫之間的數據傳送量,並且還可以提高程序的性能。
一般來說,在數據量大的情況下要分頁顯示,這樣決定返回的查詢結果集的參數有兩個:當前顯示的頁數pageIndex和每頁顯示的記錄條數size。
所使用的數據表如下圖:表中的id是主鍵。
下面我們按照id正序排列查詢所有人的信息,SQL語句如下:
select * from T_Person order by id ASC;
現在我們對數據進行分頁,分頁規則就是,頁容量5條數據,那么我們完成第1頁的數據查詢可以使用SQL語句是:
select top 5 * from T_Person order by id asc;
這樣我們就可以取出第1頁所要顯示的5條數據。但是我們應該怎么樣編寫SQL語句才可以顯示第2,3,4......頁的數據呢?
如果說我們第1頁取出的數據時第1-5條記錄,那么第2頁的數據就應該是6-10的記錄。我們應該怎么做到呢?有兩種方法:第一種就是一次性的將所有的數據都提取出填充到DataTable中,然后在for循環中通過i從5開始,並且i小於10這種方法顯示數據,這種方法的缺點前面已經介紹。第二種方法就是在數據庫中對數據進行過濾,這個時候SQL語句中的 not in 就可以很好地排上用場。
那么怎么使用not in將第2頁的數據顯示出來呢,SQL語句如下:

1 select top 5 * from T_Person where id not in 2 ( 3 select top 5 id from T_Person order by id asc 4 )order by id asc;
在這里使用了一個子查詢先將第1頁的數據編號顯示出來,然后使用not in 將1-5的記錄從數據中排出,顯示的就是6-10 的數據記錄。
因為數據id是從1開始,所以id為1-5的記錄顯示在第1頁,id為6-10的記錄在第2頁顯示,id為11-15的記錄在第3頁顯示,依此類推第n頁的數據的SQL語句是:n為定義顯示數據的第幾頁,
1 select top 5 * from T_Person where id not in 2 ( 3 select top (n-1)5 id from T_Person order by id asc 4 )order by id asc;
這樣就可以根據參數n顯示第幾頁的數據。
還有一個比較重要的知識點就是如何計算數據頁分頁的總數,如果現在有20條數據,如果每頁5條數據,很明顯就是分4頁。但是如果記錄數是21條,這個時候很明顯應該分5頁。有一個公式,假如總共有m條數據,每頁顯示n條數據(m,n都大於0),那么需要顯示所有記錄的頁數page為:page=(m%n)==0?(m/n):(m/n+1);
第二種分頁的方法:
這里需要使用SQL中的ROW_NUMBER函數,該函數的作用就是在返回的記錄集合內為每一條記錄標上順序編號。
因為我們要對數據庫進行刪除操作的話,數據庫表中的id的值可能是不連續的。因為在上面的方法中,我們主要是使用id來排序,不需要太多的操作,但是下面的方法,就需要有一個連續的id值來查詢數據。
先看一個SQL語句:
1 select * from 2 ( 3 select * from T_Person 4 )as a 5 where id>5 and id<=10
這樣的話,我們仍然能夠按照要求取出相應頁數的數據。我們只需要稍微改變一下,SQL語句如下:n為顯示數據的頁碼
1 select * from 2 ( 3 select * from T_Person 4 )as a 5 where id>(n-1)*5 and id<=n*5
這個時候我們就可以根據參數n來選出相應頁數的數據,但是我們可以很快的發現,這個分頁對id的連續有很大的依賴性,所以,我們在對數據進行刪除操作的時候,數據庫中的id很可能是不連續的,所以在數據庫中進行分頁的時候,就需要對數據進行編號,這個時候就要使用SQl中的ROW_NUMBER函數,
使用ROW_NUMBER函數查詢的SQl語句和顯示結果如下:
很容易的我們發現在id的前面有了一個按照id正序排列的rl的列。
所以,完整的 SQL分頁語句為:n為我們傳入的分頁的頁碼,默認的每頁顯示的數據位5條
1 select * from 2 ( 3 select * from T_Person 4 )as a 5 where id>(n-1)*5 and id<=n*5
這樣,我們就可以建立相應的分頁存儲過程,在數據庫中對數據進行分頁,然后供程序進行調用。
最后分享一個,在網上看到的一個比較好的分頁存儲過程:
1 create PROCEDURE GetPageData 2 ( 3 @TableName varchar(30),--表名稱 4 @IDName varchar(20),--表主鍵名稱 5 @PageIndex int,--當前頁數 6 @PageSize int--每頁大小 7 ) 8 AS 9 IF @PageIndex > 0 10 BEGIN 11 set nocount on 12 DECLARE @PageLowerBound int,@StartID int,@sql nvarchar(225) 13 SET @PageLowerBound = @PageSize * (@PageIndex-1) 14 IF @PageLowerBound<1 15 SET @PageLowerBound=1 16 SET ROWCOUNT @PageLowerBound 17 SET @sql=N'SELECT @StartID = ['+@IDName+'] FROM '+@TableName+' ORDER BY '+@IDName 18 exec sp_executesql @sql,N'@StartID int output',@StartID output 19 SET ROWCOUNT 0 20 SET @sql='select top '+str(@PageSize) +' * from '+@TableName+' where ['+@IDName+']>='+ str(@StartID) +' ORDER BY ['+@IDName+'] ' 21 EXEC(@sql) 22 set nocount off 23 END