现在的位置: 首页 > 综合 > 正文

一个成熟的 多字段 排序 分页 存储过程 (有bug)

2013年10月19日 ⁄ 综合 ⁄ 共 6950字 ⁄ 字号 评论关闭

 

同事那的一个成熟 多字段 排序 分页 存储过程

 

 

sql中调用 :

 

exec CMS_SearchGetDataByPage 'tblschool','id,IsEmp,IsNom','IsEmp , IsNom','IsEmp desc, IsNom desc','id',10,1,''

 

 

 

 

c# 中调用:

 

  1. /// <summary>
  2.         /// 分页获取数据列表2
  3.         /// </summary>
  4.         /// <param name="tableName">表名</param>
  5.         /// <param name="fldNames">选择字段列表,以,分隔</param>
  6.         /// <param name="selectOrderFldName">排序字段列表,以,分隔(不能含keyFldName指定的字段,可为空)</param>
  7.         /// <param name="orderFldDesc">排序字段及方向,如addDate desc,id desc(排序字段需通过selectOrderFldName指
  8. 定,可为空)</param>
  9.         /// <param name="keyFldName">主键字段(没有主键请指定不重复的字段)</param>
  10.         /// <param name="PageSize">每页记录数</param>
  11.         /// <param name="PageIndex">当前页</param>
  12.         /// <param name="strWhere">SQL条件</param>
  13.         /// <returns>数据列表</returns>
  14.         public static DataSet GetList(string tableName, string fldNames, string selectOrderFldName, string 
  15. orderFldDesc, string keyFldName, int PageSize, int PageIndex, string strWhere)
  16.         {
  17.             SqlParameter[] parameters = {
  18.                     new SqlParameter("@tblName", SqlDbType.VarChar, 255),
  19.                     new SqlParameter("@fldNames", SqlDbType.VarChar, 1000),
  20.                     new SqlParameter("@selectOrderFldName", SqlDbType.VarChar, 500),
  21.                     new SqlParameter("@orderFldDesc", SqlDbType.VarChar, 500),
  22.                     new SqlParameter("@keyFldName", SqlDbType.VarChar, 255),
  23.                     new SqlParameter("@PageSize", SqlDbType.Int),
  24.                     new SqlParameter("@PageIndex", SqlDbType.Int),
  25.                     new SqlParameter("@strWhere", SqlDbType.VarChar,1000)
  26.                     };
  27.             parameters[0].Value = tableName;
  28.             parameters[1].Value = fldNames;
  29.             parameters[2].Value = selectOrderFldName;
  30.             parameters[3].Value = orderFldDesc;
  31.             parameters[4].Value = keyFldName;
  32.             parameters[5].Value = PageSize;
  33.             parameters[6].Value = PageIndex;
  34.             parameters[7].Value = strWhere;
  35.             return DbHelperSQL.RunProcedure("CMS_SearchGetDataByPage", parameters, "ds");
  36.         }

