CREATE PROC sp_PageView
@tbname     sysname,            --要分页显示的表名
@FieldKey   nvarchar(1000),      --用于定位记录的主键(惟一键)字段,可以是逗号分隔的多个字段
@PageCurrent int=1,              -->0表示要显示的页码,如果为0表示仅清理缓存数据的临时表,不返回数据,其他值代表重建缓存数据的临时表
@PageSize   int=10,             --每页的大小(记录数)
@FieldShow  nvarchar(1000)='',    --以逗号分隔的要显示的字段列表,如果不指定,则显示所有字段
@Where     nvarchar(1000)='',    --查询条件
@UserName  sysname='',         --调用查询的用户名
@PageCount  int OUTPUT        --总页数
AS
SET NOCOUNT ON
--检查对象是否有效
IF OBJECT_ID(@tbname) IS NULL
BEGIN
RAISERROR(N'对象"%s"不存在',1,16,@tbname)
RETURN
END
IF OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTable')=0
AND OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsView')=0
AND OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTableFunction')=0
BEGIN
RAISERROR(N'"%s"不是表、视图或者表值函数',1,16,@tbname)
RETURN
END--分页字段检查
IF ISNULL(@FieldKey,N'')=''
BEGIN
RAISERROR(N'分页处理需要主键(或者惟一键)',1,16)
RETURN
END--其他参数检查及规范
IF ISNULL(@PageSize,0)<1 SET @PageSize=10
IF ISNULL(@FieldShow,N'')=N'' SET @FieldShow=N'*'
IF ISNULL(@Where,N'')=N''
SET @Where=N''
ELSE
SET @Where=N'WHERE ('+@Where+N')'--分页数据缓存临时表状态检测
DECLARE @tempTable sysname,@TempField sysname,@TempTableDate datetime
SET @tempTable=QUOTENAME(N'##'
+RTRIM(LEFT(HOST_NAME(),50))
+N'_'+RTRIM(LEFT(CASE WHEN ISNULL(@UserName,N'')=N'' THEN SUSER_SNAME() ELSE @UserName END,50))
+N'_'+RTRIM(@tbname))SELECT @TempField=QUOTENAME(c.name),
@TempTableDate=DATEADD(Hour,1,o.crdate) --临时表的有效缓存时间为1小时,创建时间超过1小时的临时表会被重建
FROM tempdb..sysobjects o,tempdb..syscolumns c
WHERE o.id=c.id 
AND o.id=OBJECT_ID(N'tempdb..'+@tempTable)
AND c.status=0x80
IF @@ROWCOUNT>0
IF ISNULL(@PageCurrent,0)<1 OR @TempTableDate<GETDATE()
BEGIN
EXEC('DROP TABLE '+@tempTable)
IF @PageCurrent=0 RETURN
END
ELSE
GOTO lb_TempTable_Created
ELSE
SELECT @TempField=QUOTENAME(NEWID())--创建分页数据缓存临时表
EXEC(N'SELECT *,IDENTITY(decimal(18,0),0,1) as '+@TempField
+N' INTO '+@tempTable
+N' FROM(SELECT TOP 100 PERCENT '+@FieldKey
+N' FROM '+@tbname
+N' '+@Where
+N' ORDER BY NEWID())a')
SET @PageCount=(@@ROWCOUNT+@PageSize-1)/@PageSize
GOTO lb_ShowDatalb_TempTable_Created:
--如果@PageCount为NULL值,则计算总页数(这样设计可以只在第一次计算总页数,以后调用时,把总页数传回给存储过程,避免再次计算总页数,对于不想计算总页数的处理而言,可以给@PageCount赋值)
IF @PageCount IS NULL
BEGIN
DECLARE @sql nvarchar(4000)
SET @sql=N'SELECT @PageCount=COUNT(*)'
+N' FROM '+@tbname
+N' '+@Where
EXEC sp_executesql @sql,N'@PageCount int OUTPUT',@PageCount OUTPUT
SET @PageCount=(@PageCount+@PageSize-1)/@PageSize
ENDlb_ShowData:
IF ISNULL(@PageCurrent,0)<1 SET @PageCurrent=1--计算分页显示的TOPN值
DECLARE @TopN varchar(20),@TopN1 varchar(20)
SELECT @TopN=(@PageCurrent-1)*@PageSize,
@TopN1=@PageCurrent*@PageSize-1--生成主键(惟一键)处理条件
DECLARE @Field sysname
SET @Where=N''
WHILE CHARINDEX(N',',@FieldKey)>0
SELECT @Field=LEFT(@FieldKey,CHARINDEX(N',',@FieldKey)-1),
@FieldKey=STUFF(@FieldKey,1,CHARINDEX(N',',@FieldKey),N''),
@Where=@Where
+N' AND a.'+@Field+N'=b.'+@Field,
@FieldShow=REPLACE(@FieldShow,@Field,N'a.'+@Field)
SELECT @Where=STUFF(@Where+N' AND a.'+@FieldKey+N'=b.'+@FieldKey,1,5,N''),
@FieldShow=REPLACE(@FieldShow,@FieldKey,N'a.'+@FieldKey)
IF @FieldShow=N'*' SET @FieldShow=N'a.*'--执行查询
EXEC(N'SELECT '+@FieldShow
+N' FROM '+@tbname
+N' a,'+@tempTable
+N'b WHERE (b.'+@TempField
+N' BETWEEN '+@TopN
+N' AND '+@TopN1
+N') AND ('+@Where
+N') ORDER BY b.'+@TempField)

