最新评论

共2页: 1 2 下一页 
分页: [url=http://www.cnblogs.com/huyong/archive/2010/12/18/1910253.html]http://www.cnblogs.com/huyong/archive/2010/12/18/1910253.html[/url]
Re:MaxMind的GeoIP應用 Ray.BH 2011-03-24 11:38  
location是神马
-- 生成执行SQL时必须的语句 select @sort = @sort + ',' select @tempwhere = '' while CHARINDEX(',',@sort) > 0 begin select @temp = substring(@sort,0,CHARINDEX(',',@sort)) select @temp = replace(@temp,' desc','') select @temp = replace(@temp,' asc','') select @setVariableName = @setVariableName + '@' + ltrim(replace(@temp,'.','')) + '=Convert(nvarchar(300),' + @temp + ',21),' select @variableName = @variableName + '@' + ltrim(replace(@temp,'.','')) + ' nvarchar(300),' --print @variableName if @tempwhere <> '' begin select @where = @where + ' or (' + right(@tempwhere,len(@tempwhere)-4) end select @where = @where + ' and ' + @temp if CHARINDEX(' desc',@sort) <> 0 begin select @where = @where + ' <= @' + ltrim(replace(@temp,'.','')) end else begin select @where = @where + ' >= @' + ltrim(replace(@temp,'.','')) end if @tempwhere <> '' begin select @where = @where + ')' end select @tempwhere = @tempwhere + ' and ' + @temp + ' = @' + ltrim(replace(@temp,'.','')) select @sort = substring(@sort,CHARINDEX(',',@sort)+1,len(@sort)) end select @variableName = left(@variableName,len(@variableName)-1) select @setVariableName = left(@setVariableName,len(@setVariableName)-1) select @where = '(' + substring(@where,6,len(@where))+ ')' --print @where --print @setVariableName --print @variableName -- 设置RowCount declare @strStartRow int Select @strStartRow = ((@CurrentPage - 1)*@PageSize + 1) Set RowCount @strStartRow --print @sql -- 最终执行Sql select @temp = 'DECLARE ' + @variableName + ' SET ROWCOUNT ' + Convert(nvarchar(20),@strStartRow) + ' Select ' + @setVariableName + ' from (' + left(@Sql,@orderbylocation) + ') as t ' + substring(@sql,@orderbylocation,len(@sql)) + ' SET ROWCOUNT ' + Convert(nvarchar(20),@PageSize) + ' ' --print @temp --print @sql --print @wherelocation if @wherelocation <> 0 select @temp = @temp + STUFF(@sql,@wherelocation+7,0,@where + ' and ') else begin if @groupbylocation <> 0 select @temp = @temp + STUFF(@sql,@groupbylocation + 1,0,' where ' + @where + ' ') else if @orderbylocation <> 0 select @temp = @temp + STUFF(@sql,@orderbylocation + 1,0,' where ' + @where + ' ') end exec(@temp) --print @temp end end
你这个如何多表连接查询?如果嵌套SELECT? 给个我写的万能通用的给你看下.晕,还太长了,分两次发. /*************************************************************** 分页存储过程 Create BY Tellov 2008-05-28 tellov@gmail.com 注意:使用本存储过程,SQL语句中必须要带有Order BY 子句 支持多表链接查询,支持别名,支持嵌套SELECT语句 注:语句中如果带有group by ,则页总数和记录数无法正确统计 -- Modify BY Tellov 2008-12-10 修正了多字段排序且序不同时分页会出现返回数据集不正确的问题 -- Moidfy By Tellov 2009-08-03 修正了出现此种嵌套(select *,(select count(1) from b) c from a)时此存储过程会报错的BUG *************************************************************** 参数说明: 1.@sql 查询语句 2.@CurrentPage 当前页 3.@PageSize 页大小 4.@Counts 查询到的记录总数 5.@pageCount 页总数 ***************************************************************/ Alter PROCEDURE [dbo].[Sp1_Exec_Page] ( @Sql nvarchar(4000), -- 要执行的SQL语句 @CurrentPage int = 1, -- 当前页 @PageSize int = 30, -- 每页纪录数 @counts int output, -- 纪录总数 @pageCount int output -- 页总数 ) --WITH ENCRYPTION AS Set Lock_TimeOut 2000 declare @sort nvarchar(500) declare @variableName nvarchar(300) declare @setVariableName nvarchar(2000) declare @where nvarchar(4000) declare @temp nvarchar(max) declare @tempwhere nvarchar(2000) select @sql = replace(@sql,' ',' ') select @where = '' select @setVariableName = '' select @variableName = '' -- 取出orderBy if CHARINDEX(' order by ',@sql) = 0 begin select '使用此存储过程时查询语句中必须带上order by 子句'; end else begin declare @wherelocation int,@orderbylocation int,@groupbylocation int -- 取最后一个order by 的位置 select @orderbylocation = CHARINDEX(' order by ',@sql) while CHARINDEX(' order by ',@sql,@orderbylocation+10) <> 0 begin select @orderbylocation = CHARINDEX(' order by ',@sql,@orderbylocation+10) end -- 默认当前页 IF @CurrentPage < 1 SET @CurrentPage = 1 -- 获取总行数 select @temp = left(@Sql,@orderbylocation) select @temp = 'Select @counts = count(1) from ( ' + @temp + ') as __tt' --print @temp exec sp_executesql @temp,N'@counts int output',@counts output -- 获取总分页数 If @counts < @pageSize Select @pageCount = 1 else Select @pageCount = ((@Counts-1) / @pageSize) +1 -- 提高效率,如果是第一页直接返回 if @CurrentPage = 1 begin declare @returntemp nvarchar(4000) select @returntemp = 'select top ' + convert(nvarchar(20),@pageSize) + substring(@sql,CHARINDEX('select ',@sql) + 6,len(@sql)) exec(@returntemp) --print @returntemp end else begin -- 取最后一个WHERE的位置 select @wherelocation = CHARINDEX(' where ',@sql) while @wherelocation <> 0 and CHARINDEX(' on ',@sql,@wherelocation + 7) <> 0 begin select @wherelocation = CHARINDEX(' where ',@sql,@wherelocation + 7) end -- 取最后一个group by 的位置 select @groupbylocation = CHARINDEX(' group by ',@sql) while CHARINDEX(' group by ',@sql,@groupbylocation+10) <> 0 begin select @groupbylocation = CHARINDEX(' group by ',@sql,@groupbylocation+10) end select @sort = substring(@sql,@orderbylocation+10,len(@sql))
re: sql行列转换 Harlan 2009-03-31 08:39  
@侯唯

谢谢了!我试试!
re: sql行列转换 BillGan 2009-03-30 23:34  
如果你用SQL 2005,可以用PIVO实现,具体你可以搜索PIVO关键字;
如果你用SQL 2000/2005,这个方法都可以,用case 判断要转行的列名,拼接下SQL语句,代码也很少,很通用,这个你也可以搜索得到,要是在公司,我上个项目做报表还有保存的列子,呵呵。
re: sql行列转换 侯唯 2009-03-30 21:54  
public DataTable GetList()
{
DataTable dtKC = new DataTable();//表1的结构
DataTable dtCJ = new DataTable();//表1的列表
DataTable dtTX = new DataTable();//从表1中取出同学列表
DataTable dtDate=new DataTable();//从表1中取出日期列表

DataTable dt = new DataTable();
dt.Columns.Add("序号", typeof(int));
dt.Columns.Add("名称",typeof(string));
dt.Columns.Add("课程",typeof(string));
for (int i = 0; i < dtDate.Rows.Count; i++)
{
dt.Columns.Add(dtDate.Rows[i]["日期"].ToString(), typeof(string));
}
int n = 1;
for (int j = 0; j < dtTX.Rows.Count; j++)
{

for (int i = 1; i < dtKC.Columns.Count - 1; i++)
{
DataRow dr = dt.NewRow();
dr["序号"] = n;
dr["名称"] = dtTX.Rows[j]["名称"];
dr["课程"] = dtKC.Columns[i].ColumnName;
for (int m = 0; m < dtDate.Rows.Count; m++)
{
dr[dtDate.Rows[i]["日期"].ToString()] = dtCJ.Select("(名称=" + dr["名称"] + ") and (日期=" + dtDate.Rows[m]["日期"] + ")")[0][i];
dt.Rows.Add(dr);
}
}
}
return dt;
}

试一下看看,我没有测试,不过想来是可以的。这几天有做过类似的。
不知道当数据库中有大量重复的数据的时候,且排序字段偏偏又要以重复字段为准是:
点到下一页的时候是不是没反映,老是在那一页
@蜀山雪狼
真是个聪明的人啊!
强烈鄙视那些只说自己的如何好的,不贴代码的。
楼主的这个不错。
在大的项目也没有全部显示出来的。
re: 海量存储过程(500w数据,分页只需2秒) 赖文华(SWPU小赖) 2008-06-06 00:14  
谢谢楼主分享,如果有朋友有更好的方法,请分享!
请第一楼的,还有 "没剑"这位仁兄把你们的海量数据分页方法贴出来啊,别老是在这里忽悠.支持楼主
学习。。
re: 页面刷新特征 新.NET革命武装战士 2008-05-17 10:16  
已经拿下了
re: 页面刷新特征 Eve 2008-05-17 03:11  
抄自《Asp.net 2.0高级编程》
这里:http://book.csdn.net/bookfiles/172/1001727755.shtml
re: 页面刷新特征 Anders Liu 2008-05-16 18:43  
这一缺陷自Web编程最先出现时就已经存在了,ASP.NET无疑不会引入它。

——ASP.NET到底引入没引入这个缺陷?
re: 页面刷新特征 dddddddddddd 2008-05-16 16:55  
一看排版就知道是转载的,建议拿下来~
re: 页面刷新特征 丁学 2008-05-16 15:23  
原来是个转载,还是个二级转载
re: 页面刷新特征 lswweb1 2008-05-16 15:04  
。。。。。。。。。。。。。。。。。。。。。。
这个最下边左角的这个“顶”也来了。。
re: 利用js方法实现html静态页面间参数传递 簡簡單單.. 2008-05-14 10:38  
封装很好..
我收一下了
2s太慢了,呵呵
re: 海量存储过程(500w数据,分页只需2秒) 蜀山雪狼 2008-05-04 20:17  
--引用--------------------------------------------------
badnewfish: 我没做过这样的应用,但是我笨笨的一想,每次取一页的数据就可以了!
点“下一页”时再去取下一页的!
呵呵!
--------------------------------------------------------
你太有才了。
我没做过这样的应用,但是我笨笨的一想,每次取一页的数据就可以了!
点“下一页”时再去取下一页的!
呵呵!
re: 海量存储过程(500w数据,分页只需2秒) 倒霉孩子 2008-05-04 13:42  
都是垃圾,没事爱找别人的错,如果行的话,就把代码穿上去分享一下
我也来晒晒我目前用到的两个存储过程:http://www.cnblogs.com/zhengyulu-2008/articles/1095534.html
top 10000,多余的查出来也没人看
不知道把500w数据分页来做什么?给人看?给电脑看? 还是用来做什么? 谁会这样看数据? 谁/那一类人有这个需求? 或在什么情况下会用得上? 你做这个功能的给谁用啊?
楼主,我的分页存储过程和你的类似,但没要求排序的字段必须是主键




/****** 对象: 存储过程 dbo.sp_Paging 脚本日期: 2007-11-27 9:43:17 ******/




/****** 对象: 存储过程 dbo.sp_Paging 脚本日期: 2007-4-27 13:19:03 ******/

/*
分页存储过程(来源于网络,经过修改以适应多表联合查询)

注意:该存储过程和和网络上其他分页存储过程一样,存在经典的SQL注入漏洞; 不论在asp/asp.net等中调用时,
都要把 @strWhere参数中的非法字符(逗号过滤掉)
*/

CREATE PROCEDURE sp_Paging
@tblName varchar(255) , -- 表名
@strGetFields varchar(1000) = '*', -- 需要返回的列
@fldName varchar(255)='', -- 主关键字字段名
@orderfield varchar(255)='', -- 排序的字段名
@pageSize int = 10, -- 页尺寸
@pageIndex int = 1, -- 页码
@recordCount int = 0 output, -- 返回记录总数
@pageCount int = 0 output, --分页总数
@orderType int = 0, -- 设置排序类型, 非 0 值则降序
@strWhere varchar(1500) = '' -- 查询条件 (注意: 不要加 where)
AS
declare @strSQL nvarchar(3000) -- 主语句
declare @strTmp varchar(110) -- 临时变量
declare @strOrder varchar(400) -- 排序类型

begin
if @strWhere !=''
set @strSQL = 'select @recordCount = count(*) from ' + @tblName + ' where '+@strWhere
else
set @strSQL = 'select @recordCount = count(*) from ' + @tblName
end

exec sp_executesql @strSQL,N'@recordCount int out ',@recordCount out

if @recordCount % @pageSize = 0
set @pageCount = @recordCount / @pageSize
else
set @pageCount = @recordCount / @pageSize + 1
--以上代码的意思是计算出记录是总数和求出总共的页数

begin
if @orderType != 0
begin
set @strTmp = '<(select min'
set @strOrder = ' order by ' + @orderfield +' desc'
--如果@orderType不是0,就执行降序,这句很重要!
end
else
begin
set @strTmp = '>(select max'
set @strOrder = ' order by ' + @orderfield +' asc'
end

if @pageIndex = 1
begin
if @strWhere != ''

set @strSQL = 'select top ' + str(@pageSize) +' '+@strGetFields+ ' from ' + @tblName + ' where ' + @strWhere + ' ' + @strOrder
else

set @strSQL = 'select top ' + str(@pageSize) +' '+@strGetFields+ ' from '+ @tblName + ' '+ @strOrder
--如果是第一页就执行以上代码,这样会加快执行速度
end
else
begin
if @strWhere != ''
set @strSQL = 'select top ' + str(@pageSize) +' '+@strGetFields+ ' from '
+ @tblName + ' where ' + @fldName + '' + @strTmp + '('
+ substring(@fldName, charindex('.',@fldName)+1, len(@fldName)) + ') from (select top ' + str((@pageIndex-1)*@pageSize) + ' '
+ @fldName + ' from ' + @tblName + ' where ' + @strWhere + ' '
+ @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder
else
set @strSQL = 'select top ' + str(@pageSize) +' '+@strGetFields+ ' from '
+ @tblName + ' where ' + @fldName + '' + @strTmp + '('
+ substring(@fldName, charindex('.',@fldName)+1, len(@fldName)) + ') from (select top ' + str((@pageIndex-1)*@pageSize) + ' '
+ @fldName + '  from ' + @tblName + '' + @strOrder + ') as tblTmp)'
+ @strOrder
end
end
print @strSQL
exec sp_executesql @strSQL

GO
--引用--------------------------------------------------
搞IT的狐狸: 另外在 SQL里 != 是错误的用法 请用 &lt;&gt;
--------------------------------------------------------
好像 mssql 2005 可以
我觉得不考虑查询条件不同的分页SP的效率应该差不了多少,如果加入各种各样的查询条件,差别可能就比较大了。我觉得根据特定的表写特定的分页SP,效率可能会好些。
--引用--------------------------------------------------
kiler: 分页的问题还是要转变一下观念啊,问题在于要不要对所有的500w条数据分页,都显示出来客户看得了吗,他会从头点到尾吗,还不就是看前几页,想看后面的数据,设定排序条件反序排一下还是前几页,只对前5000条进行分页不行吗?
--------------------------------------------------------
赞同这个做法,淘宝也是只给出了前100页的数据。
re: 海量存储过程(500w数据,分页只需2秒) 留恋星空 2008-05-03 21:25  
有更好的方式么?如果非得是SQL 2000?
re: 海量存储过程(500w数据,分页只需2秒) 曲滨*銘龘鶽 2008-05-03 19:57  
SQL server 2000 本来在在设计上对分页类操作就是有缺陷的怎么也不行
SQL server 2005 虽然加了 row_number() 不过使用起来没有其他数据库如oracle 哪么方便,不过相对的容易很多;

不过 SQL server 嵌套查询这里做的不好,
比如子查询不能排序等
使得好多复杂查询很难做通用的分页查询。

期待 2008 有好转
re: 用反射来解决字段多带来的烦恼(转自论坛) 金色海洋(jyk) 2008-05-03 19:52  
你的这个想法挺好

只是兜了一个大圈子。

想象我们要的是什么?就是一个 insert into ......

字符串——字段名——控件名——实体类——反射——赋值——组合sql语句


ps:
组合sql语句 这一步可以用很放反方来实现,比如 ORM LinQ 了什么的。

想想 中间的步骤是必需的吗?
添加与删除用一个表统计总数后再分页在海量数据必须这么做,你那么做只对一半--读取总记录数
SET ROWCOUNT 1
SELECT @Count = Count
FROM BaseInfo_TheEmployee_Count
if @@ROWCOUNT <> 1
begin
set @Return = -6
return -6
end
if @@error <> 0
begin
set @Return = -7
return -7
end
--计算总页数
set @OutPage = dbo.CountPage(@Count, @SetPageRows)
--页码大于总页码侧修饰为数据总数计算分页页码
if @SetPage > @OutPage set @SetPage = @OutPage
--计算对后一页余数值
set @PageMin = dbo.CountTopMin(@Count,@SetPageRows,@SetPage,@OutPage)
--计算页码
set @PageMax = (@SetPage * @SetPageRows)
--读取员工信息与一寸相片与身份证复印件
if @ShowPhoto = 1 and @ShowIDCardPhoto = 1
if @Order = 1
begin
--重新设定读取行数
SET ROWCOUNT @PageMin
SELECT TOP (@PageMin) TheEmployeeID, TheEmployeeName, CreatedDate, Auditing,
UniqueNumber, Sex, Tel, Number, EnterDutyDate, DateOfBirth,
EducateTheBackgroundTypeID, HouseholdRegister, IDCard, TheEmployeeTypeID,
MobilePhone, StandbyTel, Address, State, Email, FixedWage, ZipCode, Remark,
SalaryAccountNumber, DepartmentTypeID, Piecework, BusinessMember, HeadshipTypeID,
DimissionState, IDCardPhoto, IDCardPhotoImageType, Photo, PhotoImageType
FROM (SELECT TOP (@PageMax) TheEmployeeID, TheEmployeeName, CreatedDate, Auditing,
UniqueNumber, Sex, Tel, Number, EnterDutyDate, DateOfBirth,
EducateTheBackgroundTypeID, HouseholdRegister, IDCard,
TheEmployeeTypeID, MobilePhone, StandbyTel, Address, State, Email,
FixedWage, ZipCode, Remark, SalaryAccountNumber, DepartmentTypeID,
Piecework, BusinessMember, HeadshipTypeID, DimissionState, IDCardPhoto,
IDCardPhotoImageType, Photo, PhotoImageType
FROM (SELECT BaseInfo_TheEmployee.TheEmployeeID,
BaseInfo_TheEmployee.TheEmployeeName,
BaseInfo_TheEmployee.CreatedDate, BaseInfo_TheEmployee.Auditing,
BaseInfo_TheEmployee.UniqueNumber, BaseInfo_TheEmployee.Sex,
BaseInfo_TheEmployee.Tel, BaseInfo_TheEmployee.Number,
BaseInfo_TheEmployee.EnterDutyDate,
BaseInfo_TheEmployee.DateOfBirth,
BaseInfo_TheEmployee.EducateTheBackgroundTypeID,
BaseInfo_TheEmployee.HouseholdRegister,
BaseInfo_TheEmployee.IDCard,
BaseInfo_TheEmployee.TheEmployeeTypeID,
BaseInfo_TheEmployee.MobilePhone,
BaseInfo_TheEmployee.StandbyTel, BaseInfo_TheEmployee.Address,
BaseInfo_TheEmployee.State, BaseInfo_TheEmployee.Email,
BaseInfo_TheEmployee.FixedWage, BaseInfo_TheEmployee.ZipCode,
BaseInfo_TheEmployee.Remark,
BaseInfo_TheEmployee.SalaryAccountNumber,
BaseInfo_TheEmployee.DepartmentTypeID,
BaseInfo_TheEmployee.Piecework,
BaseInfo_TheEmployee.BusinessMember,
BaseInfo_TheEmployee.HeadshipTypeID,
BaseInfo_TheEmployee.DimissionState,
BaseInfo_TheEmployee_IDCardPhoto.IDCardPhoto,
BaseInfo_TheEmployee_IDCardPhoto.IDCardPhotoImageType,
BaseInfo_TheEmployee_Photo.Photo,
BaseInfo_TheEmployee_Photo.PhotoImageType
FROM BaseInfo_TheEmployee INNER JOIN
BaseInfo_TheEmployee_IDCardPhoto ON
BaseInfo_TheEmployee.TheEmployeeID = BaseInfo_TheEmployee_IDCardPhoto.TheEmployeeID
INNER JOIN
BaseInfo_TheEmployee_Photo ON
BaseInfo_TheEmployee.TheEmployeeID = BaseInfo_TheEmployee_Photo.TheEmployeeID)
AS a
ORDER BY TheEmployeeID) AS b
ORDER BY TheEmployeeID DESC
if @@ROWCOUNT <> @PageMin
begin
set @Return = -8
return -8
end
if @@error <> 0
begin
set @Return = -9
return -9
end
set @Return = @PageMin
return @PageMin
end
尊重楼主的努力,希望大家评论时语言温和点,博客园是个交朋友的地方,大家要共同营造和谐的气氛!
这个分页算我现在用着!不过就会出你非唯一建排序而导致错误的结果的情况。郁闷。
re: 海量存储过程(500w数据,分页只需2秒) 金色海洋(jyk) 2008-05-03 18:03  
不知道lz有没有看到
http://www.cnblogs.com/jyk/archive/2008/04/29/1175808.html

http://www.cnblogs.com/jyk/archive/2007/05/31/766908.html

可以参考一下,这是一个分页控件,有源码,还有分页算法。

500w 数据 count(1) 一下,不会超过 800毫秒的。

我的分页控件

cpu:xp3000+ 单核
内存:DDR2 1G
硬盘:串口

测试用数据库:SQL Server2000 里的 Northwind 数据库里的 Products 表,就是自带的那个。
显示数据的控件:DataGrid 自动填充字段的方式。

记录数:2523136条。
一页显示5条记录。


//分页算法1 单字段排序,且排序字段是聚集索引。
//1000 页以内 15毫秒
//10000页以内 30毫秒
//50000页以内 100多毫秒
//100000页以内 200多毫秒
//最后几页 第一次跳转到 4秒多
//最后几页 连续向前翻页 1秒156毫秒

//页号大范围跳转的时候需要的时间比较长,但是也小于1秒,同时SQL Server 占用的内存有所增加 120M。最后几页时达到320M

===================================================================
以下是多排序字段的分页情况,排序字段是 UnitPrice,ProductID

//分页算法2 无索引 首页 8秒187毫秒 。
//10 页以内 2秒812毫秒
//速度太慢下面的就不测试了

//分页2 非聚集索引 UnitPrice 首页 468毫秒
//10 页以内 2秒671毫秒
//速度太慢下面的就不测试了


//分页算法2 非聚集索引 UnitPrice,ProductID 首页 500毫秒
//10 页以内 2秒796毫秒
//100页以内 4秒796毫秒
//速度太慢下面的就不测试了


//分页算法2 非聚集索引 UnitPrice,ProductID desc 首页 500毫秒
//10 页以内 0-15毫秒
//100页以内 15-46毫秒
//1000页以内 31-62毫秒
//10000页以内 100毫秒左右
//50000页以内 400-500毫秒
//100000页以内 900毫秒左右
//最后几页 第一次跳转到 4秒421毫秒
//最后几页 连续向前翻页 4秒375毫秒

//页号大范围跳转的时候需要的时间比较长,但是也小于1秒,
//这回SQL Server 占用的内存增加幅度不大 120M左右

海量存储我认为应该在百万以上。
想法是好,但是你没测试过反射带来的效率是多么的低吧,呵呵
你们都忽略机器性能的可比性.
re: 海量存储过程(500w数据,分页只需2秒) Angel Lucifer 2008-05-03 16:11  
看来有必要讨论一下这个话题,呵呵。
最鄙视那些直说别人的如何如何差又不放自己的代码人。
如果觉得别人如何差,把自己好的放上来啊。
sqlserver2005已经引入了新的处理办法,升级以下吧
另外,如果想简单建议使用rowcount呵呵
cnblogs 没有创新了?
再有 N久前 这代码就是别人发过的了
500W就是海量?
共2页: 1 2 下一页 

导航

公告

昵称:Harlan---
园龄:3年9个月
粉丝:1
关注:0
<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

统计

搜索

 
 

常用链接

我的标签

随笔分类(42)

随笔档案(21)

最新评论

阅读排行榜

评论排行榜

推荐排行榜