成熟sql 分页存储过程(UP_General_GetOrderPage)
View Code
1 GO
2 /****** Object: StoredProcedure [dbo].[UP_General_GetOrderPage] Script Date: 03/17/2011 11:16:42 ******/
3 SET ANSI_NULLS ON
4 GO
5 SET QUOTED_IDENTIFIER ON
6 GO
7 ALTER PROCEDURE [dbo].[UP_General_GetOrderPage]
8 @tblName nvarchar(255), -- 表名
9 @strGetFields nvarchar(1000), -- 选择的字段列表以,分隔
10 @OrderFldName nvarchar(500), -- 排序字段以,分隔(不能含keyFldName指定的字段,可为空)
11 @orderFldDesc nvarchar(500), -- 排序字段及排序方向,如addDate desc,id desc(排序字段需通过selectOrderFldName指定,可为空)
12 @fldName nvarchar(255), -- 主键字段
13 @PageSize int = 10, -- 页尺寸
14 @PageIndex int = 1, -- 页码
15 @strWhere nvarchar(1000) = '', -- 查询条件(注意: 不要加where)
16 @RowCount int output
17 AS
18 declare @strWhereA nvarchar(1200) -- 临时变量,给sqlwhere加where
19 declare @strOrderA nvarchar(2000) -- 第一次排序类型
20 declare @strOrderB nvarchar(2000) -- 第二次排序类型
21 declare @strSqlA nvarchar(4000) -- 第一次选出
22 declare @strSqlB nvarchar(4000) -- 第二次选出
23 declare @strSQL nvarchar(4000) -- 最后选出
24
25 set @strSQL = 'select @RowCount=ISNULL(count(*),0) from ' + @tblName + ' where 1=1 '+@strWhere
26 exec sp_executesql @strSQL,N'@RowCount int output',@RowCount out
27
28 IF @RowCount=0
29 BEGIN
30 RETURN
31 END
32 --以上代码的意思是如果@doCount传递过来的不是0,就执行总数统计。以下的所有代码都是@doCount为0的情况
33 set @strSQL =''
34 /* 条件*/
35 if @strWhere != ''
36 set @strWhereA = ' where 1=1 ' + @strWhere
37 else
38 set @strWhereA = ''
39
40 /* 选择字段列表*/
41 if @strGetFields is null or rtrim(@strGetFields) = ''
42 set @strGetFields = '*'
43
44 /* 排序字段列表*/
45 if not(@OrderFldName is null or rtrim(@OrderFldName) = '')
46 if rtrim(@OrderFldName) = 'id'
47 set @OrderFldName = ''
48 else
49 set @OrderFldName = ',' + @OrderFldName
50
51 /* 构建order,按指定方式排序*/
52 if @orderFldDesc is null or rtrim(@orderFldDesc) = ''
53 set @orderFldDesc = ' order by id desc'
54 else
55 set @orderFldDesc = ' order by ' + @orderFldDesc
56 set @strOrderA = UPPER(@orderFldDesc)
57 set @strOrderB = replace(@strOrderA,'DESC','DESC1')
58 set @strOrderB = replace(@strOrderB,'ASC','DESC')
59 set @strOrderB = replace(@strOrderB,'DESC1','ASC')
60
61 /* 第一页*/
62 if @PageIndex = 1
63 set @strSQL = 'select top ' + str(@PageSize) + ' ' + @strGetFields + ' from [' + @tblName + '] with(nolock)' + @strWhereA + ' ' + @strOrderA
64 else
65 begin
66 --取得总记录数
67 declare @sql nvarchar(500)
68 declare @maxCount int
69 declare @maxPage int
70 declare @tempRowCount int
71 set @sql ='select @maxCount = count('+@fldName+') from [' + @tblName + ']' + @strWhereA
72 exec sp_executesql @sql,N'@maxCount int output',@maxCount output
73 set @maxPage = @maxCount / @PageSize
74 if(@maxCount % @PageSize > 0)
75 set @maxPage = @maxPage + 1
76 /* 最后一页*/
77 if @PageIndex >= @maxPage
78 begin
79 set @PageIndex = @maxPage
80 set @strSqlA = char(13) + '(select top '+str(@maxCount % @PageSize)+' ' + @fldName + @OrderFldName + ' from [' + @tblName + '] as a with(nolock) ' + @strWhereA + @strOrderB + ' )' + char(13)
81 set @strSqlB = char(13) + '(select ' + @fldName +' from ' + @strSqlA + ' as b )' + char(13)
82 set @strSQL = 'select ' + @strGetFields + ' from [' + @tblName + '] where ([' + @fldName + '] in '+@strSqlB+')' + @strOrderA + char(13)
83 end
84 else
85 begin
86 /* 不是第一页,也不是最后一页*/
87 if(@PageIndex <= @maxPage / 2)
88 begin
89 --前半数的页
90 set @tempRowCount = @PageIndex * @PageSize
91 /* 构建SQL,本分页算法的目的是为了实现高效的非主键排序的分页。by tony */
92 /* 1、先按指定字段+主键字段按降序选出perPage*pageNum条记录*/
93 set @strSqlA = char(13) + '(select top '+str(@tempRowCount)+' ' + @fldName + @OrderFldName + ' from [' + @tblName + '] as a with(nolock) ' + @strWhereA + @strOrderA + ' )' + char(13)
94 /* 2、再从选出的记录中按升序选出perPage条记录*/
95 set @strSqlB = char(13) + '(select top '+str(@PageSize)+' ' + @fldName + ' from ' + @strSqlA + ' as b ' + @strOrderB + ' )' + char(13)
96 /* 3、从数据库中选出主键在第二次选出的记录中的记录,按降序排列,分页完成*/
97 set @strSQL = 'select ' + @strGetFields + ' from [' + @tblName + '] where ([' + @fldName + '] in '+@strSqlB+')' + @strOrderA
98 end
99 else
100 begin
101 --后半数的页
102 set @tempRowCount = @maxCount - (@PageIndex -1) * @PageSize
103 /* 构建SQL,本分页算法的目的是为了实现高效的非主键排序的分页。by tony */
104 /* 1、先按指定字段+主键字段按降序选出perPage*pageNum条记录*/
105 set @strSqlA = char(13) + '(select top '+str(@tempRowCount)+' ' + @fldName + @OrderFldName + ' from [' + @tblName + '] as a with(nolock) ' + @strWhereA + @strOrderB + ' )' + char(13)
106 /* 2、再从选出的记录中按升序选出perPage条记录*/
107 set @strSqlB = char(13) + '(select top '+str(@PageSize)+' ' + @fldName + ' from ' + @strSqlA + ' as b ' + @strOrderA + ' )' + char(13)
108 /* 3、从数据库中选出主键在第二次选出的记录中的记录,按降序排列,分页完成*/
109 set @strSQL = 'select ' + @strGetFields + ' from [' + @tblName + '] where ([' + @fldName + '] in '+@strSqlB+')' + @strOrderA
110 end
111 end
112 end
113
114 set nocount on
115
116 /*print @strSQL*/ --显示SQL
117 exec (@strSQL)
118 set nocount off
119 RETURN