plsql分页

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

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

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

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

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

[c-sharp] view
plain
copy

  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;

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

[java] view
plain
copy

  1. //调用一个无返回值的过程

  2. import java.sql.*;

  3. public class Test2{

  4. public static void main(String[] args){
  5. try{

  6. //1.加载驱动

  7. Class.forName("oracle.jdbc.driver.OracleDriver");

  8. //2.得到连接

  9. Connection ct = DriverManager.getConnection("jdbc:oracle:[email protected]: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
plain
copy

  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;

java调用过程代码如下:

[java] view
plain
copy

  1. import java.sql.*;

  2. public class Test2{

  3. public static void main(String[] args){
  4. try{

  5. //1.加载驱动

  6. Class.forName("oracle.jdbc.driver.OracleDriver");

  7. //2.得到连接

  8. Connection ct = DriverManager.getConnection("jdbc:oracle:[email protected]: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
plain
copy

  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;

java调用过程代码如下:

[java] view
plain
copy

  1. import java.sql.*;

  2. public class Test2{

  3. public static void main(String[] args){
  4. try{

  5. //1.加载驱动

  6. Class.forName("oracle.jdbc.driver.OracleDriver");

  7. //2.得到连接

  8. Connection ct = DriverManager.getConnection("jdbc:oracle:[email protected]: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
plain
copy

  1. create or replace package testpackage as

  2. TYPE test_cursor is ref cursor;

  3. end testpackage;

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

[c-sharp] view
plain
copy

  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] view
plain
copy

  1. import java.sql.*;

  2. public class Test2{

  3. public static void main(String[] args){
  4. try{

  5. //1.加载驱动

  6. Class.forName("oracle.jdbc.driver.OracleDriver");

  7. //2.得到连接

  8. Connection ct = DriverManager.getConnection("jdbc:oracle:[email protected]: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
plain
copy

  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
plain
copy

  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;

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

[java] view
plain
copy

  1. import java.sql.*;

  2. public class FenYe{

  3. public static void main(String[] args){
  4. try{

  5. //1.加载驱动

  6. Class.forName("oracle.jdbc.driver.OracleDriver");

  7. //2.得到连接

  8. Connection ct = DriverManager.getConnection("jdbc:oracle:[email protected]: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
plain
copy

  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

时间: 2024-10-10 07:42:07

plsql分页的相关文章

PLSQL 学习之路(2)分页查询

PROCEDURE proc_query_organization_emps(p_request  CLOB, x_response OUT CLOB) IS v_api             VARCHAR2(100) := 'proc_query_organization_emps'; v_request         json; v_response        pl_json := pl_json; v_organization_id NUMBER; v_page         

pl/sql之编写分页过程

--开发一个包 --建立一个包,在该包中,我定义类型test_cursor,是个游标. 如下: Sql代码 create or replace package testpackage as TYPE test_cursor is ref cursor; end testpackage; --开始编写分页过程 create or replace procedure fenye (table_name in varchar2, page_size in number,        --每页显示的记

数据库 day60,61 Oracle入门,单行函数,多表查询,子查询,事物处理,约束,rownum分页,视图,序列,索引

1.    oracle介绍 ORACLE数据库系统是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一.比如SilverStream就是基于数据库的一种中间件.ORACLE数据库是目前世界上使用最为广泛的数据库管理系统,作为一个通用的数据库系统,它具有完整的数据管理功能:作为一个关系数据库,它是一个完备关系的产品:作为分布式数据库它实现了分布式处理功能.但它的所有知识,只要在一种机型上学习

给PLSQL插上飞翔的翅膀-PLSQL优化

60-80% of database performance issues are related to poorly performing SQL.60-80%的数据库性能问题要归结于生产中糟糕的SQL语句! 以此一文来总结笔者近10多年来的工作经验并基于最主要的也是最有效的对于Oracle数据库中的RBO.CBO.索引.WHERE条件进行解说同一时候配以大量案例来帮助读者从此文中学到的相关的理论知识高速的运用到其正在从事的生产环境中的优化过程中去. 优化的理论基础 通过Select Coun

诡异的分页代码失效问题

前言: 之前碰到了一个界面上分页失效的问题,并为之困扰了数日,后台定位为排序失效的问题,问题就迎刃而解了... 问题描述: 在界面上的某个分页功能存在失效的问题,第一页.第二页和最后一页的分页效果正常,但是中间的分页数据不变. QA提了一个关于此的Bug. 问题分析: 1.  分析界面分页代码 界面分页的代码属于在项目使用较多的组件,关于失效分页部分的代码无特殊的定制和使用. 2.  前端和后台端交互的分析 基于HTTP的监控工具,发现分页请求的请求数据一切正常,分页的start/limit数据

用rownum先排序后分页

今天突然想到rownum可以解决分页问题,于是做了各种实验,找个几个文章,最后有了一定成果. 现有表tablename,含有字段showorder,要求提取showorder的第11行到20行数据. 用语句select rownum r,a.* from tablename a order by showorder进行查询的时候会发现结果集中rownum是在排序之前赋的值,因此如果需要按showorder提前的话应该先将tablename按showorder排序,将排序后的结果集按rownum提

python__Django 分页

自定义分页的类: #!/usr/bin/env python # -*- coding: utf-8 -*- # Created by Mona on 2017/9/20 from django.utils.safestring import mark_safe class Paginator: ''' 页码的格式依赖于bootstrap: 使用案例: from django.shortcuts import render,redirect,HttpResponse from app01.mod

ajax+分页

<!DOCTYPE html><html><head lang="zh-cn"><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><meta http-equiv="X-UA-Compat

使用插件bootstrap-table实现表格记录的查询、分页、排序等处理

在业务系统开发中,对表格记录的查询.分页.排序等处理是非常常见的,在Web开发中,可以采用很多功能强大的插件来满足要求,且能极大的提高开发效率,本随笔介绍这个bootstrap-table是一款非常有名的开源表格插件,在很多项目中广泛的应用.Bootstrap-table插件提供了非常丰富的属性设置,可以实现查询.分页.排序.复选框.设置显示列.Card view视图.主从表显示.合并列.国际化处理等处理功能,而且该插件同时也提供了一些不错的扩展功能,如移动行.移动列位置等一些特殊的功能,插件可