--集合实现游标查询

CREATE OR REPLACE PACKAGE emppkg IS

  TYPE t_record IS RECORD(

       rn INT,

       empno emp.empno%TYPE,

       ename emp.ename%TYPE,

       sal emp.sal%TYPE,

       deptno emp.deptno%TYPE);

  TYPE emplist IS TABLE OF t_record;--定义返回结果的记录集合类型

  --定义实现分页显示的过程

  PROCEDURE sp_page(

            p_page_size IN OUT INT,--每页输出显示的记录数

            p_cur_page_no IN OUT INT,--当前页码

            p_outcollection OUT emplist--接收查询返回结果

            );

END emppkg;

/

CREATE OR REPLACE PACKAGE BODY emppkg IS

  PROCEDURE sp_page(

            p_page_size IN OUT INT,--每页输出记录数

            p_cur_page_no IN OUT INT,--当前页码

            p_outcollection OUT emplist--接收查询返回值

            )

    IS

      v_start_rownum  NUMBER;

      v_end_rownum    NUMBER;

      v_total_records NUMBER;

      v_total_pages   NUMBER;

      indexvalue      BINARY_INTEGER :=1;

    BEGIN

      --查询记录总数

      SELECT COUNT(*) INTO v_total_records FROM emp;

      --验证输入页面显示记录数量,确保大于0

      IF p_page_size < 0 THEN

        p_page_size :=10;

      END IF;

      --计算页面总数

      IF MOD(v_total_records,v_total_pages) = 0 THEN

        v_total_pages := v_total_records / p_page_size;

       ELSE

         v_total_pages := (v_total_records / p_page_size)+1;

      END IF;

      --验证页号

      IF p_cur_page_no < 1 THEN

        p_cur_page_no := 1;

      END IF;

      IF p_cur_page_no > v_total_pages THEN

        p_cur_page_no := v_total_pages;

      END IF;

      --执行分页查询

      --计算当前页开始显示的记录在整个记录中从哪开始

      v_start_rownum := (p_cur_page_no-1)*p_page_size+1;

      --计算当前页的最后一条记录位于哪

      v_end_rownum := p_cur_page_no*p_page_size;

      --构造初始化记录嵌套表

      p_outcollection := emplist();

      --查询记录

      FOR v_emp IN (SELECT * FROM (SELECT ROWNUM rn,empno,ename,sal,deptno FROM

                                       (SELECT empno,ename,sal,deptno FROM emp

                                        WHERE sal IS NOT NULL

                                        ORDER BY sal) A--选出有sal的作为表A

                                   WHERE ROWNUM<=v_end_rownum) B

                    WHERE rn>=v_start_rownum)--在B中筛选去掉当前页之前的所有记录

      LOOP--循环把取出的数赋给接收变量

        p_outcollection.EXTEND;

        p_outcollection(indexvalue):=v_emp;

        indexvalue:=indexvalue+1;

      END LOOP;

   END sp_page;

END emppkg;  

/

 --游标实现分页查询

CREATE OR REPLACE PACKAGE curspkg IS

  TYPE query_cursor IS REF CURSOR;

  PROCEDURE sp_page(

            p_page_size IN OUT  INT,--每页输出记录数

            p_cur_page_no IN OUT INT,--当前页码

            p_sql_select VARCHAR2,--查询语句,包含排序部分

            p_total_pages OUT INT,--返回总页数

            p_total_records OUT INT,--返回总记录数

            p_out_cursor OUT query_cursor--接收返回当前页的数据集

            );

END curspkg;

/

CREATE OR REPLACE PACKAGE BODY curspkg IS

  PROCEDURE sp_page(

            p_page_size IN OUT  INT,--每页输出记录数

            p_cur_page_no IN OUT INT,--当前页码

            p_sql_select VARCHAR2,--查询语句,包含排序部分

            p_total_pages OUT INT,--返回总页数

            p_total_records OUT INT,--返回总记录数

            p_out_cursor OUT query_cursor--接收返回当前页的数据集

            )

   IS

     v_count_sql VARCHAR2(1000);

     v_start_rownum INT;

     v_end_rownum INT;

     v_sql VARCHAR2(4000);

   BEGIN

     --动态sql语句,调用输入的查询语句,计算输入的语句一共查询出多少数据

     v_count_sql := 'SELECT TO_CHAR(COUNT(*)) FROM ('||p_sql_select||')';

     EXECUTE IMMEDIATE v_count_sql INTO p_total_records;

     --验证输入页面显示记录数量,确保大于0

      IF p_page_size < 0 THEN

        p_page_size :=10;

      END IF;

      --计算页面总数

      IF MOD(p_total_records,P_total_pages) = 0 THEN

        P_total_pages := p_total_records / p_page_size;

       ELSE

         P_total_pages := (p_total_records / p_page_size)+1;

      END IF;

      --验证页号

      IF p_cur_page_no < 1 THEN

        p_cur_page_no := 1;

      END IF;

      IF p_cur_page_no > P_total_pages THEN

        p_cur_page_no := P_total_pages;

      END IF;

      --执行分页查询

      --计算当前页开始显示的记录在整个记录中从哪开始

      v_start_rownum := (p_cur_page_no-1)*p_page_size+1;

      --计算当前页的最后一条记录位于哪

      v_end_rownum := p_cur_page_no*p_page_size;

      v_sql:='SELECT * FROM (SELECT ROWNUM rn,A.* FROM

                            ('||p_sql_select||') A

                            WHERE ROWNUM<='||TO_CHAR(v_start_rownum)||') B

              WHERE rn>='||TO_CHAR(v_end_rownum);

      OPEN p_out_cursor FOR v_sql;

   END sp_page;

