pl/sql之分页

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

 无返回值的存储过程
古人云:欲速则不达,为了让大家伙比较容易接受分页过程编写,我还是从简单到复杂,循序渐进的给大家讲解。首先是掌握最简单的存储过程,无返回值的存储过程:
案例:现有一张表book,表结构如下:看图:

书号 书名 出版社

请写一个过程,可以向book表添加书,要求通过java程序调用该过程

--in:表示这是一个输入参数,不写in的话默认就为in
--out:表示一个输出参数

Sql代码
  1. create or replace procedure sp_pro7(spBookId in number,spbookName in varchar2,sppublishHouse in varchar2) is  
  2. begin  
  3.     insert into book values(spBookId,spbookName,sppublishHouse);   
  4. end;   
  5. /  

--在java中调用
--在java中调用

Java代码:
//调用一个无返回值的过程
import java.sql.*;
public class Test2{
    public static void main(String[] args){
        
        try{
            //1.加载驱动
            Class.forName("oracle.jdbc.driver.OracleDriver");
            //2.得到连接
            Connection ct = DriverManager.getConnection("jdbc:oracle:thin@127.0.0.1:1521:MYORA1","scott","m123");

            //3.创建CallableStatement
            CallableStatement cs = ct.prepareCall("{call sp_pro7(?,?,?)}");
            //4.给?赋值
            cs.setInt(1,10);
            cs.setString(2,"笑傲江湖");
            cs.setString(3,"人民出版社");
            //5.执行
            cs.execute();            
        } catch(Exception e){
            e.printStackTrace();
        } finally{
            //6.关闭各个打开的资源
            cs.close();
            ct.close();
        }
    }
}

执行,记录被加进去了
有返回值的存储过程(非列表)
再看如何处理有返回值的存储过程:
案例:编写一个过程,可以输入雇员的编号,返回该雇员的姓名。
案例扩张:编写一个过程,可以输入雇员的编号,返回该雇员的姓名、工资和岗位。

Sql代码 :
  1. --有输入和输出的存储过程   
  2. create or replace procedure sp_pro8   
  3. (spno in number, spName out varchar2) is  
  4. begin  
  5.     select ename into spName from emp where empno=spno;   
  6. end;   
  7. /  
