sql分页存储过程排序问题
这个存储过程还是比较好用的。可是里面有些问题。看看有没有高手帮帮忙解决一下,问题一就是这个存储过程的排续只能以id或别的字段递增方式进行,,如果不是递增的或有相同值的排序,就会出错的。看看有没有人能修改一下,,谢谢了~~~~~~   set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[P_newpager ]
@tblname VARCHAR(255), -- 表名
@strGetFields nvarchar(1000) = "*", -- 需要返回的列
@fldName varchar(255)='', -- 排序的字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@doCount bit = 0, -- 返回, 非0 值则返回记录总数
@OrderType bit = 0, -- 设置排序类型, 非0 值则降序
@strWhere varchar(1500) = '' -- 查询条件(注意: 不要加where)
AS
declare @strSQL varchar(5000) -- 主语句
declare @strTmp varchar(110) -- 临时变量
declare @strOrder varchar(400) -- 排序类型if @doCount != 0
begin
   if @strWhere !=''
    set @strSQL = 'select count(*) as Total from [' + @tblName + '] where 1=1 '+ @strWhere
   else
    set @strSQL = 'select count(*) as Total from [' + @tblName + ']'
end --以上代码的意思是如果@doCount传递过来的不是,就执行总数统计。以下的所有代码都是@doCount为的情况:
else
begin
   if @OrderType != 0--降序
   begin
    set @strTmp = '<(select min'
    set @strOrder = ' order by [' + @fldName +'] desc'--如果@OrderType不是0,就执行降序,这句很重要!
   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 1=1 ' + @strWhere + ' ' + @strOrder
    else
     set @strSQL = 'select top ' + str(@PageSize) +' ' + @strGetFields + ' from [' + @tblName + '] ' + @strOrder--如果是第一页就执行以上代码,这样会加快执行速度
   end
   else
   begin--以下代码赋予了@strSQL以真正执行的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 1=1 ' + @strWhere + ' ' + @strOrder + ') as tblTmp) and 1=1 ' + @strWhere + ' ' + @strOrder
   end 
   if @strWhere !=''            --得到记录的总行数
    set @strSQL =@strSQL+ '; select count(*) as Total from [' + @tblName + '] where 1=1 '+ @strWhere
   else
    set @strSQL =@strSQL+ '; select count(*) as Total from [' + @tblName + ']'
end
exec (@strSQL)
RETURN

解决方案 »

  1.   

    我这个好用的.自增字段还是得要的.
    ALTER PROCEDURE [dbo].[Up_Get_PageResult]       --生成日志列表    模板列表    游戏列表
    -- 获得某一页的数据 --    
    @tabName varchar(1000),                           --需要查看的表名 (即 from table_name)
    @showColumn varchar(2000) ,           --需要得到的字段 (即 column1,column2,) 
    @ascColumn varchar(100) ,                 --排序的字段名 (即 order by column asc/desc) 
    @bitOrderType bit = 0,                            --排序的类型 (0为升序,1为降序)
    @strCondition varchar(2000) ,              --查询条件 (即 where condition) 不用加where关键字  
    @currPage int = 1,                                    --当前页页码 (即Top currPage) 
    @pageSize int = 10,                                --分页大小
    @pkColumn varchar(50) ,                  --主键名称
    @intcount int output --返回总数
       
    AS   
    BEGIN -- 存储过程开始    
    -- 该存储过程需要用到的几个变量 --    
    DECLARE @strTemp varchar(1000)    
    DECLARE @strSql varchar(4000)                   --该存储过程最后执行的语句    
    DECLARE @strOrderType varchar(1000)      --排序类型语句 (order by column asc或者order by column desc)    
       
    BEGIN   declare @sql nvarchar(500);
    set @sql=N'select @intcount=count(*) from '+ @tabname +' where '+@strcondition;
    exec sp_executesql   @sql,N'@intcount  int   output ',@intcount   output IF @bitOrderType = 1   -- bitOrderType=1即执行降序    
    BEGIN   
        SET @strOrderType = ' ORDER BY '+@ascColumn+' DESC,'+@pkcolumn+' asc'   
        SET @strTemp = '<(SELECT min'   
    END   
    ELSE   
    BEGIN   
        SET @strOrderType = ' ORDER BY '+@ascColumn+' ASC,'+@pkcolumn+' asc'   
        SET @strTemp = '>(SELECT max'   
    END   
       
    IF @currPage = 1    -- 如果是第一页    
            SET @strSql = 'SELECT TOP '+STR(@pageSize)+' '+@showColumn+' FROM '+@tabName+    
                ' WHERE '+@strCondition+@strOrderType    
    ELSE    -- 其他页    
            SET @strSql = 'SELECT TOP '+STR(@pageSize)+' '+@showColumn+' FROM '+@tabName+    
            ' WHERE '+@strCondition+' AND '+@pkColumn+@strTemp+'('+@pkColumn+')'+' FROM (SELECT TOP '+STR((@currPage-1)*@pageSize)+    
            ' '+@pkColumn+' FROM '+@tabName+' WHERE '+@strCondition+@strOrderType+') AS TabTemp)'+@strOrderType    
    END   
    EXEC (@strSql)    
    END  -- 存储过程结束    
    ------------------------------------------------
      

  2.   

    楼上这样不行,如果主键和排序列没有相同大小顺序就不行
    比如
    id  clicks
    1    5
    2    3
    3    4
    这样的话,如果按降序 取第二页的内容(pagesize=2)
    第二页是取不出数据的
    因为排序以后这样的
    id  clicks
    1    5
    3    4
    2    3
    2<1 是没有数据的