软件下载 | 资讯教程 | 最近更新 | 下载排行 | 一键转帖 | 发布投稿
您的位置:最火下载站 > 网络编程 > ASP教程 > 数据绑定到分页的快速开发最佳实践

数据绑定到分页的快速开发最佳实践

项目中要使用分页的地方很多,园子里面也有很多各种分页方法的性能测试。但是如何既能满足快速开发的要求,又能保证良好的性能这是需要值得权衡的事情。经过几天的测试,我觉得比较好的方法是通用存储过程+ajax分页,为什么呢。且看以下分析。

使用通用存储过程,大大的节约了开发时间,一般情况下的分页,涉及的查询无非是单表多表查询,按条件排排序之类的,所以有个通用存储过程可以省很多力气。特殊的再使用专用的存储过程来解决。网上的这种通用SP比较多,我自己改了一个,这个SP经过长期使用,没有什么问题。里面优化了首页、尾页的算法,查询时经测试,前后翻页速度在1900W级别时也能基本保持一致。

存储过程如下

Copy to ClipboardLiehuo.Net Codes引用的内容:[www.veryhuo.com]
/*通用存储过程
支持多表查询,需要有索引,和int的ID字段
2008-1-10
2009-7-21 支持非主键的单字段排序
2009-11-20 去掉out total
by emilchan
*/
create PROCEDURE [dbo].[spCRM_GetPageListByNoTotal]
(
@strSelect varchar(2000), -- 要返回的列 strSelect=
@strFrom varchar(2000), -- 主表名 strFrom=
@strWhere varchar(2000)='1=1', -- 查询条件
@strPk varchar(2000)='a.Id', -- 主键字段名
@strOrder varchar(100), -- 排序字段
@strDirection varchar(5)='desc', -- 排序方向
@PageSize int = 10, -- 单页大小
@PageIndex int = 1 -- 第几页
)
AS
declare @sql nvarchar(4000)
declare @sort varchar(10) --desc or asc
declare @operator varchar(2) --方向符号
IF LOWER(@strDirection)='desc' --如果是逆序
BEGIN
set @sort=' desc '
SET @operator = '<='
END
ELSE --否则正序
BEGIN
set @sort=' asc '
SET @operator = '>='
END

declare @strOrderSql varchar(6000) --没有排序的包含主键、order字段的列表
declare @strSelectSQL varchar(6000) --返回列表
declare @strGetRecordSql varchar(6000) --最终输出表
declare @tmpStrPk varchar(2000) --把形如a.Id的主键还原为Id

if(@strPk<>@strOrder)
set @strOrderSql = 'select '+@strPk+','+@strOrder+' from '+ @strFrom+' where '+@strWhere
else
set @strOrderSql = 'select '+@strPk+' from '+ @strFrom+' where '+@strWhere

set @strSelectSQL = 'select '+@strSelect+' from '+ @strFrom+' where '+@strWhere

declare @tmpStrOrder varchar(50)
--修改pkstr以适合构造sql,去掉a.Id的a.
select @tmpStrPk=@strPk
select @tmpStrOrder=@strOrder
if(charindex('.',@tmpStrPk)>0)
select @tmpStrPk=substring(@tmpStrPk,3, len(@tmpStrPk)-2)
if(charindex('.',@tmpStrOrder)>0)
select @tmpStrOrder=substring(@tmpStrOrder,3, len(@tmpStrOrder)-2)

/*默认当前页*/
/*直接显示第一页*/
IF @PageIndex <= 1
begin
SET @PageIndex = 1
if @PageIndex=1
begin
set @strSelectSQL=stuff(@strSelectSQL,7,0,' top '+cast(@PageSize as varchar)+' ')+ ' order by '+@strOrder+@sort
exec(@strSelectSQL)
end
end
else
begin

--主键是int,且排序为主键的情况
if(@strPk=@strOrder)
begin
--设置分页参数
DECLARE @strPageSize varchar(50) --页大小str
DECLARE @strStartRow varchar(50) --开始的行的计数值

SET @strPageSize = CAST(@PageSize AS varchar(50))
SET @strStartRow = CAST(((@PageIndex-1)*@PageSize+1) AS varchar(50))

declare @topPostion int -- select后插入top 语句的位置
set @topPostion= len('select')+1
DECLARE @SortColumn varchar(50) --返回边界值,第一条记录的pkid
--返回@SortColumn值,该值为条件搜索结果的第一条返回记录,通过该记录,由@operator来决定排序,该值就是当前的的上边界值
set @sql='
SET ROWCOUNT ' + @strStartRow + '
Select @SortColumn=m. '+@tmpStrPk+' from (' + @strOrderSql+ ') m order by m.'+@tmpStrOrder+@sort
--返回一个pkstr值

exec sp_executesql @sql, N'@SortColumn varchar(50) output',@SortColumn output

--符合条件的,还没有按页大小取记录的记录集
set @strGetRecordSql=@strSelectSQL+' and '+@strPk+ @operator +cast(@SortColumn as varchar)+'order by '+@strOrder+@sort

--获取top n行
set @strGetRecordSql=stuff(@strGetRecordSql,@topPostion,0, ' top '+cast(@PageSize as varchar)+' ')
exec(@strGetRecordSql)

end
else
begin
--非主键排序情况
declare @maxPage int
declare @lastPageSize int
declare @tmpOrderIn varchar(100) --内层order带a.xx
declare @tmpOrderOut varchar(100) --外层反向order
declare @tmpOrder varchar(100) --最外层order没有a.xx
declare @total int

if(@strDirection='desc')
begin
set @tmpOrderIn= @strOrder+' desc,'+@strPk+' desc'
set @tmpOrderOut= @tmpStrOrder+' asc,'+@tmpStrPk+' asc'
set @tmpOrder= @tmpStrOrder+' desc,'+@tmpStrPk+' desc'
end
else
begin
set @tmpOrderIn= @strOrder+' asc,'+@strPk+' asc'
set @tmpOrderOut= @tmpStrOrder+' desc,'+@tmpStrPk+' desc'
set @tmpOrder= @tmpStrOrder+' asc,'+@tmpStrPk+' asc'
end

set @lastPageSize=@pageSize
set @maxPage=@total/@pageSize

set @sql = 'select @total=count('+@strPk+') from '+@strFrom+' where '+ @strWhere
exec sp_executesql @sql, N'@total int output',@total output

if(@total%@pageSize)>0
begin
set @maxPage=@maxPage+1
set @lastPageSize=@pageSize-((@pageSize*@pageIndex)-@total)
end

--最后一页不是满页的情况
if (@total<@pageSize*@pageIndex and @pageIndex=@maxPage)
begin
set @strGetRecordSql='select * from ( select TOP '+cast(@lastPageSize as varchar)+' * FROM
( SELECT TOP '+cast(@total as varchar)+ ' '+@strSelect+' from '+@strFrom+' where '+@strWhere+' ORDER BY '+@tmpOrderIn+' ) as m ORDER BY '+@tmpOrderOut+') as b ORDER BY '+@tmpOrder
end
else
begin
set @strGetRecordSql='select * from ( select TOP '+cast(@pageSize as varchar)+' * FROM
( SELECT TOP '+cast(@pageSize*@pageIndex as varchar)+ ' '+@strSelect+' from '+@strFrom+' where '+@strWhere+' ORDER BY '+@tmpOrderIn+' ) as m ORDER BY '+@tmpOrderOut+' ) as b ORDER BY '+@tmpOrder
end
exec(@strGetRecordSql)
end
end

GO

相关阅读
栏目导航
推荐软件