惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
Microsoft Azure Blog
Microsoft Azure Blog
G
Google Developers Blog
宝玉的分享
宝玉的分享
V
V2EX
MongoDB | Blog
MongoDB | Blog
S
SegmentFault 最新的问题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Microsoft Security Blog
Microsoft Security Blog
博客园 - 聂微东
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
IT之家
IT之家
Martin Fowler
Martin Fowler
大猫的无限游戏
大猫的无限游戏
Recent Announcements
Recent Announcements
人人都是产品经理
人人都是产品经理
博客园 - 司徒正美
美团技术团队
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
Hugging Face - Blog
Hugging Face - Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
罗磊的独立博客
B
Blog RSS Feed

博客园 - 七玄门

设置google搜索框默认文本 jQuery 表格插件 不再限于页面脚本 JavaScript挺入服务器端开发语言序列 实用的 JavaScript 测试及效验工具 那些相见恨晚的 JavaScript 技巧 一个简单功能的google地图 无法在Web服务器上启动调试。与Web服务器通信时出现身份验证错误 url重写—适用html为伪静态后真实的html无法访问的解决方法 - 七玄门 - 博客园 禁用浏览器缓存 - 七玄门 - 博客园 google搜索框添加关键字 千万数量级分页存储过程2(可支持多表查询,任意排序) 千万数量级分页存储过程1 js实现tab原理 http返回网页状态码查询 IIS 实现资源永久重定向(301)的常见参数 利用JS解决IE6PNG不透明 验证码生成示例 利用JavaScript更改input中radio和checkbox样式 翻页用户控件-1 - 七玄门 - 博客园
千万级通用的分页存储过程3
七玄门 · 2010-04-27 · via 博客园 - 七玄门

001 第一个方法: 

002   

003   

004 /* 

005   经测试,在 14483461 条记录中查询第 100000 页,每页 10 条记录按升序和降序第一次时间均为 0.47 秒,第二次时间均为 0.43 秒,测试语法如下: 

006   exec GetRecordFromPage news,newsid,10,100000 

007   news 为 表名, newsid 为关键字段, 使用时请先对 newsid 建立索引。 

008 */

009   

010 /* 

011   函数名称: GetRecordFromPage 

012   函数功能: 获取指定页的数据 

013   参数说明: @tblName      包含数据的表名 

014            @fldName      关键字段名 

015            @PageSize     每页记录数 

016            @PageIndex    要获取的页码 

017            @OrderType    排序类型, 0 - 升序, 1 - 降序 

018            @strWhere     查询条件 (注意: 不要加 where) 

019   作  者: 铁拳 

020   邮  箱: sunjianhua_kki@sina.com 

021   创建时间: 2004-07-04 

022   修改时间: 2004-07-04 

023 */

024 CREATE PROCEDURE GetRecordFromPage 

025     @tblName      varchar(255),       -- 表名 

026     @fldName      varchar(255),       -- 字段名 

027     @PageSize     int = 10,           -- 页尺寸 

028     @PageIndex    int = 1,            -- 页码 

029     @OrderType    bit = 0,            -- 设置排序类型, 非 0 值则降序 

030     @strWhere     varchar(2000) = ''  -- 查询条件 (注意: 不要加 where) 

031 AS 

032   

033 declare @strSQL   varchar(6000)       -- 主语句 

034 declare @strTmp   varchar(1000)       -- 临时变量 

035 declare @strOrder varchar(500)        -- 排序类型 

036   

037 if @OrderType != 0 

038 begin 

039     set @strTmp = '<(select min'

040     set @strOrder = ' order by [' + @fldName + '] desc'

041 end 

042 else

043 begin 

044     set @strTmp = '>(select max'

045     set @strOrder = ' order by [' + @fldName +'] asc'

046 end 

047   

048 set @strSQL = 'select top ' + str(@PageSize) + ' * from ['

049     + @tblName + '] where [' + @fldName + ']' + @strTmp + '(['

