1 ----------------------------------------------------------------------------------------------------- 2 --TOP n 实现的通用分页存储过程 3 CREATE PROC sp_PageView( 4 @tbname sysname, --要分页显示的表名 5 @FieldKey NVARCHAR(1000), --用于定位记录的主键(惟一键)字段,可以是逗号分隔的多个字段 6 @PageCurrent INT=1, --要显示的页码 7 @PageSize INT=10, --每页的大小(记录数) 8 @FieldShow NVARCHAR(1000)='', --以逗号分隔的要显示的字段列表,如果不指定,则显示所有字段 9 @FieldOrder NVARCHAR(1000)='', --以逗号分隔的排序字段列表,可以指定在字段后面指定DESC/ASC 用于指定排序顺序 10 @Where nvarchar(1000)='', --查询条件 11 @PageCount INT OUTPUT --总页数 12 ) 13 AS 14 SET NOCOUNT ON 15 --检查对象是否有效 16 17 IF OBJECT_ID(@tbname) IS NULL 18 BEGIN 19 RAISERROR(N'对象"%s"不存在', 1, 16, @tbname) 20 RETURN 21 END 22 23 24 IF OBJECTPROPERTY(OBJECT_ID(@tbname), N'IsTable') = 0 25 AND OBJECTPROPERTY(OBJECT_ID(@tbname), N'IsView') = 0 26 AND OBJECTPROPERTY(OBJECT_ID(@tbname), N'IsTableFunction') = 0 27 BEGIN 28 RAISERROR(N'"%s"不是表、视图或者表值函数', 1, 16, @tbname) 29 RETURN 30 END 31 32 --分页字段检查 33 IF ISNULL(@FieldKey, N'')='' 34 BEGIN 35 RAISERROR(N'分页处理需要主键(或者惟一键)', 1, 16) 36 RETURN 37 END 38 39 --其他参数检查及规范 40 IF ISNULL(@PageCurrent, 0) < 1 41 SET @PageCurrent = 1 42 43 IF ISNULL(@PageSize,0) < 1 44 SET @PageSize = 10 45 46 IF ISNULL(@FieldShow, N'') = N'' 47 SET @FieldShow = N'*' 48 49 IF ISNULL(@FieldOrder, N'') = N'' 50 SET @FieldOrder = N'' 51 ELSE 52 SET @FieldOrder = N'ORDER BY ' + LTRIM(@FieldOrder) 53 54 IF ISNULL(@Where, N'') = N'' 55 SET @Where = N'' 56 ELSE 57 SET @Where = N'WHERE ('+@Where+N')' 58 59 60 61 --如果@PageCount为NULL值,则计算总页数(这样设计可以只在第一次计算总页数, 62 --以后调用时,把总页数传回给存储过程,避免再次计算总页数,对于不想计算总页数的处理而言,可以给@PageCount赋值) 63 IF @PageCount IS NULL 64 BEGIN 65 DECLARE @sql NVARCHAR(4000) 66 SET @sql=N'SELECT @PageCount=COUNT(*)' 67 + N' FROM ' + @tbname 68 + N' ' + @Where 69 EXEC sp_executesql @sql, N'@PageCount int OUTPUT', @PageCount OUTPUT 70 SET @PageCount = (@PageCount + @PageSize-1) / @PageSize 71 END 72 73 --计算分页显示的TOPN值 74 DECLARE @TopN VARCHAR(20), @TopN1 VARCHAR(20) 75 SELECT @TopN = @PageSize, 76 @TopN1 = (@PageCurrent-1) * @PageSize 77 78 --第一页直接显示 79 IF @PageCurrent = 1 80 EXEC(N'SELECT TOP ' + @TopN 81 + N' ' + @FieldShow 82 +N' FROM ' + @tbname 83 + N' ' + @Where 84 + N' ' + @FieldOrder) 85 ELSE 86 BEGIN 87 --处理别名 88 IF @FieldShow = N'*' 89 SET @FieldShow = N'a.*' 90 91 --生成主键(惟一键)处理条件 92 DECLARE @Where1 nvarchar(4000), 93 @Where2 nvarchar(4000), 94 @s nvarchar(1000), 95 @Field sysname 96 97 SELECT @Where1=N'', @Where2=N'', @s=@FieldKey 98 WHILE CHARINDEX(N',',@s) > 0 99 100 SELECT @Field = LEFT(@s, CHARINDEX(N',',@s)-1), 101 @s = STUFF(@s, 1, CHARINDEX(N',',@s), N''), 102 @Where1 = @Where1 + N' AND a.' + @Field + N'=b.' + @Field, 103 @Where2 = @Where2 + N' AND b.' + @Field + N' IS NULL', 104 @Where = REPLACE(@Where, @Field, N'a.' + @Field), 105 @FieldOrder = REPLACE(@FieldOrder, @Field, N'a.' + @Field), 106 @FieldShow = REPLACE(@FieldShow, @Field, N'a.' + @Field) 107 108 109 SELECT @Where = REPLACE(@Where, @s, N'a.' + @s), 110 @FieldOrder = REPLACE(@FieldOrder, @s, N'a.' + @s), 111 @FieldShow = REPLACE(@FieldShow, @s, N'a.' + @s), 112 @Where1 = STUFF(@Where1 + N' AND a.' + @s + N'=b.' + @s, 1, 5, N''), 113 @Where2 = CASE 114 WHEN @Where = '' THEN N'WHERE (' ELSE @Where + N' AND (' END + N'b.' + @s + N' IS NULL' + @Where2 + N')' 115 116 117 118 --执行查询 119 EXEC(N'SELECT TOP ' + @TopN 120 + N' ' + @FieldShow 121 + N' FROM ' + @tbname 122 + N' a LEFT JOIN(SELECT TOP ' + @TopN1 123 + N' ' + @FieldKey 124 + N' FROM ' + @tbname 125 + N' a ' + @Where 126 + N' ' + @FieldOrder 127 + N')b ON ' + @Where1 128 + N' ' + @Where2 129 + N' ' + @FieldOrder) 130 END
另,一个查询的思路
1 m:代表总记录数(m>0) 2 n:代表每页显示N条记录(n>0) 3 page:代表当前页(page从0开始) 4 求总页数:(m%n)==0?(m/n):(m/n+1); 5 6 select top n * from 表名 where id not in(select top (n*page) id from 表名 order by 排序) order by 排序