这个BUG存在任意字段排序部分。
当 排序字段 内容不重复时,这个BUG就体现不出来了。
但是当 排序字段内容出现重复时,这个BUG就体现出来了。例如 共有数据45 条每页显示 20 条数据,当第二页的 38-45条记录 的排序内容 相同时。 第三页就无数据显示了。CREATE Procedure GetTurnPage
@tblName varchar(255), -- 表名
@strGetFields varchar(1000) = '*', -- 需要返回的列
@fldName varchar(255)='', -- 排序的字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@doCount bit = 0, -- 返回记录总数, 非 0 值则返回
@OrderType bit = 0, -- 设置排序类型, 非 0 值则降序
@strWhere varchar(1500) = '' -- 查询条件 (注意: 不要加 where)ASdeclare @strSQL varchar(5000) -- 主语句
declare @strTmp varchar(110) -- 临时变量
declare @strOrder varchar(400) -- 排序类型if @doCount != 0
beginif @strWhere !=''
set @strSQL = "select count(*) as Total from [" + @tblName + "] where "+@strWhere
else
set @strSQL = "select count(*) as Total from [" + @tblName + "]"
end--以上代码的意思是如果@doCount传递过来的不是0,就执行总数统计。以下的所有代码都是@doCount为0的情况elsebeginif @OrderType != 0
beginset @strTmp = "< (select min"
set @strOrder = " order by [" + @fldName +"] desc"--如果@OrderType不是0,就执行降序,这句很重要!endelsebeginset @strTmp = "> (select max"
set @strOrder = " order by [" + @fldName +"] asc"endif @PageIndex = 1beginif @strWhere != ''
set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from [" + @tblName + "] where " + @strWhere + " " + @strOrder
else
set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from ["+ @tblName + "] "+ @strOrder--如果是第一页就执行以上代码,这样会加快执行速度end
elsebegin--以下代码赋予了@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)"+ @strOrderif @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 " + @strWhere + " "+ @strOrder + " ) as tblTmp) and " + @strWhere + " " + @strOrderend
end 
exec (@strSQL)
--print(@strSQL)
GO

解决方案 »

  1.   

    set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from ["在SQL里还能用这样的双引号?
      

  2.   

    这里有用到双引号, 导致我没执行成功。。是不是报这个错呢?A column has been specified more than once in the order by list. Columns in the order by list must be unique.这就需要把  @strOrder 处理下,去掉重复的字段名称,简单的就是你传过来的@fldName 不要有重复字段名。
      

  3.   

    该存储过程没有报错,也能调用。
    就是 排序内容相同时 才会 体现 BUG 例如 一个商品列表,按照 价格 排序, 里面肯定有些商品的价格是相同。
    按照下面的状况,BUG就体现出来了例如 共有数据45 条每页显示 20 条数据,当第二页的 38-45条记录 价格相同时。 第三页就无数据显示了。
      

  4.   

    你的过程中排序部分的逻辑不对,当@PageIndex<>1时,你取数据的语句可以简化如下:
    select top @PageSize * from [tb] 
    where [colname]> (
    select max([colname]) 
    from (select top (@PageIndex-1)*@PageSize [colname] from [tb] order by [colname] asc) as tblTmp
    ) order by [colname] asc举个例子,有下表A
    id
    ----
    1
    1
    1
    1假如按id排序,每页2条,取第2页时,你的过程就会取id>第一页id的最大值(1)的前两条,当然取不到。建议:
    如果是sql2005/08,可以用row_number(),然后取行号范围
    如果是sql2000及以下,可以用identity,然后取行号范围
    PS: SET QUOTED_IDENTIFIER OFF即可解决双引号问题
      

  5.   

    谢谢5楼大哥的回复如果是sql2000及以下,可以用identity,然后取行号范围我该如何把这个identity应用到我的存储过程中??
      

  6.   


    --你可以将原来排序部分:
    select top @PageSize * from [tb] 
    where [colname]> (
        select max([colname]) 
        from (select top (@PageIndex-1)*@PageSize [colname] from [tb] order by [colname] asc) as tblTmp
    ) order by [colname] asc--改成:
    select top (PageIndex*@PageSize) * into #t from [tb] order by [colname] --先插入临时表
    alter table #t add rowid int identity(1,1) --给临时表加上自增列
    select * from #t where rowid > (@PageIndex-1)*@PageSize请记得结贴