分页存储过程很大程度上影响网站系统整体性能,这个过程是我找到作了相应修改。 现在的过程还存在性能上的问题,我己经将其完美化,过些时候贴出来。
过程如下:
CREATE procedure propage
( @Tables varchar(1000), --表名如testtable @PrimaryKey varchar(100),--表的主键,必须唯一性 @Sort varchar(200) = NULL,--排序字段如f_Name asc或f_name desc(注意只能有一个排序字段) @CurrentPage int = 1,--当前页 @PageSize int = 10,---每页大小 @Fields varchar(1000) = '*',--显示的字段列表 @Filter varchar(1000) = NULL,--条件语句,不加where,如 f_id>3 @Group varchar(1000) = NULL,--分组字段 @TotalPage int output --返回总页数 )
--WITH ENCRYPTION ---加密存储
AS
SET NOCOUNT ON Declare @intResult Int
Begin Tran
DECLARE @sql nvarchar(4000) if @Filter is null or @Filter='' set @Sql = 'select @intResult = count(' + @PrimaryKey + ') from ' + @Tables else set @Sql = 'select @intResult = count(' + @PrimaryKey + ') from ' + @Tables + ' where + ' + @Filter
EXEC sp_executesql @sql,N'@intResult int OUTPUT',@intResult OUTPUT--计算总记录数 select @TotalPage=CEILING((@intResult+0.0)/@PageSize)--计算总页数 IF @Sort IS NULL or @Sort = '' SET @Sort = @PrimaryKey
DECLARE @SortTable varchar(100) DECLARE @SortName varchar(100) DECLARE @strSortColumn varchar(200) DECLARE @operator char(2) DECLARE @type varchar(100) DECLARE @prec int IF CHARINDEX('DESC',@Sort)>0 BEGIN SET @strSortColumn = REPLACE(@Sort, 'DESC', '') SET @operator = '<=' END ELSE IF CHARINDEX('ASC', @Sort) > 0 BEGIN SET @strSortColumn = REPLACE(@Sort, 'ASC', '') SET @operator = '>=' END ELSE BEGIN SET @strSortColumn = @SORT SET @operator = '>=' END IF CHARINDEX('.', @strSortColumn) > 0 BEGIN SET @SortTable = SUBSTRING(@strSortColumn, 0, CHARINDEX('.',@strSortColumn)) SET @SortName = SUBSTRING(@strSortColumn, CHARINDEX('.',@strSortColumn) + 1, LEN(@strSortColumn)) END ELSE BEGIN SET @SortTable = @Tables SET @SortName = @strSortColumn END Select @type=t.name, @prec=c.prec FROM sysobjects o JOIN syscolumns c on o.id=c.id JOIN systypes t on c.xusertype=t.xusertype Where o.name = @SortTable AND c.name = @SortName IF CHARINDEX('char', @type) > 0 SET @type = @type + '(' + CAST(@prec AS varchar) + ')' DECLARE @strPageSize varchar(50) DECLARE @strStartRow varchar(50) DECLARE @strFilter varchar(1000) DECLARE @strSimpleFilter varchar(1000) DECLARE @strGroup varchar(1000) IF @CurrentPage < 1 SET @CurrentPage = 1 SET @strPageSize = CAST(@PageSize AS varchar(50)) SET @strStartRow = CAST(((@CurrentPage - 1)*@PageSize + 1) AS varchar(50)) IF @Filter IS NOT NULL AND @Filter != '' BEGIN SET @strFilter = ' Where ' + @Filter + ' ' SET @strSimpleFilter = ' AND ' + @Filter + ' ' END ELSE BEGIN SET @strSimpleFilter = '' SET @strFilter = '' END IF @Group IS NOT NULL AND @Group != '' SET @strGroup = ' GROUP BY ' + @Group + ' ' ELSE SET @strGroup = '' set @sql = 'DECLARE @SortColumn ' + @type + ' SET ROWCOUNT ' + @strStartRow + ' Select @SortColumn=' + @strSortColumn + ' FROM ' + @Tables + @strFilter + ' ' + @strGroup + ' orDER BY ' + @Sort + ' SET ROWCOUNT ' + @strPageSize + ' Select ' + @Fields + ' FROM ' + @Tables + ' Where ' + @strSortColumn + @operator + ' @SortColumn ' + @strSimpleFilter + ' ' + @strGroup + ' orDER BY ' + @Sort + ' ' -- exec(@sql) print @sql
-------------------------------------------------------------------------------------------------
If @@Error <> 0 Begin RollBack Tran Return -1 End Else Begin Commit Tran Return @intResult ---返回记录总数 End GO
CREATE Procedure ProPageSet @tb varchar(50), --表名 @col varchar(50), --按该列来进行分页 @orderby bit, --排序,0-顺序,1-倒序 @collist varchar(800),--要查询出的字段列表,*表示全部字段 @pagesize int, --每页记录数 @page int, --指定页 @condition varchar(800),--查询条件 @pages int OUTPUT --总页数 AS SET NOCOUNT ON Declare @intResult Int Begin Tran DECLARE @sql nvarchar(4000),@where1 varchar(800),@where2 varchar(800) IF @condition is null or rtrim(@condition)='' BEGIN--没有查询条件 SET @where1=' WHERE ' SET @where2=' ' END ELSE BEGIN--有查询条件 SET @where1=' WHERE ('+@condition+') AND '--本来有条件再加上此条件 SET @where2=' WHERE ('+@condition+') '--原本没有条件而加上此条件 END SET @sql='SELECT @intResult=COUNT(*) FROM '+@tb+@where2 EXEC sp_executesql @sql,N'@intResult int OUTPUT',@intResult OUTPUT--计算总记录数 SELECT @pages=CEILING((@intResult+0.0)/@pagesize)--计算总页数 IF @orderby=0 SET @sql='SELECT TOP '+CAST(@pagesize AS varchar)+' '+@collist+ ' FROM '+@tb+@where1+@col+'>(SELECT MAX('+@col+') '+ ' FROM (SELECT TOP '+CAST(@pagesize*(@page-1) AS varchar)+' '+ @col+' FROM '+@tb+@where2+'ORDER BY '+@col+') t) ORDER BY '+@col ELSE SET @sql='SELECT TOP '+CAST(@pagesize AS varchar)+' '+@collist+' FROM '+@tb+@where1+@col+'<(SELECT MIN('+@col+') '+ ' FROM (SELECT TOP '+CAST(@pagesize*(@page-1) AS varchar)+' '+ @col+' FROM '+@tb+@where2+'ORDER BY '+@col+' DESC) t) ORDER BY '+@col+' DESC' IF @page=1--第一页 SET @sql='SELECT TOP '+CAST(@pagesize AS varchar)+' '+@collist+' FROM '+@tb+ @where2+'ORDER BY '+@col+CASE @orderby WHEN 0 THEN '' ELSE ' DESC' END EXEC(@sql) If @@Error <> 0 Begin RollBack Tran Return -1 End Else Begin Commit Tran Return @intResult End GO
ASP调用如下:
if not(Isnumeric(request("page")))then response.write "<script>alert('页数必须为数字');history.go(-1);</Script>" Response.End end if page=request("page") if page="" or page<=0 then page=1 end if collist="*" '要注意备注字段不要取出! pagesize = 24 if request("word")<>"" then condition= "title like '%" & request("word") & "%'" else condition="" end if Set Comm = Server.CreateObject("ADODB.Command") with Comm .ActiveConnection = conn '数据库连接字串 .CommandText = "ProPageSet" '指定存储过程名 .CommandType = 4 '表明这是一个存储过程 .Prepared = true '要求将SQL命令先行编译 .Parameters.Append .CreateParameter("RETURN",3,4) '返回值 .Parameters.append .CreateParameter("@tb",200,1,50,"Ebook" ) '分页时要查询的表名 .Parameters.append .CreateParameter("@col",200,1,50,"Ebook_id") '按该列来进行分页 .Parameters.append .CreateParameter("@orderby",11,1,1,1) '排序方式,0为顺,1为倒 .Parameters.append .CreateParameter("@collist",200,1,800,collist) '每页中要显示的字段,以逗号隔开 .Parameters.append .CreateParameter("@pagesize",3,1,4,pagesize) '每页记录数 .Parameters.append .CreateParameter("@page",3,1,4,page) '指定页 .Parameters.append .CreateParameter("@condition",200,1,800,condition) '查询条件where 中的条件语句 .Parameters.Append .CreateParameter("@pages",3,2,4) '总页数 output Set rs = .Execute end with if rs.state = 0 then '未取到数据,rs关闭 recordcount = -1 else rs.close '注意:若要取得参数值,需先关闭记录集对象 recordcount = Comm(0) pagecount = Comm(8) end if Set Comm = Nothing
'以下显示记录 if recordcount = 0 then Response.Write "无记录" elseif recordcount > 0 then do while not rs.eof rs.open ..... rs.movenext loop end if |