基本上我下面要講述的側重點是如何使用,因為其實分頁預存程序網上很多,如果你懶得找,那麼可以直接使用下面這個我經過測試,並通過修改,網上評價都比較高的分頁預存程序。
這個分頁主要優點如下:
1、大容量下的資料分頁,我的測試資料是520W。
2、我結合aspnetpager控制項,使得使用起來更加方便。
3、為了結構清晰,實用3層。
4、安全,你就放心的用吧。SQL注入的問題在這裡你可以放心了。網上有文章說只要預存程序是用sql拼接的就存在sql注入的問題,並且直接在sql查詢分析器中測試了注入的情況。其實是不對的,採用預存程序和參數化的提交語句並沒有sql注入的問題。因為它進資料庫的時候會有替換的過程。
準備工作:
1、直接使用一個DB庫,資料訪問層基類,用它返回一個dataset對象,使用的時候我們只需要類似下面的語句就可以返回一個dataset對象。 複製代碼 代碼如下:sosuo8.DBUtility.DbHelperSQL.RunProcedure("pagination",parameter,"userinfo");
pagination是我在網上找的預存程序,我進行了修改的,主要是添加輸出總記錄數。這裡總記錄數也特意說一下,一般我們都是使用類似下面的語句: 複製代碼 代碼如下:select count(*) from sosuo8data
這裡我又要說兩句,網上有網友說使用count(某列),例如count(userName)會比count(*)快也是不對,如果找的列不對,那麼並不會比count(*)快。而count(*)會自動幫我們尋找可以實現最快統計的那列,而其實在使用中,一般就是我們的那個主鍵id,count(id)是最快的。
2、建立資料庫data_test,建立兩個表:
(1)、userinfo這個表用來放資料。 複製代碼 代碼如下:CREATE TABLE [dbo].[userinfo](
[id] [int] IDENTITY(1,1) NOT NULL,
[userName] [nchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[userWebName] [nchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[createDate] [datetime] NULL CONSTRAINT [DF_userinfo_createDate] DEFAULT (getdate()),
CONSTRAINT [PK_userinfo] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
id是自遞增,且是彙總索引。OK?開始往資料庫中添加520W條記錄: 複製代碼 代碼如下:--by 阿會楠 2009-4-5
set identity_insert userinfo on -- 標識可以插入自遞增列
declare @count int
declare @date datetime
set @count=1
set @date = '2009-4-5 00:00:00'
while @count<=5200000
begin
insert into userinfo(id,userName,userWebName,createDate) values(@count,'阿會楠','sosuo8.com',@date)
set @count=@count+1
set @date=@date+'00:00:01'--加一秒,避免重複,否則會造成分頁不準確的情況,排序的欄位切忌不要出現過多重複值
end
set identity_insert userinfo off
如果你的電腦配置比較一般,千萬不要嘗試,否則可能會當機;如果沒當機,那耐心等下,插入這麼多條記錄需要一點時間。
(2)tmp表用來存放無搜尋條件時的總記錄數。這裡我要說下,為什麼需要一個表用來專門存放總記錄數,總記錄數你可以在後台每隔一段時間就去更新一次,把最新的總記錄數寫進去。否則的話,520W的記錄你每次都要用count(id)那麼耗費的時間也不少。
建表的語句如下: 複製代碼 代碼如下:CREATE TABLE [dbo].[tmp](
[id] [int] IDENTITY(1,1) NOT NULL,
[rowCount_tmp] [int] NULL,
[table_tmp] [varchar](255) COLLATE Chinese_PRC_CI_AS NULL,
CONSTRAINT [PK_tmp] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
這裡不得不提一下,為什麼只要取得表的行總記錄數,而不在預存程序裡面把分頁都算好。因為我們就將採用aspnetpager這個控制項,這個控制項我們只需要傳入3個值,函數定義如下: 複製代碼 代碼如下:public DataSet GetList(int PageIndex, string strWhere,ref int rowCount)
PageIndex:當前頁,對應aspnetpager中的CurrentPageIndex
strWhere:搜尋的條件,這篇文章將不重點講搜尋部分。所以代碼中用string.Empty,大容量下的資料搜尋那需要另寫一篇文章來說明。
rowCount:總記錄數,由預存程序重新返回。