存储过程本身:

 

  1. create PROCEDURE CMS_SearchGetDataByPage
  2.     @tblName      varchar(255),       -- 表名
  3.     @fldNames      varchar(1000),     -- 选择的字段列表以,分隔
  4.     @selectOrderFldName      varchar(500),  -- 排序字段以,分隔(不能含keyFldName指定的字段,可为空)
  5.     @orderFldDesc      varchar(500),  -- 排序字段及排序方向,如addDate desc,id desc(排序字段需通过selectOrderFldName指定,可为空)
  6.     @keyFldName      varchar(255),     -- 主键字段
  7.     @PageSize     int = 10,           -- 页尺寸
  8.     @PageIndex    int = 1,            -- 页码
  9.     @strWhere     varchar(1000) = ''  -- 查询条件(注意: 不要加where)
  10. AS
  11. declare @strWhereA varchar(1200)            -- 临时变量,给sqlwhere加where
  12. declare @strOrderA varchar(2000)            -- 第一次排序类型
  13. declare @strOrderB varchar(2000)            -- 第二次排序类型
  14. declare @strSqlA varchar(4000)          -- 第一次选出
  15. declare @strSqlB varchar(8000)          -- 第二次选出
  16. declare @strSQL varchar(8000)           -- 最后选出
  17. /* 条件*/
  18. if @strWhere != ''
  19.     set @strWhereA = ' where ' + @strWhere
  20. else
  21.     set @strWhereA = ''
  22.     
  23. /* 选择字段列表*/
  24. if @fldNames is null or rtrim(@fldNames) = ''
  25.     set @fldNames = '*'
  26.     
  27. /* 排序字段列表*/
  28. if not(@selectOrderFldName is null or rtrim(@selectOrderFldName) = '')
  29.     if rtrim(@selectOrderFldName) = 'id'
  30.         set @selectOrderFldName = ''
  31.     else
  32.         set @selectOrderFldName = ',' + @selectOrderFldName
  33.     
  34. /* 构建order,按指定方式排序*/
  35. if @orderFldDesc is null or rtrim(@orderFldDesc) = ''
  36.     set @orderFldDesc = ' order by id desc'
  37. else
  38.     set @orderFldDesc = ' order by ' + @orderFldDesc
  39. set @strOrderA = UPPER(@orderFldDesc)
  40. set @strOrderB =  replace(@strOrderA,'DESC','DESC1')
  41. set @strOrderB =  replace(@strOrderB,'ASC','DESC')
  42. set @strOrderB =  replace(@strOrderB,'DESC1','ASC')
  43. /* 第一页*/
  44. if @PageIndex = 1
  45.     set @strSQL = 'select top ' + str(@PageSize) + ' ' + @fldNames + ' from [' + @tblName + '] with(nolock)' + @strWhereA + ' ' + @strOrderA
  46. else
  47.     begin
  48.         --取得总记录数
  49.         declare @sql nvarchar(500)
  50.         declare @maxCount int
  51.         declare @maxPage int
  52.         declare @tempRowCount int
  53.         set @sql ='select @maxCount = count('+@keyFldName+') from [' + @tblName + ']' + @strWhereA
  54.         exec sp_executesql @sql,N'@maxCount int output',@maxCount output
  55.         set @maxPage = @maxCount / @PageSize
  56.         if(@maxCount % @PageSize > 0)
  57.             set @maxPage = @maxPage + 1
  58.         /* 最后一页*/
  59.         if @PageIndex >= @maxPage
  60.             begin
  61.                 set @PageIndex = @maxPage
  62.                 set @strSqlA = char(13) + '(select top '+str(@maxCount % @PageSize)+' ' + @keyFldName + @selectOrderFldName + ' from [' + @tblName + '] as a with(nolock) ' + @strWhereA + @strOrderB + '  )' + char(13)
  63.                 set @strSqlB = char(13) + '(select ' + @keyFldName +' from ' + @strSqlA  + ' as b )' + char(13)
  64.                 set @strSQL = 'select ' + @fldNames + ' from [' + @tblName + '] where ([' + @keyFldName + '] in '+@strSqlB+')' + @strOrderA + char(13)
  65.             end
  66.         else
  67.             begin
  68.                 /* 不是第一页,也不是最后一页*/
  69.                 if(@PageIndex <= @maxPage / 2)
  70.                     begin
  71.                     --前半数的页
  72.                         set @tempRowCount = @PageIndex * @PageSize
  73.                         /* 构建SQL,本分页算法的目的是为了实现高效的非主键排序的分页。by tony */
  74.                         /* 1、先按指定字段+主键字段按降序选出perPage*pageNum条记录*/
  75.                         set @strSqlA = char(13) + '(select top '+str(@tempRowCount)+' ' + @keyFldName + @selectOrderFldName + ' from [' + @tblName + '] as a  with(nolock) ' + @strWhereA + @strOrderA + '  )' + char(13)
  76.                         /* 2、再从选出的记录中按升序选出perPage条记录*/
  77.                         set @strSqlB = char(13) + '(select top '+str(@PageSize)+' ' + @keyFldName + ' from ' + @strSqlA  + ' as b ' + @strOrderB + '  )' + char(13)
  78.                         /* 3、从数据库中选出主键在第二次选出的记录中的记录,按降序排列,分页完成*/
  79.                         set @strSQL = 'select ' + @fldNames + ' from [' + @tblName + '] where ([' + @keyFldName + '] in '+@strSqlB+')' + @strOrderA
  80.                     end
  81.                 else
  82.                     begin
  83.                     --后半数的页
  84.                         set @tempRowCount = @maxCount - (@PageIndex -1) * @PageSize
  85.                         /* 构建SQL,本分页算法的目的是为了实现高效的非主键排序的分页。by tony */
  86.                         /* 1、先按指定字段+主键字段按降序选出perPage*pageNum条记录*/
  87.                         set @strSqlA = char(13) + '(select top '+str(@tempRowCount)+' ' + @keyFldName + @selectOrderFldName + ' from [' + @tblName + '] as a  with(nolock) ' + @strWhereA + @strOrderB + '  )' + char(13)
  88.                         /* 2、再从选出的记录中按升序选出perPage条记录*/
  89.                         set @strSqlB = char(13) + '(select top '+str(@PageSize)+' ' + @keyFldName + ' from ' + @strSqlA  + ' as b ' + @strOrderA + '  )' + char(13)
  90.                         /* 3、从数据库中选出主键在第二次选出的记录中的记录,按降序排列,分页完成*/
  91.                         set @strSQL = 'select ' + @fldNames + ' from [' + @tblName + '] where ([' + @keyFldName + '] in '+@strSqlB+')' + @strOrderA
  92.                     end
  93.                 end
  94.     end
  95. set nocount on
  96. /*print @strSQL*/ --显示SQL
  97. exec (@strSQL)
  98. set nocount off
  99. RETURN

抱歉!评论已关闭.