PLSQL实现分页

来源:互联网 发布:乔丹生涯场均数据 编辑:程序博客网 时间:2024/06/04 17:59

分页是任何一个网站(bbs,网上商城,blog)都会使用到的技术,因此学习pl/sql编程开发就一定要掌握该技术。

1. 编写无返回值的存储过程

首先是掌握最简单的存储过程,无返回值的存储过程。

案例:现有一张表book,表结构如下:

请写一个过程,可以向book表添加书,要求通过java程序调用该过程。
--in:表示这是一个输入参数,默认为in
--out:表示一个输出参数
存储过程代码如下:

[c-sharp] view plaincopyprint?
  1. create or replace procedure sp_pro7(spBookIdin number,spbookNamein varchar2,sppublishHousein varchar2)is
  2. begin
  3. insert into book values(spBookId,spbookName,sppublishHouse);
  4. end;

在java中调用中调用该过程代码如下:

[java] view plaincopyprint?
  1. //调用一个无返回值的过程
  2. import java.sql.*;
  3. publicclass Test2{
  4. publicstaticvoid main(String[] args){
  5. try{
  6. //1.加载驱动
  7. Class.forName("oracle.jdbc.driver.OracleDriver");
  8. //2.得到连接
  9. Connection ct = DriverManager.getConnection("jdbc:oracle:thin@127.0.0.1:1521:MYORA1","scott","m123");
  10. //3.创建CallableStatement
  11. CallableStatement cs = ct.prepareCall("{call sp_pro7(?,?,?)}");
  12. //4.给?赋值
  13. cs.setInt(1,10);
  14. cs.setString(2,"笑傲江湖");
  15. cs.setString(3,"人民出版社");
  16. //5.执行
  17. cs.execute();
  18. } catch(Exception e){
  19. e.printStackTrace();
  20. } finally{
  21. //6.关闭各个打开的资源
  22. cs.close();
  23. ct.close();
  24. }
  25. }
  26. }

执行,记录被加进去了。

2. 有返回值的存储过程(非列表)
案例:编写一个过程,可以输入雇员的编号,返回该雇员的姓名。
案例扩张:编写一个过程,可以输入雇员的编号,返回该雇员的姓名、工资和岗位。

存储过程代码如下:

[c-sharp] view plaincopyprint?
  1. --有输入和输出的存储过程
  2. create or replace procedure sp_pro8
  3. (spno in number, spNameout varchar2)is
  4. begin
  5. select ename into spName from emp where empno=spno;
  6. end;

java调用过程代码如下:

