在實際過運用過程中,我們開發的項目有時需要支持多種數據庫,那麼在開發中我們會遇到不同的數據庫在SQL語句方面還有區別,導致我們有些細節需要去調整,下面就分頁功能在不同的數據庫中的具體使用詳細說明。
一、Access數據庫分頁與效率分析
由於Access操作簡單,調用,遷移方便,節省費用,對於搭建者的能力要求也會低些,對於較小量的數據,我們使用Access數據庫是比較適合的,但是隨着數據量增加,達到幾十萬、幾百萬甚至更多的時候,那麼數據庫的效率就會出現問題了,這個時候比如像分頁功能可能就出現問題了,下面我們就看看常見的Access分頁有哪些方式?
方案一:使用ADO.NET本身的結果集,使用PageSize,AbsolutePage的屬性來進行分頁
當然我一般不推薦使用拖控件進行快速開發,拖控件會導致產生大量的垃圾代碼,是網站效率低下,當然在後臺可以使用部分控件,今天就不說.NET拖控件效率低下的問題了,使用ADO.NE的結果集方式,每次都要讀入符合條件的所有記錄,然後再定位於對應頁的記錄。當數據量大的時候,效率就十分的低下。
方案二:使用not in 方式
select top 3 * from Article where Id not in(select top 6 Id from Article)
使用not in 方式,其中的top效率很高,但是not in 呢? 測試發現,當數據量比較小時還是挺快的,但是當到達10萬條數據是,單擊查詢就慢了,如果使用該分頁方式,當數據量很大時,估計天天有人在罵:這是哪個SB開發的系統啊,這麼垃圾!
方案三:使用select top pageSize * from (select top pageindex*pageSize * from ywgl_news order by id desc) order by id
在實際過程中發現,當數據量比較大是,使用這種方式分頁,Access的效率還可以,比not in 方式效率高多了,但是此處也需要注意的是:很多人喜歡使用select * from 表名, 實際中發現這不是一個好習慣,我們應該需要什麼字段查詢什麼字段,這樣能夠極大的節省服務器資源。
二、MSSQL Server和Oracle數據庫的分頁
當然MSSQL Server和Oracle數據庫的分頁可以選擇的方式更多,除了使用ADO.NET數據集、Not in 方式、Select top方式外,還有row_number方式等更好的分頁實現方式,
select * from
(select * ,row_number() over(order by Id) rownumber from T_Users) as t
where t.rownumber>4 and t.rownumber<=6
需要注意的是:在MSSQL Server和Oracle中使用row_number還有些細節不同,下面就是Oracle和MS SqlServer中的具體分頁方式:
int start = (pageindex - 1) * pageSize;
int end = pageindex * pageSize;
Oracle的分頁T-SQL語句:
string sql = "select * from(select a.*,rownum row_num from(select * from ywgl_news t {0} order by t.Id desc) a)b where b.row_num>" + start.ToString() + " and b.row_num<=" + end.ToString() + "";
MSSQL Server的分頁T-SQL語句:
string sql = "select * from(select * ,row_number() over(order by Id) rownumber from ywgl_news {0}) as t where t.rownumber>"+start.ToString()+" and t.rownumber<="+end;
三、附錄存儲過程的寫法(MSSQL SERVER爲例)
--創建存儲過程row_number方式
alter proc GetPageForRownumber
(
@pageIndex int,--當前頁
@pageSize int,--頁容量
@rowCount int out,--總行數
@pageCount int out --總頁數
)
as
begin
declare @sql nvarchar(225)
select @rowCount=count(Id),@pageCount=ceiling((count(Id)+0.0)/@pageSize) from T_Users
set @sql='select * from
(select * ,row_number() over(order by Id) rownumber from T_Users) as t
where t.rownumber>'+str((@pageIndex-1)*@pageSize)+' and t.rownumber<='+str(@pageIndex*@pageSize)+''
exec(@sql)
end
---測試row_number 方式的存儲過程
declare @rc int,@pc int
exec GetPageForRownumber 3,2,@rc out,@pc out
select @rc,@pc
四、開發中遇到的小問題
1、報錯"標準表達式中數據類型不匹配。"
Access在進行參數化查詢的時候老是報錯,這讓哥很納悶啊,看着SQL語句也是對的,參數的值也是對的,爲什麼老是提示報錯呢?如下圖代碼就會報該錯誤。
string sql = "UPDATE ywgl_News set
New_Title=@New_Title, New_Source=@New_Source ,New_ReadCount=@New_ReadCount,New_Content=@New_Content,New_Summary=@New_Summary,New_Author=@New_Author,New_ClassId=@New_ClassId
where Id=@Id";
OleDbParameter[] para = new OleDbParameter[]
{
new OleDbParameter("@Id",model.New_id),
new OleDbParameter("@New_Title",ToDBValue(model.New_title)),
new OleDbParameter("@New_Source",ToDBValue(model.New_source)),
new OleDbParameter("@New_ReadCount",ToDBValue(model.New_readcount)),
new OleDbParameter("@New_Content",ToDBValue(model.New_content)),
new OleDbParameter("@New_Summary",ToDBValue(model.New_summary)),
new OleDbParameter("@New_Author", ToDBValue(model.New_author)),
new OleDbParameter("@New_ClassId",ToDBValue(model.New_class.Id))
};
num = AccessHelper.ExecuteNonQuery(sql, para);
經過查找原因,原來問題出在”@“符號上了,我們可以用”?“佔位符替換,這個MSSQL Server有點小不同,如果使用了”@“那麼就要確保各個參數的順序一致。否則就報該錯誤。
2、在刪除操作時刪除不了
各個數據庫具體T-SQL語句還有些不同,在Oracle中中 string sql = "Delete ywgl_news where Id=:Id";可以刪除,沒問題,但是在Access中這樣寫就不行了應該這樣寫:
string sql = "Delete from ywgl_news where
Id=@Id";
五、總結三種不同數據庫的分頁方式及效率
那麼我們在實際應用中,到底該選擇哪種類型的數據庫呢?使用Access,還是MSSQL Server,還是Oracle?不要覺得Oracle就覺得你的系統很牛B,這個需要根據系統的定位和使用者來進行確定,如果說是一個很小的政府門戶網站,數據量也很小,那麼用一個Access完全夠了,而且數據量很小的時候,Access的速度還更快,當然如果說是做GIS的國土數據整合系統,那像這樣的海量的數據,那就肯定需要用像Oracle大型數據庫了。