`

oracle分页需要注意的地方

阅读更多
oracle分页查询
关键是:rownum

可以关心下:rowid

注意点:

直接使用rownum是要受到限制的。但是很容易遇到这样的需求“查出符合条件的第xx条到第xx条记录”,比如页面的分页处理。这 个时候如何构造出适合自己的结果集?







在查询中,我们可以注意到,类似于“select xx from table where rownum < n”(n>1)这样的查询是有正确含义的,而“select xx from table where rownum = n”这样的查询只在n=1的时候成立,“select xx from table where rownum > n”(n>1)这样的查询只能得到一个空集。另外“select xx from table where rownum > 0”这个查询会返回所有的记录。这是为什么呢?原因就在于Oracle对rownum的处理上,rownum是在得到结果集的时候产生的,用于标记结果集 中结果顺序的一个字段,这个字段被称为“伪数列”,也就是事实上不存在的一个数列。它的特点是按顺序标记,而且是逐次递加的,换句话说就是只有有 rownum=1的记录,才可能有rownum=2的记录。

让我们回头来分析一下在where中使用rownum作为查询条件的情况。在rownum取=1,或者rownum <= n (n>1)的时候,没有问题。那么为什么当条件为rownum = n或者rownum >= n时明明有数据却只能得到一个空集呢?假设我们的查询条件为rownum = 2,那么在查询出的第一条记录的时候,oracle标记此条记录rownum为1,结果发现和rownum=2的条件不符,于是结果集为空。写到这里,我 忽然有一个有趣的想法:假如有一条查询语句为select xx,yy from table where zz > 20 and rownum < 10,那么在执行的时候,是先按照zz>20的条件查询出一个结果集,然后按照rownum取出前10条返回?还是在按照zz>20的条件先 查询,然后有一个记录就标记一个rownum,到rownum<10的时候就停止查询?我觉得应该是后者,也就是在执行语句的时候,不是做full scan,而是取够数据就停止查询。要验证这个想法应该很简单,找一个数据量非常大的表进行查询就可以了。可惜目前我没有这样的表。

我们可以看出,直接使用rownum是要受到限制的。但是很容易遇到这样的需求“查出符合条件的第xx条到第xx条记录”,比如页面的分页处理。这 个时候如何构造出适合自己的结果集?嗯,墙边那位说全取出来手工挑选的哥们可以拉出去了。当然这样做也是可以的,但是前提是整个数据集的数据条数不多的情 况下。假如遇到上十万百条的数据,全部取出来的话,用户就不用干别的事情了。这个时候用户应该怎么做呢?当然就是要用到我们介绍的rownum 拉!rownum不是个“伪数列”么,好说,我们现在把它弄成一个实在的字段就可以了。

具体做法就是利用子查询,在构建临时表的时候,把rownum也一起构造进去。比如“select xx,yy from (select xx,yy,rownum as xyz from table where zz >20) where xyz between 10 and 20”这样就可以了。另外使用oracle提供的结果集处理函数minus也可以做到,例如“select xx,yy from table where zz > 20 and rownum <20 minus select xx,yy from table where zz>20 and rownum <10”,但是使用minus好像比使用子查询更加消耗资源。

和rownum相似,oracle还提供了另外一个伪数列:rowid。不过rowid和rownum不同,一般说来每一行数据对应的rowid是 固定而且唯一的,在这一行数据存入数据库的时候就确定了。可以利用rowid来查询记录,而且通过rowid查询记录是查询速度最快的查询方法。(这个我 没有试过,另外要记住一个长度在18位,而且没有太明显规律的字符串是一个很困难的事情,所以我个人认为利用rowid查询记录的实用性不是很 大)rowid只有在表发生移动(比如表空间变化,数据导入/导出以后),才会发生变化。
分享到:
评论

相关推荐

    Oracle分页存储过程

    "Oracle分页存储过程"就是将分页查询的逻辑封装到一个存储过程中,使得在多个地方调用分页查询时更为便捷。 创建一个简单的分页存储过程,我们可以定义两个输入参数:一个是起始记录的索引(通常为1),另一个是每...

    JSP+JDBC_真分页(基于Oracle数据库分页)笔记

    这意味着将首页、上一页、下一页和尾页等元素封装成一个独立的JSP或Java组件,然后在需要分页的地方直接引入这个组件。这样不仅可以减少代码量,还能方便地为组件添加额外的功能,如每页记录数的自定义、快速跳转等...

    mybatis分页拦截器

    同时,为了提高效率,拦截器应该尽量避免对所有查询都进行分页处理,而是只在需要分页的地方应用。 除了自定义拦截器,还有一些成熟的MyBatis分页插件可供选择,如PageHelper、MyBatis-Plus等,它们提供了更便捷的...

    mybatis分页实现1

    此外,这种方法也不能很好地复用 SQL 代码,当有多个地方需要分页查询时,可能需要重复编写类似的 SQL。 为了克服这些局限,开发者可以选择使用 MyBatis 的拦截器插件,如 PageHelper 插件。PageHelper 提供了一种...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    说明:Oracle中需要创建用户一定是要具有dba(数据库管理员)权限的用户才能创建,而且创建的新用户不具备任何权限,连登录都不可以。 用法:create user 新用户名 identified by 密码 例子: 2. 修改密码 说明:...

    实现分页存储过程pdf...........

    - 由于存储过程中包含了动态生成的SQL语句,需要注意SQL注入等问题。在实际应用中,应确保传入的参数经过严格的校验和过滤。 5. **优化建议**: - 在不影响灵活性的前提下,可以考虑使用静态SQL语句,以提高查询...

    AspNetPager.dll

    提出了与众不同的解决asp.net中分页问题的方案,即将分页导航功能与数据显示功能完全独立开来,由用户自己控制数据的获取及显示方式,因此可以被灵活地应用于任何需要实现分页导航功能的地方,如为GridView、...

    NHibernate 实例

    在Global.asax.cs文件中注册NHibernate会话工厂,然后在需要的地方创建会话实例,执行查询、添加、更新和删除操作。同时,注意事务管理,确保数据一致性。 在C/S环境下,通常使用Windows Forms或WPF,同样需要在...

    mysql found_row()使用详解

    需要注意的是,`SQL_CALC_FOUND_ROWS`必须在`LIMIT`之前出现,并且`FOUND_ROWS()`必须在`SELECT`语句之后立即调用,否则它将返回0。 在实际使用中,如果你遇到`FOUND_ROWS()`总是返回1的情况,这可能是因为你没有...

    java面试题

    创建多个线程并通过共享变量进行数据操作,需要注意线程安全问题,避免数据竞争和死锁。 ### 17. JDBC数据库操作 使用JDBC可以连接数据库,执行SQL查询,处理结果集等数据库操作。 ### 18. 文件流读取 通过`...

    MyBatisCodeHelper-Pro2.8.7代码生成自动生成

    - **使用**:在需要生成代码的地方右键选择"MyBatisCodeHelper",按照提示操作即可生成所需代码。 3. **最佳实践**: - 在项目初始化阶段,利用插件导入所有表结构,快速搭建基本的DAO层和Service层。 - 对于...

    使用数据绑定浏览数据库记录 编程小实例

    1. 数据源:在C++ .NET中,数据源通常是数据库(如SQL Server、SQLite或Oracle),或者是XML文件或其他可以提供数据的对象。数据源是应用程序获取和存储数据的地方。 2. ADO.NET:Microsoft的ADO.NET库是连接到...

    北大青鸟学士后第三单元OA办公自动化管理系统

    先在src下的jdbc.properties中配置数据库的信息(本项目使用的是Oracle) 再使用com.chen.common包中的CreateTable.java 建表,再往用户表添加一个管理员账户 就可以使用了(一定要记得添加permit的值要为1 本身页面中...

    以数据源方式导出Excel文件,C++.net源代码编写,VisualStudio.net

    数据源可以是任何能够提供结构化数据的地方,如SQL Server数据库、Oracle数据库、XML文件或内存中的数据结构。在C++.NET中,通常会使用ADO.NET(ActiveX Data Objects .NET)框架来连接和操作这些数据源。 接下来,...

    2009达内SQL学习笔记

    包含信息:想选择什么表,从什么地方选择。必须要有From子句。(最常用) 当从多张表里查询的时候,会产生笛卡尔积;可用条件过滤它。 当两个表有相同字段时必须加前缀,列名前需加表名和“.”,如“s_emp.id”。 1...

    springmybatis

    查询出列表,也就是返回list, 在我们这个例子中也就是 List&lt;User&gt; , 这种方式返回数据,需要在User.xml 里面配置返回的类型 resultMap, 注意不是 resultType, 而这个resultMap 所对应的应该是我们自己配置的 ...

Global site tag (gtag.js) - Google Analytics