邹建的 sql server 分页存储过程 以备用

来源:互联网 发布:c4d mac 百度云 编辑:程序博客网 时间:2024/04/29 18:43
  1. IF OBJECT_ID(N'dbo.pagination') IS NOT NULL
  2.     DROP PROCEDURE dbo.pagination
  3. GO
  4. /**//*--实现分页的通用存储过程
  5.     显示指定表、视图、查询结果的第X页
  6.     对于表中主键或标识列的情况,直接从原表取数查询,其它情况使用临时表的方法
  7.     如果视图或查询结果中有主键,不推荐此方法
  8.     如果使用查询语句,而且查询语句使用了order by,则查询语句必须包含top 语句
  9. 最后更新时间: 2008.01.20
  10. --邹建 2003.09(引用请保留此信息)--*/
  11. /**//*--调用示例
  12. EXEC dbo.pagination 
  13.     @QueryStr = N'tb',
  14.     @PageSize = 5,
  15.     @PageCurrent = 3,
  16.     @FdShow = 'id, colid, name',
  17.     @FdOrder = 'colid, name'
  18. select id, colid from tb
  19. order by colid, name
  20. EXEC dbo.pagination 
  21.     @QueryStr = N'
  22. SELECT TOP 100 PERCENT 
  23.     * 
  24. FROM dbo.sysobjects
  25. ORDER BY xtype',
  26.     @PageSize = 5,
  27.     @PageCurrent = 2,
  28.     @FdShow = 'name, xtype',
  29.     @FdOrder = 'xtype, name'
  30. --*/
  31. CREATE PROC dbo.pagination
  32.     @QueryStr nvarchar(4000),        -- 表名、视图名、查询语句
  33.     @PageSize int=10,                -- 每页的大小(行数)
  34.     @PageCurrent int=1,                -- 要显示的页
  35.     @FdShow nvarchar (4000) = N'',    -- 要显示的字段列表,如果查询结果不需要标识字段,需要指定此值,且不包含标识字段
  36.     @FdOrder nvarchar (1000) = N''    -- 排序字段列表
  37. AS
  38. SET NOCOUNT ON
  39. DECLARE
  40.     @FdName sysname,    --表中的主键或表、临时表中的标识列名
  41.     @Id1 sysname,        --开始和结束的记录号
  42.     @Id2 sysname,
  43.     @Obj_ID int            --对象ID
  44. --表中有复合主键的处理
  45. DECLARE
  46.     @strfd nvarchar(2000),        --复合主键列表
  47.     @strjoin nvarchar(4000),    --连接字段
  48.     @strwhere nvarchar(2000)    --查询条件
  49. SELECT
  50.     @Obj_ID = OBJECT_ID(@QueryStr),
  51.     @FdShow = CASE 
  52.                 WHEN @FdShow > N'' THEN N' ' + @FdShow
  53.                 ELSE N' *'
  54.             END,
  55.     @FdOrder = CASE
  56.                 WHEN @FdOrder > N'' THEN N' ORDER BY ' + @FdOrder
  57.                 ELSE N' ' 
  58.             END,
  59.     @QueryStr = CASE
  60.                 WHEN @Obj_ID IS NULL THEN N' (' + @QueryStr + N')A'
  61.                 ELSE N' ' + @QueryStr
  62.             END
  63. -- 如果显示第一页,可以直接用 top 来完成
  64. IF @PageCurrent = 1    
  65. BEGIN
  66.     SELECT 
  67.         @Id1 = CAST(@PageSize as varchar(20))
  68.     EXEC(N'
  69. SELECT TOP ' + @Id1 + N'
  70.     ' + @FdShow + N'
  71. FROM ' + @QueryStr + N'
  72. ' + @FdOrder
  73. )
  74.     RETURN
  75. END
  76. -- 如果是表, 则检查表中是否有标识更或主键
  77. IF @Obj_ID IS NULL OR OBJECTPROPERTY(@Obj_ID, 'IsTable') = 0
  78.     GOTO lb_usetemp
  79. ELSE
  80. BEGIN
  81.     SELECT
  82.         @Id1 = CAST(@PageSize as varchar(20)),
  83.         @Id2 = CAST((@PageCurrent - 1) * @PageSize as varchar(20))
  84.     -- 标识列
  85.     SELECT
  86.         @FdName = name
  87.     FROM dbo.syscolumns
  88.     WHERE id = @Obj_ID
  89.         AND status = 0x80
  90.     IF @@ROWCOUNT = 0            --如果表中无标识列,则检查表中是否有主键
  91.     BEGIN
  92.         DECLARE
  93.             @pk_number int
  94.         SELECT
  95.             @strfd = N'',
  96.             @strjoin = N'',
  97.             @strwhere = N''
  98.         SELECT
  99.             @strfd = @strfd 
  100.                     + N',' + QUOTENAME(name),
  101.             @strjoin = @strjoin 
  102.                     + N' AND A.' + QUOTENAME(name) 
  103.                     + N'=B.' +  QUOTENAME(name),
  104.             @strwhere = @strwhere 
  105.                     + N' AND B.' + QUOTENAME(name) + N' IS NULL'
  106.         FROM(
  107.             SELECT
  108.                 IX.id, IX.indid,
  109.                 IXC.colid, ixc.keyno,
  110.                 C.name
  111.             FROM dbo.sysobjects O, 
  112.                 dbo.sysindexes IX,
  113.                 dbo.sysindexkeys IXC,
  114.                 dbo.syscolumns C
  115.             WHERE O.parent_obj = @Obj_ID
  116.                 AND O.xtype = 'PK'
  117.                 AND O.name = IX.name
  118.                 AND IX.id = @Obj_ID
  119.                 AND IX.id = IXC.id
  120.                 AND IX.indid = IXC.indid
  121.                 AND IXC.id = C.id
  122.                 AND IXC.colid = C.colid
  123.         )A
  124.         ORDER BY keyno
  125.         SELECT
  126.             @pk_number = @@ROWCOUNT,            
  127.             @strfd = STUFF(@strfd, 1, 1, N''),
  128.             @strjoin = STUFF(@strjoin, 1, 5, N''),
  129.             @strwhere = STUFF(@strwhere, 1, 5, N'')            
  130.         IF @pk_number = 0
  131.             GOTO lb_usetemp        --如果表中无主键,则用临时表处理
  132.         ELSE IF @pk_number = 1
  133.         BEGIN
  134.             SELECT
  135.                 @FdName = @strfd
  136.             GOTO lb_useidentity    -- 使用单一主键
  137.         END
  138.         ELSE
  139.             GOTO lb_usepk        -- 使用复合主键
  140.     END
  141. END
  142. /**//*--使用标识列或主键为单一字段的处理方法--*/
  143. lb_useidentity:    
  144. EXEC(N'
  145. SELECT TOP ' + @Id1 + N'
  146.     ' + @FdShow + N'
  147. FROM '+@QueryStr + N'
  148. WHERE ' + @FdName + ' NOT IN(
  149.         SELECT TOP ' + @Id2 + N'
  150.             ' + @FdName + '
  151.         FROM ' + @QueryStr + N'
  152.         ' + @FdOrder + N')
  153. ' + @FdOrder + N'
  154. ')
  155. RETURN
  156. /**//*--表中有复合主键的处理方法--*/
  157. lb_usepk:        
  158. EXEC(N'
  159. SELECT 
  160.     ' + @FdShow + N'
  161. FROM(
  162.     SELECT TOP ' + @Id1 + N'
  163.         A.*
  164.     FROM ' + @QueryStr + N' A
  165.         LEFT JOIN(
  166.                 SELECT TOP ' + @Id2 + N'
  167.                     ' + @strfd + N' 
  168.                 FROM ' + @QueryStr + N'
  169.                 ' + @FdOrder + N'
  170.             )B
  171.                 ON ' + @strjoin + N'
  172.     WHERE ' + @strwhere + N'
  173.     ' + @FdOrder + N'
  174. )A
  175. ' + @FdOrder + N'
  176. ')
  177. RETURN
  178. /**//*--用临时表处理的方法--*/
  179. lb_usetemp:        
  180. SELECT
  181.     @FdName = QUOTENAME(N'ID_' + CAST(NEWID() as varchar(40))),
  182.     @Id1 = CAST(@PageSize * (@PageCurrent-1) as varchar(20)),
  183.     @Id2 = CAST(@PageSize * @PageCurrent-1 as varchar(20))
  184. EXEC(N'
  185. SELECT 
  186.     ' + @FdName + N' = IDENTITY(int, 0, 1),
  187.     ' + @FdShow + N'
  188. INTO #tb
  189. FROM(
  190.     SELECT TOP 100 PERCENT 
  191.         * 
  192.     FROM ' + @QueryStr + N'
  193.     ' + @FdOrder + N'
  194. )A
  195. ' + @FdOrder + N'
  196. SELECT 
  197.     ' + @FdShow + N'
  198. FROM #tb 
  199. WHERE ' + @FdName + ' BETWEEN ' + @Id1 + ' AND ' + @Id2 + N'
  200. '
  201. )
  202. GO

原创粉丝点击