Java代码:
  1. import java.sql.*;   
  2. public class Test2{   
  3.     public static void main(String[] args){   
  4.            
  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.   
  11.             //3.创建CallableStatement   
  12.             /*CallableStatement cs = ct.prepareCall("{call sp_pro7(?,?,?)}");  
  13.             //4.给?赋值  
  14.             cs.setInt(1,10);  
  15.             cs.setString(2,"笑傲江湖");  
  16.             cs.setString(3,"人民出版社");*/  
  17.   
  18.             //看看如何调用有返回值的过程   
  19.             //创建CallableStatement   
  20.             /*CallableStatement cs = ct.prepareCall("{call sp_pro8(?,?)}");   
  21.   
  22.             //给第一个?赋值   
  23.             cs.setInt(1,7788);   
  24.             //给第二个?赋值   
  25.             cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);   //通过这个注册的值返回来
  26.   
  27.             //5.执行   
  28.             cs.execute();      
  29.             //取出返回值,要注意?的顺序   
  30.             String name=cs.getString(2);    
  31.             System.out.println("7788的名字"+name);           
  32.         } catch(Exception e){   
  33.             e.printStackTrace();   
  34.         } finally{   
  35.             //6.关闭各个打开的资源   
  36.             cs.close();   
  37.             ct.close();   
  38.         }   
  39.     }   
  40. }  

运行,成功得出结果。。

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

Sql代码:
  1. --有输入和输出的存储过程   
  2. create or replace procedure sp_pro8   
  3. (spno in number, spName out varchar2,spSal out number,spJob out varchar2) is  
  4. begin  
  5.     select ename,sal,job into spName,spSal,spJob from emp where empno=spno;   
  6. end;   
  7. /  

JAVA代码:

  1. import java.sql.*;   
  2. public class Test2{   
  3.     public static void main(String[] args){   
  4.            
  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.   
  11.             //3.创建CallableStatement   
  12.             /*CallableStatement cs = ct.prepareCall("{call sp_pro7(?,?,?)}");  
  13.             //4.给?赋值  
  14.             cs.setInt(1,10);  
  15.             cs.setString(2,"笑傲江湖");  
  16.             cs.setString(3,"人民出版社");*/  
  17.   
  18.             //看看如何调用有返回值的过程   
  19.             //创建CallableStatement   
  20.             /*CallableStatement cs = ct.prepareCall("{call sp_pro8(?,?,?,?)}");   
  21.   
  22.             //给第一个?赋值   
  23.             cs.setInt(1,7788);   
  24.             //给第二个?赋值   
  25.             cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);   
  26.             //给第三个?赋值   
  27.             cs.registerOutParameter(3,oracle.jdbc.OracleTypes.DOUBLE);   
  28.             //给第四个?赋值   
  29.             cs.registerOutParameter(4,oracle.jdbc.OracleTypes.VARCHAR);   
  30.            //注意上面的那几个都应该给他们进行赋值,否则是会出错的
  31.   
  32.             //5.执行   
  33.             cs.execute();      
  34.             //取出返回值,要注意?的顺序   
  35.             String name=cs.getString(2);    
  36.             String job=cs.getString(4);   
  37.             System.out.println("7788的名字"+name+" 工作:"+job);           
  38.         } catch(Exception e){   
  39.             e.printStackTrace();   
  40.         } finally{   
  41.             //6.关闭各个打开的资源   
  42.             cs.close();   
  43.             ct.close();   
  44.         }   
  45.     }   
  46. }  

运行,成功找出记录

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

Sql代码:
  1. create or replace package testpackage as  //注意这里是as而不是is
  2.   TYPE test_cursor is ref cursor;   
  3. end testpackage; 

2.建立存储过程。如下:

Sql代码:
  1. create or replace procedure sp_pro9(spNo in number,p_cursor out 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代码:
  1. import java.sql.*;   
  2. public class Test2{   
  3.     public static void main(String[] args){   
  4.            
  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.   
  11.             //看看如何调用有返回值的过程   
  12.             //3.创建CallableStatement   
  13.             /*CallableStatement cs = ct.prepareCall("{call sp_pro9(?,?)}");   
  14.   
  15.             //4.给第一个?赋值   
  16.             cs.setInt(1,10);   
  17.             //给第二个?赋值   
  18.             cs.registerOutParameter(2,oracle.jdbc.OracleTypes.CURSOR);   //注意这里的这个类型
  19.   
  20.             //5.执行   
  21.             cs.execute();      
  22.             //得到结果集 ,在这里取出来的时候就是结果集了
  23.             ResultSet rs=(ResultSet)cs.getObject(2);        
  24.             while(rs.next()){   
  25.                 System.out.println(rs.getInt(1)+" "+rs.getString(2));   
  26.             }    
  27.         } catch(Exception e){   
  28.             e.printStackTrace();   
  29.         } finally{   
  30.             //6.关闭各个打开的资源   
  31.             cs.close();   
  32.             ct.close();   
  33.         }   
  34.     }   
  35. }  

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

 编写分页过程
  有了上面的基础,相信大家可以完成分页存储过程了。
  要求,请大家编写一个存储过程,要求可以输入表名、每页显示记录数、当前页。返回总记录数,总页数,和返回的结果集。
如果大家忘了oracle中如何分页,请参考第三天的内容。
先自己完成,老师在后面给出答案,并讲解。
--oracle的分页
Sql代码
  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;  
--开发一个包 
--建立一个包,在该包中,我定义类型test_cursor,是个游标。 如下:
Sql代码
  1. create or replace package testpackage as  
  2.   TYPE test_cursor is ref 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;   
  39. /  

运行,控制台输出:
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
过程的执行部分做下改动,如下:
Sql代码
  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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在 VS Code 中使用 Oracle 数据库,需要先安装 Oracle Instant Client,然后安装相关的插件,例如 Oracle Extension Pack 和 PL/SQL。 以下是一个示例的 Oracle 分页查询代码: ```sql SELECT * FROM ( SELECT t.*, ROWNUM rn FROM ( SELECT * FROM table_name ORDER BY id ) t WHERE ROWNUM <= :endRow ) WHERE rn >= :startRow ``` 其中,`:startRow` 和 `:endRow` 是要查询的数据范围,`table_name` 是要查询的表名,`id` 是用于排序的字段名。 如果要在 VS Code 中执行这个 SQL 语句,可以先在编辑器中打开一个 SQL 文件,然后使用 PL/SQL 插件提供的命令进行执行。例如,可以使用 `PL/SQL: Run Query` 命令来执行 SQL 语句,并在结果面板中查看查询结果。 另外,如果要在代码中执行这个 SQL 语句,可以使用类似以下的 Java 代码: ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class OraclePaginationExample { public static void main(String[] args) { String url = "jdbc:oracle:thin:@//hostname:port/service_name"; String user = "username"; String password = "password"; int startRow = 1; int endRow = 10; try (Connection conn = DriverManager.getConnection(url, user, password); PreparedStatement stmt = conn.prepareStatement( "SELECT *\n" + "FROM (\n" + " SELECT t.*, ROWNUM rn\n" + " FROM (\n" + " SELECT *\n" + " FROM table_name\n" + " ORDER BY id\n" + " ) t\n" + " WHERE ROWNUM <= ?\n" + ")\n" + "WHERE rn >= ?" )) { stmt.setInt(1, endRow); stmt.setInt(2, startRow); try (ResultSet rs = stmt.executeQuery()) { while (rs.next()) { // process query result } } } catch (SQLException e) { e.printStackTrace(); } } } ``` 这个例子使用 Java 语言连接 Oracle 数据库,并执行上面的 SQL 语句,将查询结果作为 ResultSet 对象返回。在实际应用中,需要根据具体的需求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yjsuge

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值