SQL 分页,又见分页。

最近又遇到分页的问题,首先就是页面程序中,然后又是SQL。网上找来找去,简单的分页有,复杂的也有;性能比较好的有,比较差的也有。呼,现在整理整理,备各种环境使用。

 

方法1:

  1. SELECT TOP 页大小 *
  2. FROM table1
  3. WHERE id NOT IN
  4.           (
  5.           SELECT TOP 页大小*(页数-1) id FROM table1 ORDER BY id
  6.           )
  7. ORDER BY id

适用于SQL SERVER 2000和2005

 

方法2:

  1. SELECT TOP 页大小 * 
  2. FROM 
  3.         (
  4.         SELECT ROW_NUMBER() OVER (ORDER BY id) AS RowNum,* FROM table1
  5.         ) A
  6. WHERE RowNum > 页大小*(页数-1)

适用于SQL SERVER 2005

 

方法3:

  1. with temptbl as 
  2.    (
  3.     SELECT ROW_NUMBER() OVER (ORDER BY id desc)AS RowNum, * 
  4.     from table t  where 条件1 and 条件2
  5.    )
  6. SELECT * FROM temptbl
  7. where RowNum between (页数-1)*页大小+1 and 页数*页大小

适用于SQL SERVER 2005

 

相关存储过程:

 

方法1:

  1. create procedure 存储过程名 
  2. (@变量 Int,
  3. @pagesize int,
  4. @pageindex int,
  5. @docount bit)
  6. as
  7. set nocount on
  8. if(@docount=1)
  9. select count(*) from 表名 where 子句
  10. else
  11. begin
  12. declare @indextable table(id int identity(1,1),nid int)
  13. declare @PageLowerBound int
  14. declare @PageUpperBound int
  15. set @PageLowerBound=(@pageindex-1)*@pagesize
  16. set @PageUpperBound=@PageLowerBound+@pagesize
  17. set rowcount @PageUpperBound
  18. insert into @indextable(nid) select 标识字段名 from 表名  where 子句 order by 排序字段名 desc
  19. select O.*(字段列表) from 表名 O,@indextable t where O.标识字段名=t.nid
  20. and t.id between @PageLowerBound+1 and @PageUpperBound order by t.id
  21. end
  22. set nocount off

方法2:

  1. ALTER PROCEDURE [dbo].[Pg_Paging]
  2. @Tables varchar(1000), --表名,多红表是请使用 tA a inner join tB b On a.AID = b.AID
  3. @PK varchar(100),    --主键,可以带表头 a.AID
  4. @Sort varchar(200) = '', --排序字段
  5. @PageNumber int = 1,    --开始页码
  6. @PageSize int = 10,        --页大小
  7. @Fields varchar(1000) = '*',--读取字段
  8. @Filter varchar(1000) = NULL,--Where条件
  9. @Group varchar(1000) = NULL,  --分组
  10. @isCount bit = 0     --1    --是否获得总记录数
  11. AS
  12. --
  13. --select * from GL_NEWS order by GN_UPDATE_DATE DESC
  14. --exec Pg_Paging @Tables = 'tb_NewsInfo', @PK = 'News_ID', @Sort = 'News_ID DESC', @PageNumber = 2, @PageSize = 15,@Fields = '*', @Group = '', @isCount = 0
  15. DECLARE @strFilter varchar(2000)
  16. declare @sql varchar(8000)
  17. IF @Filter IS NOT NULL AND @Filter != ''
  18.   BEGIN
  19.    SET @strFilter = ' WHERE ' + @Filter + ' '
  20.   END
  21. ELSE
  22.   BEGIN
  23.    SET @strFilter = ''
  24.   END
  25. if @isCount = 1 --只获得记录条数
  26.     begin
  27.         set @sql = 'SELECT  Count(*) FROM ' + @Tables + @strFilter  
  28.     end
  29. else
  30. begin
  31. if @Sort = ''
  32.   set @Sort = @PK + ' DESC '
  33. IF @PageNumber < 1
  34.   SET @PageNumber = 1
  35. if @PageNumber = 1 --第一页提高性能
  36. begin 
  37.   set @sql = 'select top ' + str(@PageSize) +' '+@Fields+ '  from ' + @Tables + ' ' + @strFilter + ' ORDER BY  '+ @Sort
  38. end 
  39. else
  40.   begin
  41.   /**//**//**//*Execute dynamic query*/    
  42.    DECLARE @START_ID varchar(50)
  43. DECLARE @END_ID varchar(50)
  44. SET @START_ID = convert(varchar(50),(@PageNumber - 1) * @PageSize + 1)
  45. SET @END_ID = convert(varchar(50),@PageNumber * @PageSize)
  46.     set @sql =  ' SELECT '+@Fields+ '
  47.    FROM (SELECT ROW_NUMBER() OVER(ORDER BY '+@Sort+') AS rownum, 
  48.      '+@Fields+ '
  49.       FROM '+@Tables+') AS D
  50.    WHERE rownum BETWEEN '+@START_ID+' AND ' +@END_ID +' ORDER BY '+@Sort
  51.   END
  52. END
  53. --print @sql
  54. EXEC(@sql)

