PL/SQL中编写Oracle数据库分页的存储过程

其实 Oracle数据库的分页还是比较容易理解的。此文以Oracle数据库中的SCOTT用户的EMP表为例,用PL/SQL Developer编写一个分页存储过程,要求是:可以输入表名,每页显示记录数,当前页,返回总记录数,总页数和返回的结果集

由于需要返回查询出来的结果集,需要在PL/SQL中创建一个package,这个包里面定义一个refcursor类型,用于记录sql语句查询出来的结果集。创建包的代码如下:

Plain代码   收藏代码
  1. create or replace package pagingPackage as  
  2. type paging_cursor is ref cursor;  
  3. end pagingPackage;  

接下来开始Oracle的分页过程,我们可以用select emp.*,rownum from emp;来显示地表示出每行的行标。然后可以根据行标对内容进行分页,下面这个SQL语句可以作为Oracle分页的模板。

Sql代码   收藏代码
  1. select * from   
  2. (select t1.*,rownum rn from (select * from emp) t1 where rownum<=12)  
  3. where rn>=8;  

有了上面的refcursor类型和分页模板,下面开始编写分页的存储过程,代码如下:

Plain代码   收藏代码
  1. create procedure paging  
  2. (tableName in varchar2 ,--表名  
  3. pageSizes in number,--每页显示记录数  
  4. pageNow in number,--当前页  
  5. rowNums out number,--总记录数  
  6. pageNum out number,--总页数  
  7. paging_cursor out pagingPackage.paging_cursor) is   
  8. --定义部分  
  9. --定义sql语句,字符串  
  10. v_sql varchar2(1000);  
  11. --定义两个整数,用于表示每页的开始和结束记录数  
  12. v_begin number:=(pageNow-1)*pageSizes+1;  
  13. v_end number:=pageNow*pageSizes;  
  14. begin  
  15.   --执行部分  
  16.   v_sql:='select * from (select t1.*,rownum rn from (select * from '||tableName||') t1 where rownum<='||v_end||') where rn>='||v_begin;  
  17.   --把游标和sql语句关联  
  18.   open paging_cursor for v_sql;  
  19.   --计算rowNums和pageNum  
  20.   --组织一个sql语句  
  21.   v_sql:='select count(*) from '||tableName;  
  22.   --执行该sql语句,并赋给rowNums  
  23.   execute immediate v_sql into rowNums;  
  24.   --计算pageNum  
  25.   if mod(rowNums,pageSizes)=0 then  
  26.     pageNum := rowNums/pageSizes;  
  27.     else  
  28.       pageNum := rowNums/pageSizes+1;  
  29.       end if;  
  30.   end;  

在java中编写代码测试分页,代码如下:

Java代码   收藏代码
  1. package com.test.oracletest;  
  2.   
  3. import java.sql.CallableStatement;  
  4. import java.sql.Connection;  
  5. import java.sql.DriverManager;  
  6. import java.sql.ResultSet;  
  7.   
  8. //测试分页  
  9. public class OraclePaging {  
  10.     public static void main(String[] args) {  
  11.         try {  
  12.             // 加载驱动  
  13.             Class.forName("oracle.jdbc.driver.OracleDriver");  
  14.             // 获取连接  
  15.             Connection connection = DriverManager.getConnection(  
  16.                     "jdbc:oracle:thin:@127.0.0.1:1521:ORCL""SCOTT""tiger");  
  17.             // 创建CallableStatement,调取数据库的存储过程  
  18.             CallableStatement cst = connection  
  19.                     .prepareCall("{call paging(?,?,?,?,?,?)}");  
  20.             // 给?赋值  
  21.             cst.setString(1"emp");  
  22.             cst.setInt(26);  
  23.             cst.setInt(32);  
  24.             // 注册存储过程的输出项  
  25.             cst.registerOutParameter(4, oracle.jdbc.OracleTypes.INTEGER);  
  26.             cst.registerOutParameter(5, oracle.jdbc.OracleTypes.INTEGER);  
  27.             cst.registerOutParameter(6, oracle.jdbc.OracleTypes.CURSOR);  
  28.   
  29.             // 执行  
  30.             cst.execute();  
  31.   
  32.             // 获取输出项  
  33.             int rowNums = cst.getInt(4);  
  34.             int pageNum = cst.getInt(5);  
  35.             ResultSet rs = (ResultSet) cst.getObject(6);  
  36.   
  37.             System.out.println("总记录数rowNums = " + rowNums);  
  38.             System.out.println("总页数pageNum = " + pageNum);  
  39.   
  40.             System.out.println("EMPNO" + '\t' + "ENAME" + '\t' + "ROWNUM");  
  41.             while (rs.next()) {  
  42.                 System.out.println(rs.getInt("EMPNO") + " " + '\t'  
  43.                         + rs.getString("ENAME") + '\t' + rs.getInt("RN"));  
  44.             }  
  45.         } catch (Exception e) {  
  46.             e.printStackTrace();  
  47.         } finally {  
  48.             // 关闭资源  
  49.         }  
  50.     }  
  51.   
  52. }  

执行的结果如图所示:


我们还可以通过修改模板最内侧的视图来满足其他一些基本的排序要求。Oracle的分页思想就是如此。。#

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值