END curspkg;

/

PLSQL实现分页查询的更多相关文章

  1. JdbcTemplate+PageImpl实现多表分页查询

    一.基础实体 @MappedSuperclass public abstract class AbsIdEntity implements Serializable { private static ...

  2. 用Hibernate和Struts2+jsp实现分页查询、修改删除

    1.首先用get的方法传递一个页数过去 2.通过Struts2跳转到Action 3.通过request接受主页面index传过的页数,此时页数是1, 然后调用service层的方法获取DAO层分页查 ...

  3. MySQL、Oracle和SQL Server的分页查询语句

    假设当前是第PageNo页,每页有PageSize条记录,现在分别用Mysql.Oracle和SQL Server分页查询student表. 1.Mysql的分页查询: SELECT * FROM s ...

  4. 分页查询和分页缓存查询,List<Map<String, Object>>遍历和Map遍历

    分页查询 String sql = "返回所有符合条件记录的待分页SQL语句"; int start = (page - 1) * limit + 1; int end = pag ...

  5. mysql 分页查询

    mysql,; : mysql,; -last. //如果只给定一个参数,它表示返回最大的记录行数目: mysql; 个记录行 ,n. 动态传参的分页查询 SELECT * FROM table LI ...

  6. MongoDB 分页查询的方法及性能

    最近有点忙,本来有好多东西可以总结,Redis系列其实还应该有四.五.六...不过<Redis in Action>还没读完,等读完再来总结,不然太水,对不起读者. 自从上次Redis之后 ...

  7. .NET平台开源项目速览(7)关于NoSQL数据库LiteDB的分页查询解决过程

    在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑) 与 .NET平台开源项目速览(3)小巧轻量级NoSQL文件数据库LiteDB中,介绍了LiteDB的基本使用情况以及部 ...

  8. SubSonic3.0插件分页查询速度测试

    使用SubSonic3.0一段时间了,一直都想找机会测试一下各种查询分页速度,对比一下插件的查询效率到底怎么样,所以昨天写好了测试程序,准备好1K.1W.10W.50W和100W记录的数据表,早上详细 ...

  9. Node.js、express、mongodb 实现分页查询、条件搜索

    前言 在上一篇Node.js.express.mongodb 入门(基于easyui datagrid增删改查) 的基础上实现了分页查询.带条件搜索. 实现效果 1.列表第一页. 2.列表第二页 3. ...

随机推荐

  1. 常用linux命令备忘

    备忘: 关闭防火墙:# systemctl stop firewalld 查看防火墙状态:#  systemctl status firewalld 停止防火墙:#  systemctl disabl ...

  2. Mysql查询小作业

    数据准备drop table if exists class;create table class(    class_no int(2) unsigned zerofill primary key ...

  3. Lintcode388 Permutation Sequence solution 题解

    [题目描述] Given n and k, return the k-th permutation sequence. Notice:n will be between 1 and 9 inclusi ...

  4. chall.tasteless.eu 中的注入题

    第一题好像就很难,看了payload,算是涨见识了,感觉有点为了猜而猜. 题目给我们的时候是这样的:http://chall.tasteless.eu/level1/index.php?dir=ASC ...

  5. [NOI 2011]道路修建

    Description 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家 之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿 意修建恰好 n – 1条双向道 ...

  6. bzoj4896 补退选

    Description X是T大的一名老师,每年他都要教授许多学生基础的C++知识.在T大,每个学生在每学期的开学前都需要选课,每 次选课一共分为三个阶段:预选,正选,补退选:其中"补退选& ...

  7. [USACO14DEC]驮运Piggy Back

    题目描述 Bessie 和 Elsie在不同的区域放牧,他们希望花费最小的能量返回谷仓.从一个区域走到一个相连区域,Bessie要花费B单位的能量,Elsie要花费E单位的能量. 如果某次他们两走到同 ...

  8. ●2301 [HAOI2011] Problem b

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2301 题解: 莫比乌斯反演,入门题. 类似●HDU 1695 GCD 只是多了一个下界,(另 ...

  9. 【NOIP2004】虫食算

    Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +. 8468#6633 444455 ...

  10. [Apio2009][bzoj1179]Atm

    题意:一个n个点m条单向边的图,每个点有权值,给定出发点和p个可以停止的点,你可以随便走一条路径从出发点走到一个可以停止的点,但是每个点的点权只能计算一次,求能得到的最大权值. n,m<=500 ...