方法3:

  1. SET QUOTED_IDENTIFIER ON 
  2. GO
  3. SET ANSI_NULLS ON 
  4. GO
  5. CREATE   PROCEDURE Paging_Asc_Desc
  6. @Tables varchar(1000),
  7. @PK varchar(100),
  8. @Sort varchar(200) = NULL,
  9. @PageNumber int = 1,
  10. @PageSize int = 10,
  11. @Fields varchar(1000) = '*',
  12. @Filter varchar(1000) = NULL,
  13. @Group varchar(1000) = NULL,
  14. @isCount bit = 0 --1时返回记录条数
  15. AS
  16. /**//*Find the @PK type*/
  17. DECLARE @PKTable varchar(100)
  18. DECLARE @PKName varchar(100)
  19. DECLARE @type varchar(100)
  20. DECLARE @prec int
  21. IF CHARINDEX('.', @PK) > 0
  22.     BEGIN
  23.         SET @PKTable = SUBSTRING(@PK, 0, CHARINDEX('.',@PK))
  24.         SET @PKName = SUBSTRING(@PK, CHARINDEX('.',@PK) + 1, LEN(@PK))
  25.     END
  26. ELSE
  27.     BEGIN
  28.         SET @PKTable = @Tables
  29.         SET @PKName = @PK
  30.     END
  31. SELECT @type=t.name, @prec=c.prec
  32. FROM sysobjects o 
  33. JOIN syscolumns c on o.id=c.id
  34. JOIN systypes t on c.xusertype=t.xusertype
  35. WHERE o.name = @PKTable AND c.name = @PKName
  36. IF CHARINDEX('char', @type) > 0
  37.    SET @type = @type + '(' + CAST(@prec AS varchar) + ')'
  38. DECLARE @strPageSize varchar(50)
  39. DECLARE @strRows varchar(50)
  40. DECLARE @strFilter varchar(8000)
  41. DECLARE @strGroup varchar(8000)
  42. DECLARE @strSortColumn varchar(4000)
  43. DECLARE @strSortDesc varchar(4000)
  44. /**//*Default Sorting*/
  45. IF @Sort IS NULL
  46.     SET @Sort = @PK
  47. /**//*Set sorting variables.*/    
  48. IF CHARINDEX('DESC',@Sort)>0
  49.     BEGIN
  50.         SET @strSortDesc = REPLACE(@Sort, 'DESC''ASC')
  51.         SET @strSortColumn = ', ' + REPLACE(@Sort, 'DESC''')
  52.     END
  53. ELSE
  54.     BEGIN
  55.         IF CHARINDEX('ASC', @Sort) = 0
  56.             BEGIN
  57.                 SET @strSortDesc = @Sort + ' DESC'
  58.                 SET @strSortColumn = ', ' + @Sort
  59.             END
  60.         ELSE
  61.             BEGIN
  62.                 SET @strSortDesc = REPLACE(@Sort, 'ASC''DESC')
  63.                 SET @strSortColumn = ', ' + REPLACE(@Sort, 'ASC''')
  64.             END
  65.     END
  66. IF @Sort = @PK
  67.     SET @strSortColumn = ''
  68. /**//*Default Page Number*/
  69. IF @PageNumber < 1
  70.     SET @PageNumber = 1
  71.     
  72. /**//*Set paging variables.*/
  73. SET @strPageSize = CONVERT(varchar(50), @PageSize)
  74. SET @strRows = CONVERT(varchar(50), (@PageSize * (@PageNumber - 1) + @PageSize))
  75. /**//*Set filter & group variables.*/
  76. IF @Filter IS NOT NULL AND @Filter != ''
  77.     BEGIN
  78.         SET @strFilter = ' WHERE ' + @Filter + ' '
  79.     END
  80. ELSE
  81.     BEGIN
  82.         SET @strFilter = ''
  83.     END
  84. IF @Group IS NOT NULL AND @Group != ''
  85.     SET @strGroup = ' GROUP BY ' + @Group + ' '
  86. ELSE
  87.     SET @strGroup = ''
  88. if @isCount = 1
  89.     begin
  90.         EXEC('SELECT  Count(*) FROM ' + @Tables + @strFilter + ' ' + @strGroup )
  91.     end
  92. else
  93.     begin
  94.     /**//*Execute dynamic query*/    
  95.     EXEC(
  96.     'DECLARE @tblPK TABLE (
  97.                 PK  ' + @type + ' NOT NULL PRIMARY KEY
  98.                 )
  99.     
  100.     INSERT INTO @tblPK SELECT TOP ' + @strPageSize + ' ' + @PK + ' FROM (SELECT TOP ' + @strRows + ' ' + @PK + @strSortColumn + ' FROM ' + @Tables + @strFilter + ' ' + @strGroup + ' ORDER BY ' + @Sort + ') AS ' + @PKTable + ' ORDER BY ' + @strSortDesc + '
  101.     
  102.     SELECT ' + @Fields + ' FROM ' + @Tables + ' JOIN @tblPK tblPK ON ' + @PK + ' = tblPK.PK ' + @strFilter + ' ' + @strGroup + ' ORDER BY ' + @Sort
  103.     )
  104.     end
  105. GO
  106. SET QUOTED_IDENTIFIER OFF 
  107. GO
  108. SET ANSI_NULLS ON 
  109. GO