050     + @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['

051     + @fldName + '] from [' + @tblName + ']' + @strOrder + ') as tblTmp)'

052     + @strOrder 

053   

054 if @strWhere != ''

055     set @strSQL = 'select top ' + str(@PageSize) + ' * from ['

056         + @tblName + '] where [' + @fldName + ']' + @strTmp + '(['

057         + @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['

058         + @fldName + '] from [' + @tblName + '] where ' + @strWhere + ' '

059         + @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder 

060   

061 if @PageIndex = 1 

062 begin 

063     set @strTmp = ''

064     if @strWhere != ''

065         set @strTmp = ' where (' + @strWhere + ')'

066   

067     set @strSQL = 'select top ' + str(@PageSize) + ' * from ['

068         + @tblName + ']' + @strTmp + ' ' + @strOrder 

069 end 

070   

071 exec (@strSQL) 

072   

073 GO 

074   

075   

076   

077   

078   

079 第二个方法: 

080   

081 /*--用存储过程实现的分页程序 

082   

083 显示指定表、视图、查询结果的第X页 

084 对于表中主键或标识列的情况,直接从原表取数查询,其它情况使用临时表的方法 

085 如果视图或查询结果中有主键,不推荐此方法 

086   

087 */

088   

089 /*--调用示例 

090 exec p_show '地区资料' 

091   

092 exec p_show '地区资料',5,3,'地区编号,地区名称,助记码','地区编号' 

093 --*/

094   

095 /* 

096 因为要顾及通用性,所以对带排序的查询语句有一定要求.如果先排序,再出结果.就是: 

097   

098 exec p_show 'select top 100 percent * from 地区资料 order by 地区名称',5,3,'地区编号,地区名称,助记码','地区名称' 

099   

100   

101 --查询语句加上:top 100 percent //top时 

102 */

103   

104    

105   

106   

107 if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_show]') and OBJECTPROPERTY(id, N'IsProcedure') = 1) 

108 drop procedure [dbo].[p_show] 

109 GO 

110   

111 CREATE Proc p_show 

112 @QueryStr nvarchar(4000), --表名、视图名、查询语句 

113 @PageSize int=10, --每页的大小(行数) 

114 @PageCurrent int=1, --要显示的页 

115 @FdShow nvarchar (4000)='', --要显示的字段列表,如果查询结果有标识字段,需要指定此值,且不包含标识字段 

116 @FdOrder nvarchar (1000)='' --排序字段列表 

117 as

118 declare @FdName nvarchar(250) --表中的主键或表、临时表中的标识列名 

119 ,@Id1 varchar(20),@Id2 varchar(20) --开始和结束的记录号 

120 ,@Obj_ID int --对象ID 

121 --表中有复合主键的处理 

122 declare @strfd nvarchar(2000) --复合主键列表 

123 ,@strjoin nvarchar(4000) --连接字段 

124 ,@strwhere nvarchar(2000) --查询条件 

125   

126   

127 select @Obj_ID=object_id(@QueryStr) 

128 ,@FdShow=case isnull(@FdShow,'') when '' then ' *' else ' '+@FdShow end 

129 ,@FdOrder=case isnull(@FdOrder,'') when '' then '' else ' order by '+@FdOrder end 

130 ,@QueryStr=case when @Obj_ID is not null then ' '+@QueryStr else ' ('+@QueryStr+') a' end 

131   

132 --如果显示第一页,可以直接用top来完成 

133 if @PageCurrent=1  

134 begin 

135 select @Id1=cast(@PageSize as varchar(20)) 

136 exec('select top '+@Id1+@FdShow+' from '+@QueryStr+@FdOrder

137 return

138 end 

139   

140 --如果是表,则检查表中是否有标识更或主键 

141 if @Obj_ID is not null and objectproperty(@Obj_ID,'IsTable')=1 

142 begin 

143 select @Id1=cast(@PageSize as varchar(20)) 

144 ,@Id2=cast((@PageCurrent-1)*@PageSize as varchar(20)) 

145   

146 select @FdName=name from syscolumns where id=@Obj_ID and status=0x80 

147 if @@rowcount=0 --如果表中无标识列,则检查表中是否有主键 

148 begin 

149 if not exists(select 1 from sysobjects where parent_obj=@Obj_ID and xtype='PK') 

150 goto lbusetemp --如果表中无主键,则用临时表处理 

151   

152 select @FdName=name from syscolumns where id=@Obj_ID and colid in( 

153 select colid from sysindexkeys where @Obj_ID=id and indid in( 

154 select indid from sysindexes where @Obj_ID=id and name in( 

155 select name from sysobjects where xtype='PK' and parent_obj=@Obj_ID 

156 ))) 

157 if @@rowcount>1 --检查表中的主键是否为复合主键 

158 begin 

159 select @strfd='',@strjoin='',@strwhere=''

160 select @strfd=@strfd+',['+name+']'

161 ,@strjoin=@strjoin+' and a.['+name+']=b.['+name+']'

162 ,@strwhere=@strwhere+' and b.['+name+'] is null'

163 from syscolumns where id=@Obj_ID and colid in( 

164 select colid from sysindexkeys where @Obj_ID=id and indid in( 

165 select indid from sysindexes where @Obj_ID=id and name in( 

166 select name from sysobjects where xtype='PK' and parent_obj=@Obj_ID 

167 ))) 

168 select @strfd=substring(@strfd,2,2000) 

169 ,@strjoin=substring(@strjoin,5,4000) 

170 ,@strwhere=substring(@strwhere,5,4000) 

171 goto lbusepk 

172 end 

173 end 

174 end 

175 else

176 goto lbusetemp 

177   

178 /*--使用标识列或主键为单一字段的处理方法--*/

179 lbuseidentity:  

180 exec('select top '+@Id1+@FdShow+' from '+@QueryStr 

181 +' where '+@FdName+' not in(select top '

182 +@Id2+' '+@FdName+' from '+@QueryStr+@FdOrder 

183 +')'+@FdOrder 

184 ) 

185 return

186   

187 /*--表中有复合主键的处理方法--*/

188 lbusepk:  

189 exec('select '+@FdShow+' from(select top '+@Id1+' a.* from 

190 (select top 100 percent * from '+@QueryStr+@FdOrder+') a 

191 left join (select top '+@Id2+' '+@strfd+' 

192 from '+@QueryStr+@FdOrder+') b on '+@strjoin+'

193 where '+@strwhere+') a' 

194 ) 

195 return

196   

197 /*--用临时表处理的方法--*/

198 lbusetemp:  

199 select @FdName='[ID_'+cast(newid() as varchar(40))+']'

200 ,@Id1=cast(@PageSize*(@PageCurrent-1) as varchar(20)) 

201 ,@Id2=cast(@PageSize*@PageCurrent-1 as varchar(20)) 

202   

203 exec('select '+@FdName+'=identity(int,0,1),'+@FdShow+' 

204 into #tb from'+@QueryStr+@FdOrder+'

205 select '+@FdShow+' from #tb where '+@FdName+' between ' 

206 +@Id1+' and '+@Id2 

207 ) 

208   

209 GO 

210   

211   

212 程序代码调用 

213   

214  SqlConnection con=com.sqlcon; 

215     con.Open(); 

216     SqlCommand comm=new SqlCommand(); 

217     comm.CommandType=CommandType.StoredProcedure; 

218     comm.CommandText="p_show"; 

219     comm.Connection=con; 

220     comm.Parameters.Add("@QueryStr",System.Data.SqlDbType.VarChar,4000).Value="select * from web where 仓库编号 like '%"+this.DDLType.SelectedValue.Trim()+"%' and 名称 like '%"+this.txtName.Text.Trim()+"%' and 数量>"+Convert.ToInt32(this.txtQty.Text.Trim()); 

221     comm.Parameters.Add("@FdShow",System.Data.SqlDbType.VarChar,4000).Value="编号,名称,数量"; 

222     comm.Parameters.Add("@PageSize",System.Data.SqlDbType.Int).Value=this.pagesize; 

223     comm.Parameters.Add("@PageCurrent",System.Data.SqlDbType.Int).Value=Convert.ToInt32(ViewState["pageindex"]); 

224     comm.Parameters.Add("@FdOrder",System.Data.SqlDbType.VarChar,1000).Value=""; 

225                 

226     SqlDataAdapter ada=new SqlDataAdapter(comm); 

227     DataSet ds=new DataSet(); 

228     ada.Fill(ds,"temp"); 

229     this.DataGrid1.DataSource=ds.Tables["temp"].DefaultView; 

230     this.DataGrid1.DataBind(); 

231    con.Close();

来自:http://www.cnblogs.com/Leo_wl/archive/2010/04/26/1721613.html