各位兄弟姐妹,这个程序再oracle、mysql上执行没任何问题
其中:$where为条件,currentPage为当前页码,totalRecords为记录总数,numPerPage为页记录数
在oracle、mysql上可以返回正确的记录总数,但在sqlserver上返回记录总数为-3,是何原因啊?
应该如何去改正呢?谢谢各位了!
public static List query(String $where, Integer currentPage,
AIInteger totalRecords, int numPerPage) {
List templist = new ArrayList();
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = MyDBHelper.getConnection();
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery(sql);
rs.last(); //1>处
totalRecords.setValue(rs.getRow()); //2>处
System.out.println("current page:= " + currentPage.toString() +
"; total:= " +
totalRecords + "; numPerPage:= " + numPerPage);
if (currentPage.intValue() > 1)
rs.absolute( (currentPage.intValue() - 1) * numPerPage);
else
rs.beforeFirst();
rs.setFetchSize(numPerPage);
while (rs.next()) {
、
、
、
tempList.add(temp);
numPerPage--;
}
rs.close();
stmt.close();
}
catch (SQLException ex) {
while (ex != null) {
System.out.println("Message :" + ex.getMessage());
}
}
catch (java.lang.Exception ex) {
ex.printStackTrace();
}
//释放一个连接到连接池
finally {
try {
conn.close();
}
catch (SQLException sqle) {
}
}
return tempList;
} 问题点数:100、回复次数:5Top
sqlserver uses top clause!
mysql uses limit clause!
oracle uses row_num function
using cursor is unefficientTop
有可能是rs.last();的问题
你试试next循环计数Top
兄弟,能说的具体些吗?怎么改正呢?
Top
csdn有多个关于rs.first(), rs.last()问题的
它有时总不能得到期望的结果(与数据库有关,与数据库返回类型表关,如表或光标)
这个好像都没有一个合理的解释或解决方案
要解决你的问题,可用
select count(*) recc form 表 where 条件
来先预查记录数Top
获得resultset之后
int counter = 0;
while(resultset.next())
counter++;
来获得总记录数,或者也可以参考楼上的方法
last、first等方法经常会有问题Top
如题.
问题点数:100、回复次数:8Top
搜索一下。太多了。CREATE PROCEDURE pagination2
(
@SQL nVARCHAR(4000), --不带排序语句的SQL语句
@Page int, --页码
@RecsPerPage int, --每页容纳的记录数
@ID VARCHAR(255), --需要排序的不重复的ID号
@Sort VARCHAR(255) --排序字段及规则
)
AS
DECLARE @Str nVARCHAR(4000)
SET @Str='SELECT TOP '+CAST(@RecsPerPage AS VARCHAR(20))+' * FROM '+@SQL+' T WHERE T.'+@ID+' NOT IN
(SELECT TOP '+CAST((@RecsPerPage*(@Page-1)) AS VARCHAR(20))+' '+@ID+' FROM '+@SQL+' T9 ORDER BY '+@Sort+') ORDER BY '+@Sort
PRINT @Str
EXEC sp_ExecuteSql @Str
GOTop
type refCursorType is REF CURSOR; --游标类型定义,用于返回数据集
procedure sp_Page(p_PageSize int, --每页记录数
p_PageNo int, --当前页码,从 1 开始
p_SqlSelect varchar2, --查询语句,含排序部分
p_OutRecordCount out int,--返回总记录数
p_OutCursor out refCursorType)
as
v_sql varchar2(3000);
v_count int;
v_heiRownum int;
v_lowRownum int;
begin
----取记录总数
v_sql := 'select count(*) from (' || p_SqlSelect || ')';
execute immediate v_sql into v_count;
p_OutRecordCount := v_count;
----执行分页查询
v_heiRownum := p_PageNo * p_PageSize;
v_lowRownum := v_heiRownum - p_PageSize + 1;
v_sql := 'SELECT *
FROM (
SELECT A.*, rownum rn
FROM ('|| p_SqlSelect ||') A
WHERE rownum <= '|| to_char(v_heiRownum) || '
) B
WHERE rn >= ' || to_char(v_lowRownum) ;
--注意对rownum别名的使用,第一次直接用rownum,第二次一定要用别名rn
OPEN p_OutCursor FOR v_sql;
end sp_Page;
Top
谢谢上面二位,谢谢!
我的意思是要一个适合大数据量的高效的解决方案。而且是C#连ORACLE的。oracle是不是不支持top呀?
to jxufewbt(我的目标是5星) ,这个可以查询,但是,这样数据库好像要把数据一次取出来然后生成一个临时表。如果数据量大的时候会很慢。
我想,我的这个问题肯定有很多人在作项目的时候都会遇到,而且也应该有很多人有比较理想的解决方法。由于我不太懂,又是初次使用C#语言,所以希望能有人多加指点。感激不尽!
Top
顶上去Top
使用SI object browser能更方便的管理和操作oracle数据库,效率也更好,有关资料网上很多Top
希望有更多的人参与讨论。
星期天的早晨也不可以睡懒觉,我要努力顶啊顶。Top
顶上去Top
select * from t_table where rowid not in(select rowid from t_table where rownum<=200) and rownum<=200
从第201条记录开始处取200条记录Top
在网上看了很多很多的分页算法,一般的算法几万条的时候速度相当的不错,可当记录增加到百万级的时候,速度就慢了很多,现在想和大家讨论一下千万级的数据库分页算法,请大家仅管提出自已的看法 问题点数:0、回复次数:50Top
1.Mysql,use limit
2.MsSql,use temp table
3.Oracle,use rownumTop
用JDBC的数据缓冲和连接池技术,优化数据库的索引等等都可以起到一定的作用Top
可否再详细点,我学jsp没多久Top
关注 .......!Top
连接池技术可能都很熟悉了,所谓的缓冲技术是指把一部分数据读取到应用程序服务器的缓存中,客户端的相关的查询都在应用程序服务器中执行,需要新的 数据才去连接数据库服务器,Oracle的JDBC就支持这种技术;优化索引是很常见的一种方法,不过不同的数据库有不同的效果,越是数据量大效果越明 显。
个人意见,仅供参考Top
从程序中考虑:比如用数据缓冲和连接池技术
从数据库服务器端考虑:比如csdn只选出前300行纪录,因为用户不需要那么多纪录。你也不必把1000万条全部分页。你也不必把纪录放在一个表中,一 年(太多就一个月)的数据放一张表或定期把历史数据导出到数据数据仓库中,不要用一张表装1000万条记录。做好索引。优化查询!尽量少用模糊查询,避免 表扫描。不能让客户端连续多次搜索(csdn就是)Top
楼上有道理。可以学学csdnTop
感谢大家提供了这么多的好思路,另外还想问一下,怎样在一个表中插入随机记录,我想做个1000万条记录的表,我的存储过程不是很熟Top
你用的是什么数据库?Top
你要随机记录的作用是什么了
我觉得用序号就可以了
比方说,如果你用的是oracle那么你建一个长为20位的序号,你这一辈子都别想用到重复的.Top
sql server数据库
大家看看这条sql语句怎么样啊
select top "+pagesize+" * from hisfsjour where id not in (select top "+(currpage*pagesize)+" id from hisfsjour)
当在前面几页时,速度相当的快啊Top
lynx1111(任我行):你说的那个我以前也想过,但我始终觉的不是最好的解决之道Top
starfeng(feng) :随机记录的目的是为了建立一个一千万条的记录,我不想用delphi写个小程序,只想用存储过程做到Top
从用户的角度来讲我认为不会有哪个用户有耐性去浏览这么大数量的页面,能看几十页已经是很有耐性的人了.Top
upTop
不太懂缓冲技术,谁能讲一讲呀Top
dennis03(葳蕤):我只想探讨一下技术
现在还有一个解新决方案
每次翻页的时候记录一下最后一条记录的id号
然后select top 10 * form tablename where id>xxx
这样即使数据量再大也不怕Top
http://www.csdn.net/develop/read_article.asp?id=15464
http://www.csdn.net/develop/Read_Article.asp?Id=18730
http://www.csdn.net/develop/Read_Article.asp?Id=16268Top
对于数据分页,已经有现成的模式可以使用——Value list模式:http://java.sun.com/blueprints/patterns/ValueListHandler.htmlTop
http://www.csdn.net/develop/read_article.asp?id=15464
这个还不错,前面几页的时候速度很快,后面就不行了
http://www.csdn.net/develop/Read_Article.asp?Id=18730
http://www.csdn.net/develop/Read_Article.asp?Id=16268
这个主要是jive而且好像是oracle,我用的是sql server
Top
upTop
joy_wind(wind):我只大概看了一下,请问到哪下载那个javabeanTop
如果数据量大,可以用list取全部记录写到内存的方式Top
TO红透半天天, 你已经提出了假设“如果数据量大”,这个大是怎么个大法呢?比如一个城市一天的市话话单,一个省一天的短信日志。。也就一天一两个T的存储,我看你怎么“list取全部记录写内存”?
如果数据量小的话,按我个人的经验,在1万条记录以下,倒是可以放到内存里面。
上次就有牛人狂推荐这样那样的“最佳分页方案”,到后来又在OTN上看到oracle推荐的OracleCacheRowset办法,结果一试就吐血。
应用服务器找了台IBM的服务器,4颗至强cpu,内存配的是2个G,本机带10块SCSI硬盘,做成raid5,后面用光纤接到一个SAN上面,跑oracle 9iAS,操作系统是w2k ad server。
数据库是oracle工程师过来配的oracle 8.1.7,用两台SUN的小型机做双机,存储接的是一个EMC的阵列。
测试的时候做了个简单的表,一个id一个name,两个字段,写了段pl/sql代码for循环了40万次灌记录。
用了四种办法做分页:A方案,用滚动的记录集。也就是很多牛人介绍的移到last(),取记录总数,再移回来到某一行。B方案,用oracle的 OracleCacheRowset,大致原理是先取出记录集,然后灌到CacheRowset里面去,这样的话,close掉记录集也没关系了。C方 案,用oracle的同志们通用的三层select语句嵌套,按rownum分页的办法。D方案,按2001年程序员合订本上介绍的,使用rank()分 析函数来处理的办法。
刚开始测试的时候想BT些,数据库没有做索引,没有做任何优化手段。
测试结果:
A方案折腾了半天,机器象死了一样,键盘鼠标都没用,大概20分钟左右,出来一个outofmermory。
B方案比A方案死得还要彻底,快绝望的时候也给你来个outofmermory
C方案出来最快,不管从哪一页(实际上是从第几条到第几条),最多的时候就0.2s左右。
D方案并不是太理想,4000s左右,终于出来了。
接着对库做了一些简单的优化,也就是在ID上做了索引,调了一下oracle提供的一个dbms的包(我不是做DBA的,这一块不熟)
测试结果:
A方案B方案照死不误,没见一丁点好转。
C方案应该是更快一些,不过没找到更高精确度的衡量办法:)
D方案倒是快了一点,最快的时候降到5s左右
(BTW:两台服务器属于备机)Top
zxhong(红透半边天):数据量大时,再大的内存也吃不消啊
rootwuyu(wuyu):看了你评论,非常的精彩啊,不过你能不能做个更大的数据库测一下,还有就是你用的是Oracle,sql server怎么办啊Top
最近在做测试时,发现加了order by 和不加order by速度相差太大,不知各位有没有这样的感觉,加入了order by之后速度会变的很慢Top
应该如此阿
多做了一次操作呢
Top
直接顺序分页怎么都好说limit page*pagesize,(page+1)*pagesize;
到序大家做过吗???尤其mysql不支持order by和limit合用,~~~~~~~~~~~~~Top
to wsyab(瘦瘦男--炒饭)
你用sql嵌套就是了,先查了limit的,再order byTop
加了order by 之类肯定会慢,order by rownum会比order by 字快快,order by 到没有索引的字段会比较慢,这一点建议看csdn上前段时间有人翻译的“oracle sql性能优化系列”。虽然是讲oracle的,但是有些东西对informix、sybase和sqlserver也还是有参考价值的。
至于mysql嘛,随便折腾了,实在不行你干脆把库放在内存里面得了,反正再怎么的我也不信会有人拿来跑中型应用的。
BTW:我没研究过mysql,不过据朋友说mysql的limit是先全部取到内存,再在内存里面分(小道消息,不以为证)
Top
“你用sql嵌套就是了,先查了limit的,再order by”
应该是先order by了再limit吧?
Top
UP rootwuyu(wuyu)的敬业精神Top
大家也讨论一下sql server啊,我现在用的是sql server数据库Top
starfeng(feng) && rootwuyu(wuyu)
我不太明白你们说得意思,例如:
表test,字段id排倒序,怎么写??
不会是取出来成另个临时字段,两个select吧
Top
建议你直接使用Hibernate,里面有直接分页的函数,而且是针对不同数据库做了速度优化的,非常爽!例如ORCAL采用的SQL语句与SQL SERVER的语句是不同的。Top
我介绍一种不错的分页方法吧:
如果你的页面要显示20条记录,我就只是选第1条到第20条记录,然后你按‘下一页’时,我就选第21条到30条记录,如此类推。
大概的实现方法如下(数据库为:oralce):
不要一下子把所有符合条件的记录选出来,我的意思是说:你从jsp里传几个参数,
<a href="a.jsp?NextPage=2&RowsPage=10">下一页</a>
//其中NextPage:下一页的页码;RowsPage:每页显示的记录数;
1) 这样你可以先计算出符合条件的记录数目:
String lCountSql = "select count(*) as rowcount from ("+sSql+")";
rs = st.executeQuery(lCountSql);
int iCounts = 0;
if(rs.next())
iCounts = rs.getInt("rowcount");
2)获得你传过来的参数,并做处理:
int nRowPage = request.getParameter("RowsPage")==null?0:Integer.parseInt(request.getParameter("RowsPage"));
int nPage = request.getParameter("NextPage")==null?0:Integer.parseInt(request.getParameter("NextPage"));
if(nRowPage<1) nRowPage=10;
int nPages = (iCount-1)/nRowPage+1;
if (nPages<1) nPages=1;
if (nPage>nPages) nPage=nPages;
if (nPage<1) nPage=1;
3)进一步处理,
int nStartRow = 0;
int nEndRow = nRowPage;
if(nPage>1){
nStartRow = (nPage-1)*nRowPage+1;
nEndRow = nPage*nRowPage;
}
String sSql_1 = "select a.* from (select b.*,rownum rn from("+sSql+") b where rownum <= "+nEndRow+") a where rn >= "+nStartRow;
4)取得你想要的数据:
rs = st.executeQuery(sSql_1);
while(rs.next())
{
//
}
PS:你原来的SQL语句得按一定顺序排序,所选的数据才会正确,而且要oracle9i及以上版本才支持(select b.*,rownum rn from("+sSql+") 中sSql里有order by 语句的。Top
写错了,应该是:
我就选第21条到40条记录,如此类推。
...Top
ejbcreate():目前我用的是sql server 有没有好解吗?Top
BluePenguin():你指的Hibernate是什么?可否详细说一下Top
Hibernate是个非常好用的O/R开源项目:http://hibernate.bluemars.net/
最近刚有了中文论坛:http://hibernate.fankai.com/
最新消息,Hibernate已经归入JBOSS计划,但仍然自成一个子项目,不会影响单独使用。Top
在查询分页代码中使用Hibernate的一大好处是,既兼顾了查询分页的性能,同时又保证了代码在不同的数据库之间的可移植性。Top
gzTop
前面的大部分例子只适用于简单的的查询,对于多表的的不定条件的查询很麻烦Top
markTop
千万级的数据库,有分页的意义吗?对于用户来说就是信息的海洋了,去看看Google怎么做的吧,
根本就不存在如何分页的问题,如果一个结果有千万条,那跟没有结果一样是没有一样.应该是统计条数,取出,前N条进行分页,如果到地还在准备分页的话,再次取结果n,进行分页.并且在其间推荐用户进行递进式搜索,来降低信息量,才式正确的.Top
学习Top
我有一个方法:(对于喜欢用select * 的同行可能有用)
先检索出来,符合条件的所有 id (唯一标识)放在内存里
然后根据当前页数和每页多少行纪录 去内存中取 id号的当前集
根据当前集 中的某一条 去数据库中检索相应的数据行
这里建议使用编译预处理PrepareStatement
将结果放进数据类 (如果你的数据只有两列当然可以省略这一步)
然后把数据类添加进 ArrayList 或者HashMap
然后 把载页面上输出 ArrayList 或者HashMap 的数据
这样做,是因为只检索一列数据 要比检索多类要快得多 占用更少的内存。
一次只精确定位一条纪录 要比一次取出多条要快,这里的瓶颈在于频繁的与数据库交互,但是我们使用编译预处理可以很大程度上提高性能。Top
lifejoy(山外青衫):分析的非常好啊,我很同意你的观点,但是还想讨论一下技术Top
强烈关注!Top
http://www.hnitline.com/bbs/dispbbs.asp?boardID=18&ID=807
目前最好的分页技术
思想确实很好,看看就知道了!
Top