解决方案 »

  1.   

    http://blog.csdn.net/zjcxc/category/125592.aspx
    这些都瞄过了吗?
      

  2.   


    TOP n 实现的通用分页存储过程
    /*转自邹建*/ CREATE PROC sp_PageView @tbname sysname, --要分页显示的表名 @FieldKey nvarchar(1000), --用于定位记录的主键(唯一性)字段,可以是逗号分隔的多个字段 @PageCurrent int=1, --要显示的页码 @PageSize int=10, --每页的大小(记录数) @FieldShow nvarchar(1000)='', --以逗号分隔的要显示的字段列表,如果不指定,则显示所有字段 @FieldOrder nvarchar(1000)='', --以逗号分隔的排序字段列表,可以指定在字段后面指定DESC/ASC,用于指定排序顺序 @Where nvarchar(1000)='', --查询条件 @PageCount int OUTPUT --总页数 AS SET NOCOUNT ON --检查对象是否有效 IF OBJECT_ID(@tbname) IS NULL BEGIN RAISERROR(N'对象"%s"不存在',16,1,@tbname) RETURN
    END IF OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTable')=0 AND OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsView')=0 AND OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTableFunction')=0 BEGIN RAISERROR(N'"%s"不是表、视图或者表值函数',16,1,@tbname) RETURN END
    --分页字段检查 IF ISNULL(@FieldKey,N'')='' BEGIN RAISERROR(N'分页处理需要主键(或者唯一键)',16,1) RETURN END
    --其他参数检查及规范 IF ISNULL(@PageCurrent,0)<1 SET @PageCurrent=1 IF ISNULL(@PageSize,0)<1 SET @PageSize=10 IF ISNULL(@FieldShow,N'')=N'' SET @FieldShow=N'*' IF ISNULL(@FieldOrder,N'')=N'' SET @FieldOrder=N'' ELSE SET @FieldOrder=N'ORDER BY '+LTRIM(@FieldOrder)
    IF ISNULL(@Where,N'')=N'' SET @Where=N'' ELSE SET @Where=N'WHERE ('+@Where+N')'
    --如果@PageCount为NULL值,则计算总页数(这样设计可以只在第一次计算总页数,以后调用时,把总页数传回给存储过程, --避免再次计算总页数,对于不想计算总页数的处理而言,可以给@PageCount赋值) IF @PageCount IS NULL BEGIN DECLARE @sql nvarchar(4000) SET @sql=N'SELECT @PageCount=COUNT(*)' +N' FROM '+@tbname +N' '+@Where EXEC sp_executesql @sql,N'@PageCount int OUTPUT',@PageCount OUTPUT SET @PageCount=(@PageCount+@PageSize-1)/@PageSize END
    --计算分页显示的TOPN值 DECLARE @TopN varchar(20),@TopN1 varchar(20)
    SELECT @TopN=@PageSize,@TopN1=(@PageCurrent-1)*@PageSize
    --第一页直接显示 IF @PageCurrent=1 EXEC(N'SELECT TOP '+@TopN +N' '+@FieldShow +N' FROM '+@tbname +N' '+@Where +N' '+@FieldOrder) ELSE BEGIN --处理别名 IF @FieldShow=N'*' SET @FieldShow=N'a.*'
    --生成主键(唯一键)处理条件 DECLARE @Where1 nvarchar(4000),@Where2 nvarchar(4000),@s nvarchar(1000),@Field sysname SELECT @Where1=N'',@Where2=N'',@s=@FieldKey WHILE CHARINDEX(N',',@s)>0 SELECT @Field=LEFT(@s,CHARINDEX(N',',@s)-1), @s=STUFF(@s,1,CHARINDEX(N',',@s),N''), @Where1=@Where1+N' AND a.'+@Field+N'=b.'+@Field, @Where2=@Where2+N' AND b.'+@Field+N' IS NULL', @Where=REPLACE(@Where,@Field,N'a.'+@Field),
    @FieldOrder=REPLACE(@FieldOrder,@Field,N'a.'+@Field), @FieldShow=REPLACE(@FieldShow,@Field,N'a.'+@Field) SELECT @Where=REPLACE(@Where,@s,N'a.'+@s), @FieldOrder=REPLACE(@FieldOrder,@s,N'a.'+@s), @FieldShow=REPLACE(@FieldShow,@s,N'a.'+@s), @Where1=STUFF(@Where1+N' AND a.'+@s+N'=b.'+@s,1,5,N''), @Where2=CASE WHEN @Where='' THEN N'WHERE (' ELSE @Where+N' AND (' END+N'b.'+@s+N' IS NULL'+@Where2+N')'
    --执行查询 EXEC(N'SELECT TOP '+@TopN +N' '+@FieldShow +N' FROM '+@tbname +N' a LEFT JOIN(SELECT TOP '+@TopN1 +N' '+@FieldKey+N' FROM '+@tbname+N' a '+@Where+N' '+@FieldOrder+N')b ON '+@Where1+N' '+@Where2 +N' '+@FieldOrder) END
      

  3.   

    http://blog.csdn.net/zjcxc/category/125592.aspx 
    对就是这个 老大的博客~
      

  4.   

    sql2005分页很方便:Select * FROM ( 
        select ROW_NUMBER() Over(order by 排序字段 desc) as rowId,* from 数据表 

    where rowId between 页面大小*(页号-1) and 页面大小*页号
      

  5.   

    2000create Procedure [dbo].[Page2005] 
    @TableName varchar(50),          --表名 
    @Fields varchar(5000) = '*',      --字段名(全部字段为*) 
    @PrimaryKey varchar(20),          --主键 
    @OrderField varchar(5000),        --排序字段(必须!支持多字段) 
    @Orderby varchar(8)='desc',      --排序方式(desc:倒序,asc:顺序) 
    @sqlWhere varchar(5000) = Null,  --条件语句(不用加where) 
    @pageSize int,                    --每页多少条记录 
    @pageIndex int = 1 ,              --指定当前为第几页 
    @TotalPage int output            --返回总页数 
    as 
    begin 
        Begin Tran --开始事务 
        Declare @sql nvarchar(4000); 
        Declare @totalRecord int;    
        if isnull(@PrimaryKey,'')='' 
          set @PrimaryKey='*' 
        --计算总记录数 
            
        if (@SqlWhere='' or @sqlWhere=NULL) 
            set @sql = 'select @totalRecord = count('+ @PrimaryKey +') from ' + @TableName 
        else 
            set @sql = 'select @totalRecord = count('+ @PrimaryKey +') from ' + @TableName + ' where ' + @sqlWhere 
        EXEC sp_executesql @sql,N'@totalRecord int OUTPUT',@totalRecord OUTPUT--计算总记录数        
        
        --计算总页数 
        select @TotalPage=CEILING((@totalRecord+0.0)/@PageSize) 
        if (@SqlWhere='' or @sqlWhere=NULL) 
            set @sql = 'Select * FROM (select ROW_NUMBER() Over(order by ' + @OrderField + ' '+ @Orderby +') as rowId,' + @Fields + ' from ' + @TableName 
        else 
            set @sql = 'Select * FROM (select ROW_NUMBER() Over(order by ' + @OrderField + ' '+ @Orderby +') as rowId,' + @Fields + ' from ' + @TableName + ' where ' + @SqlWhere    
            
        
        --处理页数超出范围情况 
        if @PageIndex <=0 
            Set @pageIndex = 1 
        
        if @pageIndex>@TotalPage 
            Set @pageIndex = @TotalPage 
        --处理开始点和结束点 
        Declare @StartRecord int 
        Declare @EndRecord int 
        
        set @StartRecord = (@pageIndex-1)*@PageSize + 1 
        set @EndRecord = @StartRecord + @pageSize - 1 
        --继续合成sql语句 
        set @Sql = @Sql + ') as ' + @TableName + ' where rowId between ' + Convert(varchar(50),@StartRecord) + ' and ' +  Convert(varchar(50),@EndRecord) 
        
        Exec(@Sql) 
        --------------------------------------------------- 
        If @@Error <> 0 
          Begin 
            RollBack Tran 
            Return -1 
          End 
        Else 
          Begin 
            Commit Tran 
            Return @totalRecord ---返回记录总数 
          End    
    end