方法4:分2000和2005

  1. Create PROCEDURE [dbo].[Basic_Pagination2000]
  2.     @tblName      varchar(255),   -- 表名
  3.     @fidlelist    varchar(2000),  --要查询字段
  4.     @fldName      varchar(255),   -- 排序字段
  5.     @PageSize     int,            -- 页尺寸
  6.     @PageIndex    int,            -- 页码
  7.     @IsReCount    bit,            -- 返回记录总数, 非 0 值则返回
  8.     @OrderType    bit,            -- 设置排序类型, 非 0 值则降序
  9.     @strWhere     varchar(1000)   -- 查询条件 (注意: 不要加 where)
  10. AS
  11. declare @strSQL   varchar(6000)       -- 主语句
  12. declare @strTmp   varchar(100),@tmpwhere  varchar(200)        -- 临时变量
  13. declare @strOrder varchar(400)        -- 排序类型
  14. if @OrderType != 0
  15. begin
  16.     set @strTmp = '<(select min'
  17.     set @strOrder = ' order by [' + @fldName +'] desc'
  18. end
  19. else
  20. begin
  21.     set @strTmp = '>(select max'
  22.     set @strOrder = ' order by [' + @fldName +'] asc'
  23. end
  24. set @tmpwhere='';
  25. if(@strWhere!='')
  26. begin
  27.    set @tmpwhere=' where '+@strWhere;
  28. end
  29. if @PageIndex = 1
  30. begin
  31.     set @strSQL = 'select top ' + str(@PageSize) +' '+@fidlelist+' '+'from ['
  32.         + @tblName + '] ' + @tmpwhere + ' ' + @strOrder
  33. end
  34. else
  35. begin
  36. set @strSQL = 'select top ' + str(@PageSize) + ' '+@fidlelist+' '+'from ['
  37.     + @tblName + '] where [' + @fldName + ']' + @strTmp + '(['
  38.     + @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['
  39.     + @fldName + '] from [' + @tblName + '] ' + @tmpwhere + ' '
  40.     + @strOrder + ') as tblTmp)  ' + @tmpwhere + ' ' + @strOrder
  41. end
  42. exec(@strSQL)
  43. if @IsReCount != 0
  44.     begin
  45.     set @strSQL = 'select count(*) as Total from [' + @tblName + ']'+ @strWhere
  46.     exec (@strSQL)
  47.    end
  48. ALTER PROCEDURE [dbo].[Basic_Pagination2005]
  49.   @tblName      nvarchar(200),     --表名
  50.   @fidlelist    nvarchar(1000),   --要查询字段
  51.   @fldName      nvarchar(100),    --排序字段
  52.   @PageSize     int,              --页尺寸
  53.   @PageIndex    int,              --页码
  54.   @IsReCount    bit ,             -- 返回记录总数, 非 0 值则返回
  55.   @OrderType    bit,              -- 设置排序类型, 非 0 值则降序
  56.   @strWhere nvarchar(1000)        --查询条件
  57. AS
  58.   declare @sqlstr nvarchar(4000),@tmpwhere nvarchar(4000),@tmporder nvarchar(100)
  59. BEGIN
  60.     if @OrderType != 0
  61.     begin
  62.         set @tmporder = @fldName +' desc '
  63.     end
  64.     else
  65.     begin
  66.         set @tmporder = @fldName +' asc '
  67.     end
  68.     set @tmpwhere='';
  69.     if(@strWhere!='')
  70.     begin
  71.        set @tmpwhere=' where '+@strWhere;
  72.     end
  73.     set @sqlstr=N'select * from(select  '+@fidlelist+', ROW_NUMBER() OVER(order by '+@tmporder+') as row from '+@tblName+@tmpwhere+') tmp where row between '+cast(((@PageIndex-1)*@PageSize+1) as nvarchar)+' and '+cast(@PageIndex*@PageSize as nvarchar);  
  74.     exec sp_executesql @sqlstr
  75.     if @IsReCount != 0
  76.     begin
  77.       set @sqlstr=N'select count(*) as Total from '+ @tblName+@tmpwhere
  78.       exec sp_executesql @sqlstr    
  79.     end
  80. END

方法5:这个比较有创意

 

  1. 使用系统表根据存储过程名字生成ADO.NET数据库访问代码 
  2. SET ANSI_NULLS ON
  3. GO
  4. SET QUOTED_IDENTIFIER ON
  5. GO
  6. ALTER   PROCEDURE [dbo].[sqltoolforexcuteandadapter]
  7. (
  8. @objName nvarchar(100),--存储过程名称
  9. @isexcute int --是否为execute 或者是sqladapter  0是execute,1是sqladapter
  10. )
  11. AS
  12. SET NOCOUNT ON
  13. DECLARE @parameterCount int
  14. DECLARE @errMsg varchar(100)
  15. DECLARE @parameterAt varchar(1)
  16. DECLARE @connName varchar(100)
  17. DECLARE @outputValues varchar(100)
  18. --Change the following variable to the name of your connection instance
  19. SET @connName='conn.Connection'
  20. SET @parameterAt=''
  21. SET @outputValues=''
  22. SELECT
  23.         dbo.sysobjects.name AS ObjName,
  24.         dbo.sysobjects.xtype AS ObjType,
  25.         dbo.syscolumns.name AS ColName,
  26.         dbo.syscolumns.colorder AS ColOrder,
  27.         dbo.syscolumns.length AS ColLen,
  28.         dbo.syscolumns.colstat AS ColKey,
  29.         dbo.syscolumns.isoutparam AS ColIsOut,
  30.         dbo.systypes.xtype
  31. INTO #t_obj
  32. FROM
  33.         dbo.syscolumns INNER JOIN
  34.         dbo.sysobjects ON dbo.syscolumns.id = dbo.sysobjects.id INNER JOIN
  35.         dbo.systypes ON dbo.syscolumns.xtype = dbo.systypes.xtype
  36. WHERE
  37.         (dbo.sysobjects.name = @objName)
  38.         AND
  39.         (dbo.systypes.status <> 1) 
  40. ORDER BY
  41.         dbo.sysobjects.name,
  42.         dbo.syscolumns.colorder
  43. SET @parameterCount=(SELECT count(*) FROM #t_obj)
  44. IF(@parameterCount<1) SET @errMsg='No Parameters/Fields found for ' + @objName
  45. IF(@errMsg is null)
  46.         BEGIN
  47.                 print 'SqlConnection conn = new SqlConnection("");
  48.             SqlCommand com = new SqlCommand("'+@objName+'", conn);'
  49.                 print 'com.CommandType = CommandType.StoredProcedure;'
  50.                 PRINT '   SqlParameter[] Parameters = new SqlParameter[' +
  51. cast(@parameterCount as varchar) + '];'
  52.                 PRINT ''
  53.                 DECLARE @source_name nvarchar,
  54.                                 @source_type varchar,
  55.                         @col_name nvarchar(100),
  56.                                 @col_order int,
  57.                                 @col_type varchar(20),
  58.                         @col_len int,
  59.                                 @col_key int,
  60.                                 @col_xtype int,
  61.                                 @col_redef varchar(20),
  62.                                 @col_isout tinyint
  63.                 DECLARE cur CURSOR FOR
  64.                 SELECT * FROM #t_obj
  65.                 OPEN cur
  66.                 -- Perform the first fetch.
  67.                 FETCH NEXT FROM cur INTO
  68. @source_name,@source_type,@col_name,@col_order,@col_len,@col_key,@col_isout,@col_xtype
  69.                         if(@source_type=N'U') SET @parameterAt='@'
  70.                         -- Check @@FETCH_STATUS to see if there are any more rows to fetch.
  71.                         WHILE @@FETCH_STATUS = 0
  72.                                 BEGIN
  73.                                 SET @col_redef=(SELECT CASE @col_xtype
  74.                                         WHEN 34 THEN 'Image'
  75.                                         WHEN 35 THEN 'Text'
  76.                                         WHEN 36 THEN 'UniqueIdentifier'
  77.                                         WHEN 48 THEN 'TinyInt'
  78.                                         WHEN 52 THEN 'SmallInt'
  79.                                         WHEN 56 THEN 'Int'
  80.                                         WHEN 58 THEN 'SmallDateTime'
  81.                                         WHEN 59 THEN 'Real'
  82.                                         WHEN 60 THEN 'Money'
  83.                                         WHEN 61 THEN 'DateTime'
  84.                                         WHEN 62 THEN 'Float'
  85.                                         WHEN 99 THEN 'NText'
  86.                                         WHEN 104 THEN 'Bit'
  87.                                         WHEN 106 THEN 'Decimal'
  88.                                         WHEN 122 THEN 'SmallMoney'
  89.                                         WHEN 127 THEN 'BigInt'
  90.                                         WHEN 165 THEN 'VarBinary'
  91.                                         WHEN 167 THEN 'VarChar'
  92.                                         WHEN 173 THEN 'Binary'
  93.                                         WHEN 175 THEN 'Char'
  94.                                         WHEN 231 THEN 'NVarChar'
  95.                                         WHEN 239 THEN 'NChar'
  96.                                         ELSE '!MISSING'
  97.                                         END AS C)
  98.                                 --Write out the parameter
  99.                                 PRINT '   Parameters[' + cast(@col_order-1 as varchar)
  100.                                     + '] = new SqlParameter("' + @parameterAt + @col_name
  101.                                     + '", SqlDbType.' + @col_redef
  102.                                     + ');'
  103.                                 --Write out the parameter direction it is output
  104.                                 IF(@col_isout=1)
  105.                                         BEGIN
  106.                                                 PRINT '   Parameters['+ cast(@col_order-1 as varchar)
  107. +'].Direction=ParameterDirection.Output;'
  108.                                                 SET @outputValues=@outputValues+'   ?=Parameters['+
  109. cast(@col_order-1 as varchar) +'].Value;'
  110.                                         END
  111.                                         ELSE
  112.                                         BEGIN
  113.                                                 --Write out the parameter value line
  114.                                                 PRINT '   Parameters['+ cast(@col_order-1 as varchar) + '].Value = ?;'
  115.                                         END
  116.                                 --If the type is a string then output the size declaration
  117.                                 IF(@col_xtype=231)OR(@col_xtype=167)OR(@col_xtype=175)OR(@col_xtype=99)OR(@col_xtype=35)
  118.                                         BEGIN
  119.                                                 PRINT '   Parameters[' + cast(@col_order-1 as varchar) +
  120. '].Size=' + cast(@col_len as varchar) + ';'
  121.                                         END
  122.                                  -- This is executed as long as the previous fetch succeeds.
  123.                         FETCH NEXT FROM cur INTO
  124. @source_name,@source_type,@col_name,@col_order,
  125. @col_len,@col_key,@col_isout,@col_xtype
  126.         END
  127.   PRINT ''
  128.   print '       com.Parameters.AddRange(Parameters);'
  129. if      @isexcute = 0 --使用的execute方法执行sql语句
  130. begin
  131.       print 'try
  132.             {
  133.                 conn.Open();
  134.                 com.ExecuteNonQuery();
  135.             }
  136.             catch (Exception ee)
  137.             {
  138.                 throw ee;
  139.             }
  140.             finally
  141.             {
  142.                 conn.Close();
  143.             }'
  144. end
  145. else if @isexcute = 1--需要返回数据集的话使用这个
  146. begin
  147.         print 'try
  148.             {
  149.                 da.Fill(ds);
  150.             }
  151.             catch (Exception ee)
  152.             {
  153.                 throw ee;
  154.             }
  155.             finally
  156.             {
  157.                //do what you want to do or dispose resoures.
  158.             }'
  159. end
  160.   CLOSE cur
  161.   DEALLOCATE cur
  162.  END
  163. if(LEN(@errMsg)>0) PRINT @errMsg
  164. DROP TABLE #t_obj
  165. SET NOCOUNT ON
  1. 测试代码: sqltoolforexcuteandadapter 'YourProcName',1--or 0
  2. 显示出来的结果是:
  3. SqlConnection conn = new SqlConnection("");
  4.             SqlCommand com = new SqlCommand("YourProcName", conn);
  5. com.CommandType = CommandType.StoredProcedure;
  6.    SqlParameter[] Parameters = new SqlParameter[1];
  7.    Parameters[0] = new SqlParameter("@yourparam", SqlDbType.VarChar);
  8.    Parameters[0].Value = ?;
  9.    Parameters[0].Size=6;
  10.        com.Parameters.AddRange(Parameters);
  11. try
  12.             {
  13.                 da.Fill(ds);
  14.             }
  15.             catch (Exception ee)
  16.             {
  17.                 throw ee;
  18.             }
  19.             finally
  20.             {
  21.                //do what you want to do or dispose resoures.
  22.             }

 

恩,方法很多,虽然有些都大同小异,争论点也很多,比如要不要拼接SQL语句。有人说损失性能比较大,但又没给出具体解决方案。还有就是有的遇到100W条记录的时候,分页只给显示到多少记录位置,恩,这个是很好提议。100W记录的话,确实没人会一条条的查看完整的。

 

呼。问题还多。。。还得自己整理。毕竟东西是别人的,拿来主意不太好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值