网络编程
位置:首页>> 网络编程>> Asp编程>> 通用分页存储过程

通用分页存储过程

作者:幻想曲 来源:幻想曲 发布时间:2007-11-28 13:08:00 

标签:分页,存储过程,sql


/*
功能: 通用分页存储过程
参数:
@PK varchar(50), 
主键,用来排序的单一字段,空的话,表示没有主键,存储过程将自动创建标识列主键
@Fields varchar(500), 要显示的字段列表(格式如:ID,Code,Name)
@Tables varchar(1000), 要使用的表集合(Org)
@Where varchar(500), 查询条件(Code like '100')
@OrderBy varchar(100), 排序条件(支持多个排序字段,如:ID,Code desc,Name desc)
@PageIndex int, 当前要显示的页的页索引,索引从1开始,无记录时为0。
@PageSize int, 页大小
创建者:Hollis Yao
创建日期:2006-08-06
备注:
*/
CREATE PROCEDURE [dbo].[listpage]
@PK varchar(50)='',
@Fields varchar(500),
@Tables varchar(1000),
@Where varchar(500)='',
@OrderBy varchar(100),
@PageIndex int,
@PageSize int
AS
--替换单引号,避免构造SQL出错
set @Fields = replace(@Fields, '''', '''''')
--要执行的SQL,切分为几个字符串,避免出现长度超过4k时的问题
declare @SQL1 varchar(4000)
declare @SQL2 varchar(4000) 
if @PageIndex=0
set @PageIndex = 1
set @SQL1 = ''
set @SQL2 = ''
if @Where is not null and len(ltrim(rtrim(@Where))) > 0
set @Where = ' where ' + @Where
else
set @Where = ' where 1=1'
set @SQL1 = @SQL1 + ' declare @TotalCount int' --声明一个变量,总记录数
set @SQL1 = @SQL1 + ' declare @PageCount int' --声明一个变量,总页数
set @SQL1 = @SQL1 + ' declare @PageIndex int' --声明一个变量,页索引
set @SQL1 = @SQL1 + ' declare @StartRow int' --声明一个变量,当前页第一条记录的索引
set @SQL1 = @SQL1 + ' select @TotalCount=count(*) from ' + @Tables + @Where --获取总记录数
set @SQL1 = @SQL1 + ' if @PageCount <= 0 begin' --如果记录数为0,直接输出空的结果集
set @SQL1 = @SQL1 + ' select ' + @Fields + ' from ' + @Tables + ' where 1<>1'
set @SQL1 = @SQL1 + ' select 0 as PageIndex,0 as PageCount,' 
+ convert(varchar, @PageSize) + ' as PageSize,0 as TotalCount'
set @SQL1 = @SQL1 + ' return end'
set @SQL1 = @SQL1 + ' set @PageCount=(@TotalCount+' + convert(varchar, @PageSize) 
+ '-1)/' + convert(varchar, @PageSize) --获取总页数
set @SQL1 = @SQL1 + ' set @PageIndex=' + convert(varchar, @PageIndex) 
--设置正确的页索引
set @SQL1 = @SQL1 + ' if @PageIndex<0 set @PageIndex=1'
set @SQL1 = @SQL1 + ' if @PageIndex>@PageCount and @PageCount>0 
set @PageIndex=@PageCount'
set @SQL1 = @SQL1 + ' set @StartRow=(@PageIndex-1)*' + convert(varchar, @PageSize)
+ '+1'
if (charindex(',', @OrderBy)=0 and charindex(@PK, @OrderBy)>0)
begin
--****************************************************************************
--****************不需要创建主键********************************************
--****************************************************************************
declare @SortDirection varchar(10) --排序方向,>=:升序,<=:倒序
set @SortDirection = '>='
if charindex('desc', @OrderBy) > 0
set @SortDirection = '<='
set @SQL2 = @SQL2 + ' declare @Sort varchar(100)' 
--声明一个变量,用来记录当前页第一条记录的排序字段值
set @SQL2 = @SQL2 + ' set rowcount @StartRow' 
--设置返回记录数截止到当前页的第一条
set @SQL2 = @SQL2 + ' select @Sort=' + @PK + ' from ' 
+ @Tables + @Where + ' order by ' + @OrderBy --获取当前页第一个排序字段值
set @SQL2 = @SQL2 + ' set rowcount ' + convert(varchar, @PageSize) 
--设置返回记录数为页大小
set @Where = @Where + ' and ' + @PK + @SortDirection + '@Sort'
set @SQL2 = @SQL2 + ' select ' + @Fields + ' from ' + @Tables 
+ @Where + ' order by ' + @OrderBy 
--输出最终显示结果
end
else
begin
--需要创建自增长主键
set @SQL2 = @SQL2 + ' declare @EndRow int'
set @SQL2 = @SQL2 + ' set @EndRow=@PageIndex*' + convert(varchar, @PageSize)
set @SQL2 = @SQL2 + ' set rowcount @EndRow'
set @SQL2 = @SQL2 + ' declare @PKBegin int' --声明一个变量,开始索引
set @SQL2 = @SQL2 + ' declare @PKEnd int' --声明一个变量,结束索引
set @SQL2 = @SQL2 + ' set @PKBegin=@StartRow'
set @SQL2 = @SQL2 + ' set @PKEnd=@EndRow'
--****************************************************************************
--************对特殊字段进行转换,以便可以插入到临时表******************
--****************************************************************************
declare @TempFields varchar(500)
set @TempFields=@Fields
set @TempFields = replace(@TempFields, ''''' as CheckBox', '')
set @TempFields = replace(@TempFields, ''''' as DetailButton', '')
set @TempFields = replace(@TempFields, ''''' as Radio', '')
set @TempFields = LTRIM(RTRIM(@TempFields))
if left(@TempFields,1)=',' --去除最左边的逗号
set @TempFields = substring(@TempFields, 2, len(@TempFields))
if right(@TempFields,1)=',' --去除最右边的逗号
set @TempFields = substring(@TempFields, 1, len(@TempFields)-1)
set @SQL2 = @SQL2 + ' select identity(int,1,1) as PK,' + @TempFields 
+ ' into #tb from ' + @Tables + @Where + ' order by ' + @OrderBy
--****************************************************************************
--********去除字段的表名前缀,当有字段有别名时,只保留字段别名*********
--****************************************************************************
declare @TotalFields varchar(500)
declare @tmp varchar(50)
declare @i int
declare @j int
declare @iLeft int --左括号的个数
declare @iRight int --右括号的个数
set @i = 0
set @j = 0
set @iLeft = 0
set @iRight = 0
set @tmp = ''
set @TotalFields = '' 
while (len(@Fields)>0)
begin
set @i = charindex(',', @Fields)
--去除字段的表名前缀 本篇文章发表于www.xker.com(小新技术网) 
if (@i=0)
begin
--找不到逗号分割,即表示只剩下最后一个字段
set @tmp = @Fields
end
else
begin
set @tmp = substring(@Fields, 1, @i)
end
set @j = charindex('.', @tmp)
if (@j>0)
set @tmp = substring(@tmp, @j+1, len(@tmp))
--*******当有字段有别名时,只保留字段别名********* 
--带括号的情况要单独处理,如Convert(varchar(10), B.EndDate, 120) as EndDate
while (charindex('(', @tmp) > 0)
begin
set @iLeft = @iLeft + 1
set @tmp = substring(@tmp, charindex('(', @tmp)+1, Len(@tmp))
end
while (charindex(')', @tmp) > 0)
begin
set @iRight = @iRight + 1
set @tmp = substring(@tmp, charindex(')', @tmp)+1, Len(@tmp))
end
--当括号恰好组队的时候,才能进行字段别名的处理
if (@iLeft = @iRight)
begin
set @iLeft = 0
set @iRight = 0
--不对这几个特殊字段作处理:CheckBox、DetailButton、Radio
if (charindex('CheckBox', @tmp) = 0 and charindex
('DetailButton', @tmp) = 0 and charindex('Radio', @tmp) = 0)
begin
--判断是否有别名
if (charindex('as', @tmp) > 0)--别名的第一种写法,带'as'的格式
begin
set @tmp = substring(@tmp, charindex('as', @tmp)+2, len(@tmp))
end
else
begin
if (charindex(' ', @tmp) > 0)--别名的第二种写法,带空格(" ")的格式
begin
while(charindex(' ', @tmp) > 0)
begin
set @tmp = substring(@tmp, charindex(' ', @tmp)+1, len(@tmp))
end
end
end
end
set @TotalFields = @TotalFields + @tmp
end
if (@i=0)
set @Fields = ''
else
set @Fields = substring(@Fields, @i+1, len(@Fields))
end
--print @TotalFields
set @SQL2 = @SQL2 + ' select ' + @TotalFields + ' 
from #tb where PK between @PKBegin and @PKEnd order by PK' 
--输出最终显示结果
set @SQL2 = @SQL2 + ' drop table #tb'
end 
--输出“PageIndex(页索引)、PageCount(页数)、PageSize(页大小)、TotalCount(总记录数)”
set @SQL2 = @SQL2 + ' select @PageIndex as PageIndex,@PageCount as PageCount,' 
+ convert(varchar, @PageSize) + ' as PageSize,@TotalCount as TotalCount'
--print @SQL1 + @SQL2
--return
exec(@SQL1 + @SQL2)
GO


最终这个存储过程将生成二张表,表1显示记录集,表2显示当前页码、总页数、每页记录数、总记录数。

使用方法:


SqlCommand comm = new SqlCommand(); 
                comm.CommandText = "listpage"; 
                comm.CommandType = System.Data.CommandType.StoredProcedure; 
                comm.Connection = conn; 
                /* 
                    @PK varchar(50), 
                    主键,用来排序的单一字段,空的话,表示没有主键,存储过程将自动创建标识列主键 
                    @Fields varchar(500), 要显示的字段列表(格式如:ID,Code,Name) 
                    @Tables varchar(1000), 要使用的表集合(Org) 
                    @Where varchar(500), 查询条件(Code like '100') 
                    @OrderBy varchar(100), 排序条件(支持多个排序字段,如:ID,Code desc,Name desc) 
                    @PageIndex int, 当前要显示的页的页索引,索引从1开始,无记录时为0。 
                    @PageSize int, 页大小 
                  
                 */ 
                //增加参数及值 
                comm.Parameters.AddWithValue("@PK", "主键"); 
                comm.Parameters.AddWithValue("@Fields", "字段列表"); 
                comm.Parameters.AddWithValue("@Table", "doc_qa"); 
                comm.Parameters.AddWithValue("@Where", "  条件 "); 
                comm.Parameters.AddWithValue("@OrderBy", " 排序的语句"); 
                comm.Parameters.AddWithValue("@PageIndex", 1); 
                comm.Parameters.AddWithValue("@pagesize", 15); 
                conn.Open(); 
                DataSet dst = new DataSet(); 
                SqlDataAdapter da = new SqlDataAdapter(comm); 
                da.Fill(dst); 
                DataTable DataSource = dst.Tables[0];  //记录集 
                DataTable DataCount = dst.Tables[1]; //页码等信息 



0
投稿

猜你喜欢

  • 使用SQL SERVER的[导入]功能,便可将access数据转换,但要注意原来的'自增字段'需要修改,将相应字段标识修改为
  • 摘要: Portal是IT领域的新技术,是企业信息化工作的发展方向之一。本文首先介绍了Oracle Portal的定义、特点,接着阐述了po
  • 为了让鼠标移到小图上显示大图,我利用鼠标事件新建了一个层来显示大图.当然之前最好得到XY坐标取得当前鼠标的X,Y坐标:function&nb
  •     (一)原理 小偷程序实际上是通过了XML中的XMLHTTP组件调用其它网站上的网页。比如新闻小偷程序,
  • 省市级联这东西基本是网注一份,而且基本是全是js写的,js写唯一坏处就是JS无效时不可用,我所说的js无效包括不支持js,js加载未完成或者
  • 大家知道,在js里encodeURIComponent 方法是一个比较常用的编码方法,但因工作需要,在asp里需用到此方法,查了好多资料,没
  • 内容摘要:“ASP”(Active Server Pages)作为一种典型的服务器端网页设计技术,被广泛地应用在网上银行
  • 程序代码: '关键字的搜索 str="select * from tableNam
  • 以下是几个文件操作过程,创建文件,删除文件,修改文件:
  • 图形由json格式加载,可以灵活配置。下一步是完善用户的操作,做这个感觉还是蛮有意思的。呵呵。截图:部分源码:<script type
  • 本文介绍了四种asp导出excel数据的方法:1.使用OWC ,2.用Excel的Application组件,3.直接在IE中打开,4.导出
  • 1、授权机制的主要作用是什么?授权机制的基本作用是给某个主机上的用户对某个数据库以select,insert,update和detete的权
  • 虽然ting88没有注册的用户不能下载歌曲,但搞定它也非难事啊:)进入www.ting88.com的网站,把歌手专辑页面的URL复制到文本框
  • 阅读上一篇:WEB前端开发经验总结 ⅠWEB标准篇现在我们接着来讲怎么在实际开发中结合我前面所讲的理论来开发制作页面吧。现在就来看看我们要制
  • hmac主要应用在身份验证中,它的使用方法是这样的:1. 客户端发出登录请求(假设是浏览器的GET请求)2. 服务器返回一个随机值,并在会话
  • 今天萌发一个想法,用css来实现透视效果。起初,我想到的是我们常见的添加阴影效果的方法,用多个div通过偏移来实现,但这需要很多 div,不
  • input高级限制级用法1.取消按钮按下时的虚线框 在input里添加属性值 hideFocus 或者 HideFocus=true2.只读
  • 本文中的示例主要是解决在函数间不能传递多个(32个以上)参数的问题,解题的具体思路就是采用记录类型作为函数的输入和返回值,所以我们需要先定义
  • 樂思蜀将SEO工作中所需要的301转向代码进行了整理,收藏并分享,以备查阅。1、IIS下301设置 Internet信息服务管理器 ->
  • Web2.0时代,体验式营销,体验式网站设计开始走向主流,那么体验式网站到底意味着什么?具体表现在那些地方?周末,根据建站的一点经验和观察,
手机版 网络编程 asp之家 www.aspxhome.com