asp.net 安全、實用、簡單的大容量存儲過程分頁第2/2頁
更新時間:2009年06月19日 23:52:57 作者:
昨晚研究到2點多,對網(wǎng)絡上主流的分頁存儲過程大體看了一遍,但對安全以及如何使用很多文章都沒有過多的提及,而我要在這些文章的基礎上總結出一個比較實用的分頁存儲過程,方便大家在以后的項目中使用。
開始測試:
在BLL層(業(yè)務邏輯層),DAL層(數(shù)據(jù)訪問層),DB(訪問層基類),WEB(網(wǎng)站),關于3層結構這里就不介紹了,大家可以看看我前面寫過的文章《.net三層結構初探》 。
先添加存儲過程:
復制代碼 代碼如下:
--阿會楠根據(jù)網(wǎng)絡上的代碼進行了修改,版權歸原作者所有2009-4-5
--修改輸出總記錄數(shù)
create PROCEDURE [dbo].[pagination]
@tblName varchar(255), -- 表名
@strGetFields varchar(1000), -- 需要返回的列
@fldName varchar(255), -- 排序的字段名
@PageSize int, -- 頁尺寸
@PageIndex int, -- 頁碼
@OrderType bit, -- 設置排序類型, 非 0 值則降序
@strWhere varchar(1500), -- 查詢條件 (注意: 不要加 where)
@rowCount int output --查詢到的記錄數(shù)
AS
declare @strSQL varchar(5000) -- 主語句
declare @strTmp varchar(110) -- 臨時變量
declare @strOrder varchar(400) -- 排序類型
declare @strCountTmp nvarchar(100) --記錄數(shù)
declare @timediff datetime --耗時
begin
select @timediff = Getdate()
if @strWhere !=''
set @strCountTmp = 'select @rowCount = count(*) from [' + @tblName + '] where '+@strWhere
else
set @strCountTmp = 'select @rowCount = rowCount_tmp from tmp where (table_tmp = ''' + @tblName +''')'
exec sp_executesql @strCountTmp,N'@rowCount int out',@rowCount out --輸出總記錄數(shù)
if @OrderType != 0
begin
set @strTmp = '<(select min'
set @strOrder = ' order by ' + @fldName +' desc'
--如果@OrderType不是0,就執(zhí)行降序,這句很重要!
end
else
begin
set @strTmp = '>(select max'
set @strOrder = ' order by ' + @fldName +' asc'
end
if @PageIndex = 1
begin
if @strWhere != ''
set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from [' + @tblName + '] where ' + @strWhere + ' ' + @strOrder
else
set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from ['+ @tblName + '] '+ @strOrder
--如果是第一頁就執(zhí)行以上代碼,這樣會加快執(zhí)行速度
end
else
begin
--以下代碼賦予了@strSQL以真正執(zhí)行的SQL代碼
set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from ['
+ @tblName + '] where [' + @fldName + ']' + @strTmp + '(['+ @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['+ @fldName + '] from [' + @tblName + ']' + @strOrder + ') as tblTmp)'+ @strOrder
if @strWhere != ''
set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from ['
+ @tblName + '] where [' + @fldName + ']' + @strTmp + '(['
+ @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['
+ @fldName + '] from [' + @tblName + '] where ' + @strWhere + ' '
+ @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder
end
end
exec (@strSQL)
select datediff(ms,@timediff,GetDate()) as runtime
這個SQL存儲過程語句非常的好,但是不足的地方就是如果你的條件語句中含有'(單引號)那就很郁悶了,十分的麻煩。你可以試下改動上面的相關代碼如下:
復制代碼 代碼如下:
replace(@strWhere,'''','''''')
不放心自己測試下吧。
復制代碼 代碼如下:
USE [data_Test]
GO
DECLARE @return_value int,
@rowCount int
EXEC @return_value = [dbo].[pagination]
@tblName = 'userinfo',
@strGetFields = N'id',
@fldName = N'id',
@PageSize = 10,
@PageIndex = 300,
@OrderType = 0,
@strWhere = null,
@rowCount = @rowCount OUTPUT
SELECT @rowCount as N'@rowCount'
SELECT 'Return Value' = @return_value
GO
最主要的DAL層代碼:
復制代碼 代碼如下:
public DataSet GetList(int PageIndex, string strWhere,ref int rowCount)
{
SqlParameter[] parameter = sosuo8.DBUtility.DbHelperSQL.pagePara();
parameter[0].Value = "userinfo";
parameter[1].Value = "id,userName,userWebName,createDate";
parameter[2].Value = "id";
parameter[3].Value = 10;
parameter[4].Value = PageIndex;
parameter[5].Value = 0;
parameter[6].Value = strWhere;
parameter[7].Direction = ParameterDirection.Output;//聲明為輸出類型
DataSet ds = sosuo8.DBUtility.DbHelperSQL.RunProcedure("pagination",parameter,"userinfo");
rowCount = Convert.ToInt32(parameter[7].Value);
return ds;
}
default.aspx.cs代碼
復制代碼 代碼如下:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
bind();
}
}
private void bind()//綁定數(shù)據(jù)
{
this.anPager.PageSize = 10;//每頁記錄數(shù)
this.anPager.AlwaysShow = true;//是否一直顯示分頁
int rowCount = 0;//初始化記錄數(shù)為0
string wherestr = string.Empty;//搜索關鍵字,這部分后面我在講講優(yōu)化
sosuo8.BLL.bll_test bll = new sosuo8.BLL.bll_test();
this.rpt.DataSource = bll.GetList(this.anPager.CurrentPageIndex,wherestr,ref rowCount);//rowCount在經(jīng)過這個函數(shù)后,返回的是重新賦值的記錄總數(shù)
this.anPager.RecordCount = rowCount;
this.rpt.DataBind();
}
protected void anPager_PageChanging(object src, Wuqi.Webdiyer.PageChangingEventArgs e)
{
this.anPager.CurrentPageIndex = e.NewPageIndex;
bind();
}
}
里面涉及到aspnetpager的使用,如果你還不會使用這個控件,可以自己看看有關教程。最終的界面如下:
令我十分高興的是,在處理520W的記錄時,它速度還在可以接受的范圍內(nèi),不會出現(xiàn)超時的現(xiàn)象。而作為優(yōu)化,可以在界面層中盡量少讀數(shù)據(jù)??梢约由弦詐age為參數(shù)頁面輸出緩存:
復制代碼 代碼如下:
<%@ OutputCache Duration="360" VaryByParam="page" %>
你也許并沒有用過里面的一些控件,但是知道原理和方法我相信你也可以自由搭配你需要的東西,下面我僅上傳部分比較重要的代碼,對于需要的控件我也放在里面,至于建表測試那些大家慢慢研究吧!當前的存儲過程只能針對一個字段排序,后面有時間我會修改成多字段排序
打包下載地址
您可能感興趣的文章:
相關文章
CodeFirst從零開始搭建Asp.Net Core2.0網(wǎng)站
這篇文章主要為大家詳細介紹了CodeFirst從零開始搭建Asp.Net Core2.0網(wǎng)站的詳細過程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07創(chuàng)建一個完整的ASP.NET Web API項目
ASP.NET Web API具有與ASP.NET MVC類似的編程方式,ASP.NET Web API不僅僅具有一個完全獨立的消息處理管道,而且這個管道比為ASP.NET MVC設計的管道更為復雜,功能也更為強大。下面創(chuàng)建一個簡單的Web API項目,需要的朋友可以參考下2015-10-10asp.net 未能加載文件或程序集“XXX”或它的某一個依賴項。試圖加載格式不正確的程序。
運行asp.net后提示未能加載文件或程序集“XXX”或它的某一個依賴項。試圖加載格式不正確的程序。2011-07-07ASP.NET網(wǎng)站聊天室的設計與實現(xiàn)(第3節(jié))
這篇文章主要介紹了ASP.NET網(wǎng)站聊天室的設計與實現(xiàn),了解Session、Application對象的屬性和事件,并且掌握利用它們在頁面間保存和傳遞數(shù)據(jù)的方法,需要的朋友可以參考下2015-08-08asp.net模板引擎Razor調(diào)用外部方法用法實例
這篇文章主要介紹了asp.net模板引擎Razor調(diào)用外部方法用法,實例分析了Razor調(diào)用外部方法的相關使用技巧,需要的朋友可以參考下2015-06-06asp.net Grid 導出Excel實現(xiàn)程序代碼
看了FineUI中的將Grid導出為Excel的實現(xiàn)方法,實際上是可以非常簡單。看來很難的問題,變換一種思路就可以非常簡單2012-12-12