[java] view plaincopyprint?
  1. import java.sql.*;
  2. publicclass Test2{
  3. publicstaticvoid main(String[] args){
  4. try{
  5. //1.加载驱动
  6. Class.forName("oracle.jdbc.driver.OracleDriver");
  7. //2.得到连接
  8. Connection ct = DriverManager.getConnection("jdbc:oracle:thin@127.0.0.1:1521:MYORA1","scott","m123");
  9. //3.创建CallableStatement
  10. /*CallableStatement cs = ct.prepareCall("{call sp_pro7(?,?,?)}");
  11. //4.给?赋值
  12. cs.setInt(1,10);
  13. cs.setString(2,"笑傲江湖");
  14. cs.setString(3,"人民出版社");*/
  15. //看看如何调用有返回值的过程
  16. //创建CallableStatement
  17. /*CallableStatement cs = ct.prepareCall("{call sp_pro8(?,?)}");
  18. //给第一个?赋值
  19. cs.setInt(1,7788);
  20. //给第二个?赋值
  21. cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);
  22. //5.执行
  23. cs.execute();
  24. //取出返回值,要注意?的顺序
  25. String name=cs.getString(2);
  26. System.out.println("7788的名字"+name);
  27. } catch(Exception e){
  28. e.printStackTrace();
  29. } finally{
  30. //6.关闭各个打开的资源
  31. cs.close();
  32. ct.close();
  33. }
  34. }
  35. }


运行,成功得出结果。

案例扩张:编写一个过程,可以输入雇员的编号,返回该雇员的姓名、工资和岗位。

[c-sharp] view plaincopyprint?
  1. --有输入和输出的存储过程
  2. create or replace procedure sp_pro8
  3. (spno in number, spNameout varchar2,spSalout number,spJobout varchar2)is
  4. begin
  5. select ename,sal,job into spName,spSal,spJob from emp where empno=spno;
  6. end;

java调用过程代码如下:

[java] view plaincopyprint?
  1. import java.sql.*;
  2. publicclass Test2{
  3. publicstaticvoid main(String[] args){
  4. try{
  5. //1.加载驱动
  6. Class.forName("oracle.jdbc.driver.OracleDriver");
  7. //2.得到连接
  8. Connection ct = DriverManager.getConnection("jdbc:oracle:thin@127.0.0.1:1521:MYORA1","scott","m123");
  9. //3.创建CallableStatement
  10. /*CallableStatement cs = ct.prepareCall("{call sp_pro7(?,?,?)}");
  11. //4.给?赋值
  12. cs.setInt(1,10);
  13. cs.setString(2,"笑傲江湖");
  14. cs.setString(3,"人民出版社");*/
  15. //看看如何调用有返回值的过程
  16. //创建CallableStatement
  17. /*CallableStatement cs = ct.prepareCall("{call sp_pro8(?,?,?,?)}");
  18. //给第一个?赋值
  19. cs.setInt(1,7788);
  20. //给第二个?赋值
  21. cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);
  22. //给第三个?赋值
  23. cs.registerOutParameter(3,oracle.jdbc.OracleTypes.DOUBLE);
  24. //给第四个?赋值
  25. cs.registerOutParameter(4,oracle.jdbc.OracleTypes.VARCHAR);
  26. //5.执行
  27. cs.execute();
  28. //取出返回值,要注意?的顺序
  29. String name=cs.getString(2);
  30. String job=cs.getString(4);
  31. System.out.println("7788的名字"+name+" 工作:"+job);
  32. } catch(Exception e){
  33. e.printStackTrace();
  34. } finally{
  35. //6.关闭各个打开的资源
  36. cs.close();
  37. ct.close();
  38. }
  39. }
  40. }

运行,成功找出记录。
3. 有返回值的存储过程(列表[结果集])

案例:编写一个过程,输入部门号,返回该部门所有雇员信息。
对该题分析如下:
由于oracle存储过程没有返回值,它的所有返回值都是通过out参数来替代的,列表同样也不例外,但由于是集合,所以不能用一般的参数,必须要用pagkage了。所以要分两部分:
(1). 建立一个包,在该包中,我定义类型test_cursor,是个游标。代码如下:

[c-sharp] view plaincopyprint?
  1. create or replace package testpackageas
  2. TYPE test_cursor isref cursor;
  3. end testpackage;

(2). 建立存储过程,代码如下:

[c-sharp] view plaincopyprint?
  1. create or replace procedure sp_pro9(spNoin number,p_cursorout testpackage.test_cursor)is
  2. begin
  3. open p_cursor for
  4. select * from emp where deptno = spNo;
  5. end sp_pro9;

(3). 在java中调用该过程,代码如下:

[java] view plaincopyprint?
  1. import java.sql.*;
  2. publicclass Test2{
  3. publicstaticvoid main(String[] args){
  4. try{
  5. //1.加载驱动
  6. Class.forName("oracle.jdbc.driver.OracleDriver");
  7. //2.得到连接
  8. Connection ct = DriverManager.getConnection("jdbc:oracle:thin@127.0.0.1:1521:MYORA1","scott","m123");
  9. //看看如何调用有返回值的过程
  10. //3.创建CallableStatement
  11. /*CallableStatement cs = ct.prepareCall("{call sp_pro9(?,?)}");
  12. //4.给第?赋值
  13. cs.setInt(1,10);
  14. //给第二个?赋值
  15. cs.registerOutParameter(2,oracle.jdbc.OracleTypes.CURSOR);
  16. //5.执行
  17. cs.execute();
  18. //得到结果集
  19. ResultSet rs=(ResultSet)cs.getObject(2);
  20. while(rs.next()){
  21. System.out.println(rs.getInt(1)+" "+rs.getString(2));
  22. }
  23. } catch(Exception e){
  24. e.printStackTrace();
  25. } finally{
  26. //6.关闭各个打开的资源
  27. cs.close();
  28. ct.close();
  29. }
  30. }
  31. }

运行,成功得出部门号是10的所有用户。

4. 编写分页过程
要求,请大家编写一个存储过程,要求可以输入表名、每页显示记录数、当前页。返回总记录数,总页数,和返回的结果集。
(1). oracle中的分页实现:

[c-sharp] view plaincopyprint?
  1. select t1.*, rownum rn from (select * from emp) t1 where rownum<=10;
  2. --在分页时,大家可以把下面的sql语句当做一个模板使用
  3. select * from
  4. (select t1.*, rownum rn from (select * from emp) t1 where rownum<=10)
  5. where rn>=6;

(2). 开发一个包

建立一个包,在该包中,我定义类型test_cursor,是个游标。代码如下:

[c-sharp] view plaincopyprint?
  1. create or replace package testpackageas
  2. TYPE test_cursor isref cursor;
  3. end testpackage;
  4. --开始编写分页的过程
  5. create or replace procedure fenye
  6. (tableName in varchar2,
  7. Pagesize in number,--一页显示记录数
  8. pageNow in number,
  9. myrows out number,--总记录数
  10. myPageCount out number,--总页数
  11. p_cursor out testpackage.test_cursor--返回的记录集
  12. ) is
  13. --定义部分
  14. --定义sql语句 字符串
  15. v_sql varchar2(1000);
  16. --定义两个整数
  17. v_begin number:=(pageNow-1)*Pagesize+1;
  18. v_end number:=pageNow*Pagesize;
  19. begin
  20. --执行部分
  21. v_sql:='select * from (select t1.*, rownum rn from (select * from '||tableName||') t1 where rownum<='||v_end||') where rn>='||v_begin;
  22. --把游标和sql关联
  23. open p_cursor for v_sql;
  24. --计算myrows和myPageCount
  25. --组织一个sql语句
  26. v_sql:='select count(*) from '||tableName;
  27. --执行sql,并把返回的值,赋给myrows;
  28. execute inmediate v_sql into myrows;
  29. --计算myPageCount
  30. --if myrows%Pagesize=0 then这样写是错的
  31. if mod(myrows,Pagesize)=0 then
  32. myPageCount:=myrows/Pagesize;
  33. else
  34. myPageCount:=myrows/Pagesize+1
  35. end if;
  36. --关闭游标
  37. close p_cursor;
  38. end;

(3). 使用java测试该分页过程,代码如下:

[java] view plaincopyprint?
  1. import java.sql.*;
  2. publicclass FenYe{
  3. publicstaticvoid main(String[] args){
  4. try{
  5. //1.加载驱动
  6. Class.forName("oracle.jdbc.driver.OracleDriver");
  7. //2.得到连接
  8. Connection ct = DriverManager.getConnection("jdbc:oracle:thin@127.0.0.1:1521:MYORA1","scott","m123");
  9. //3.创建CallableStatement
  10. CallableStatement cs = ct.prepareCall("{call fenye(?,?,?,?,?,?)}");
  11. //4.给第?赋值
  12. cs.seString(1,"emp");
  13. cs.setInt(2,5);
  14. cs.setInt(3,2);
  15. //注册总记录数
  16. cs.registerOutParameter(4,oracle.jdbc.OracleTypes.INTEGER);
  17. //注册总页数
  18. cs.registerOutParameter(5,oracle.jdbc.OracleTypes.INTEGER);
  19. //注册返回的结果集
  20. cs.registerOutParameter(6,oracle.jdbc.OracleTypes.CURSOR);
  21. //5.执行
  22. cs.execute();
  23. //取出总记录数 /这里要注意,getInt(4)中4,是由该参数的位置决定的
  24. int rowNum=cs.getInt(4);
  25. int pageCount = cs.getInt(5);
  26. ResultSet rs=(ResultSet)cs.getObject(6);
  27. //显示一下,看看对不对
  28. System.out.println("rowNum="+rowNum);
  29. System.out.println("总页数="+pageCount);
  30. while(rs.next()){
  31. System.out.println("编号:"+rs.getInt(1)+" 名字:"+rs.getString(2)+" 工资:"+rs.getFloat(6));
  32. }
  33. } catch(Exception e){
  34. e.printStackTrace();
  35. } finally{
  36. //6.关闭各个打开的资源
  37. cs.close();
  38. ct.close();
  39. }
  40. }
  41. }

运行,控制台输出:
rowNum=19
总页数:4
编号:7369 名字:SMITH 工资:2850.0
编号:7499 名字:ALLEN 工资:2450.0
编号:7521 名字:WARD 工资:1562.0
编号:7566 名字:JONES 工资:7200.0
编号:7654 名字:MARTIN 工资:1500.0

新的需要,要求按照薪水从低到高排序,然后取出6-10。

代码如下:

[c-sharp] view plaincopyprint?
  1. begin
  2. --执行部分
  3. v_sql:='select * from (select t1.*, rownum rn from (select * from '||tableName||' order by sal) t1 where rownum<='||v_end||') where rn>='||v_begin;

重新执行一次procedure,java不用改变,运行,控制台输出:
rowNum=19
总页数:4
编号:7900 名字:JAMES 工资:950.0
编号:7876 名字:ADAMS 工资:1100.0
编号:7521 名字:WARD 工资:1250.0
编号:7654 名字:MARTIN 工资:1250.0
编号:7934 名字:MILLER 工资:1300.0

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 海棠花瓣干枯怎么办茎变软 微信上的图片打不开怎么办 口红吊兰老掉叶子怎么办 翠叶竹芋叶子卷怎么办 牙有龋齿垫底以后酸怎么办 事业单位辞职请示30天不批怎么办 孕早期吃了油菜怎么办 实体店买到翻新苹果手机怎么办 太阳花叶子蔫了怎么办 刚摘下来的多肉怎么办 购车4s不给合同怎么办 橙光游戏2.0商城怎么办 飞羽花卷叶了怎么办 孔雀竹芋叶子发黄卷曲怎么办 孔雀竹芋叶子黄了卷了怎么办 飞羽竹芋叶尖黄怎么办 十七岁还是胸小怎么办 英雄联盟连接不上服务器怎么办 彩叶草叶子蔫了怎么办 家里种葱老是死怎么办 非洲菊生虫子了怎么办 多肉的花剪下来怎么办 结石痛怎么办怎么止疼 喝玫瑰花茶胃疼怎么办 卡地亚戒指掉色怎么办 苹果8plus掉电快怎么办 苹果8plus耗电快怎么办 卡地亚戒指划痕怎么办 苹果手机玫瑰金掉色怎么办 14k玫瑰金掉色怎么办 卡地亚手镯掉色怎么办 手机掉油漆里了怎么办 黄金戴久了变黑怎么办 玫瑰金褪色不亮了怎么办 黄金带久了不亮怎么办 玉石带久了不亮怎么办 手表带久了不亮怎么办 蜜蜡带久了不亮怎么办 钛钢首饰不亮了怎么办 潘多拉玫瑰金戒指褪色了怎么办 金色手表漆掉了怎么办