PL/SQL的进阶----编写分页过程

33 篇文章 0 订阅

PL/SQL的进阶----编写分页过程

介绍

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

 

①无返回值的存储过程

古人云:欲速则不达。首先是掌握最简单的存储过程,无返回值的存储过程:

案例:现在有一张表,字段有“书号,书名,出版社”。请编写一个存储过程,可以向book表添加书,要求通过JAVA程序调用该过程。

----book表

SQL>create table book (boodId number, bookName varchar2(50), publishHouse varchar2(50));

----编写存储过程

----in:表示这是一个输入参数!不写in,默认就是in!

----out:表示是一个输出参数

create or replace procedure sp_pro7

(spBookId in number, spbookName in varchar2, sppublishHouse in varchar2) is

begin

insert into book values(spBookId, spbookName, sppublishHouse);

end;                     

 

----在JAVA中调用

package com.sp;

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

import java.sql.*;

public class Test1 {

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.关闭各种打开的资源

}

}

}

 

②.1>有返回值的存储过程(非列表)

案例:编写一个过程,可以输入雇员的编号,返回该雇员的姓名。

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

-----有输入和输出的存储过程:

create or replace procedure sp_pro8

(spNo in varchar2, spName out varchar2) is

begin

select ename into spName from emp where empno=spNo;

end;

 

在JAVA中调用:

package com.sp;

//调用一个有返回值的过程

import java.sql.*;

public class Test1 {

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_pro8(?,?)}");

//4.1给第一个?赋值

cs.setInt(1,7788);

//4.2给第二个?赋值

cs.registerOutParameter(2, oracle.jdbc.OracleTypes.VARCHAR);

//5.执行

cs.execute();

//6.取出返回值,要注意?的顺序

String name=cs.getString(2);

System.out.println("7788的名字是:"+name);

}catch (Exception e){

e.printStackTrace();

}finally{

//7.关闭各种打开的资源

}

}

}

 

若有多个返回值!

create or replace procedure sp_pro8

(spNo in varchar2, spName out varchar2, spSal out number, spJob out varchar2) is

begin

select ename,sal,job into spName,spSal,spJob from emp where empno=spNo;

end;

 

package com.sp;

//调用一个有多个返回值的过程

import java.sql.*;

public class Test1 {

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_pro8(?,?,?,?)}");

//4.1给第一个?赋值

cs.setInt(1,7788);

//4.2给第二个?赋值

cs.registerOutParameter(2, oracle.jdbc.OracleTypes.VARCHAR);

//4.3给第三个?赋值

cs.registerOutParameter(3, oracle.jdbc.OracleTypes.DOUBLE);

//4.4给第四个?赋值

cs.registerOutParameter(4, oracle.jdbc.OracleTypes.VARCHAR);

//5.执行

cs.execute();

//6.取出返回值,要注意?的顺序

String name=cs.getString(2);

String job=cs.getString(4);

System.out.println("7788的名字是:"+name+" 工作:"+job);

}catch (Exception e){

e.printStackTrace();

}finally{

//7.关闭各种打开的资源

}

}

}

 

②.2>有返回值的存储过程(列表[结果集])

案例:编写一个过程,输入部门号,返回该部门所有雇员信息。

分析:由于ORACLE存储过程没有返回值,它的所有返回值都是通过out参数来替代的,列表同样也不例外,但是由于是集合,所以不能用一般的参数,必须要用package了。所以要分两部分:

 

<1>建一个包。如下:

-----创建一个包,在该包中,我定义类型 test_cursor, 是一个游标

create or replace package testpackage AS 

TYPE test_cursor is ref cursor;

end testpackage;

<2>创建过程

create or replace procedure sp_pro9

(spNo in number, p_cursor out testpackage.test_cursor) is

begin

open p_cursor for select * from emp where deptno=spNo;

end;

<3>在JAVA中调用

package com.sp;

//调用一个返回结果集的过程

import java.sql.*;

public class Test1 {

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_pro9(?,?)}");

//4.1给第一个?赋值

cs.setInt(1,10);

//4.2给第二个?赋值(注册一个问号)

cs.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);

//5.执行

cs.execute();

//6.得到结果集

ResultSet rs=(ResultSet)cs.getObject(2);

while(rs.next()){

System.out.println(rs.getInt(1)+" "+rs.getString(2));

}

}catch (Exception e){

e.printStackTrace();

}finally{

//7.关闭各种打开的资源

}

}

}

 

③:编写分页过程:

要求,编写一个存储过程:要求可以输入表名,每页显示记录数,当前页。返回总记录数,总页数,和返回的结果集。

ORACLE的分页 

SQL>select t1.*, rownum rn from (select * from emp) t1    //select * from emp=>内嵌视图

SQL>select t1.*,rownum rn from (select * from emp) t1 where rownum<=10;

SQL>select * from 

>(select t1.*,rownum rn from (select * from emp) t1 where rownum<=10)

>where rn>=6;

[在分页的时候,可以将上面的SQL语句当做一个模板使用]

分页过程

---a>开发一个包

create or replace package testpackage as

type test_cursor is ref cursor;

end testpackage;

 

---b>开始编写分页过程

create or replace procedure fenye

(tableName in varchar2,

pageSize in number, ---一页显示的记录数

pageNow in number, ---当前页数

myrows out number,   ---总记录数

myPageCount out number, ---总页数

p_cursor out testpackage.test_cursor  ---返回的记录集

) is

---定义部分

---定义sql语句 字符串

v_sql varchar2(1000);

---定义两个整数

v_begin number:=(pageNow-1)*pageSize+1;

v_end number:=pageNow*pageSize;

begin

---执行部分

v_sql:='select * from (select t1.*,rownum rn from (select * from '|| tableName ||') t1 where rownum<='||v_end||') where rn>='||v_begin||';

---把游标和sql关联

open p_cursor for v_sql;

---计算myrows和myPageCount

---组织一个sql

v_sql:='select count(*) from '||tableName;

---执行一个sql,并把返回的值,赋给myrows;

execute imediate v_sql into myrows;

---计算myPageCount

if mod(myrows,pageSize)=0 then

myPageCount:=myrows/pageSize;

else

myPageCount:=myrows/pageSize+1;

end if;

---关闭游标

close p_cursor;

end;

 

--c> 在JAVA中测试!

package com.sp;

import java.sql.*;

//测试分页

public class FenYe {

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 fenye(?,?,?,?,?,?}");

//4.1.给前三个输入参数的?赋值

cs.setString(1,"emp");

cs.setInt(2,5);

cs.setInt(3,1);

//4.2.给后面三个输出参数的?赋值

//4.2.1:注册总记录数

cs.registerOutParameter(4, oracle.jdbc.OracleTypes.INTEGER);

//4.2.2: 注册总页数

cs.registerOutParameter(5, oracle.jdbc.OracleTypes.INTEGER);

//4.2.3: 注册返回的结果集

cs.registerOutParameter(6, oracle.jdbc.OracleTypes.CURSOR);

//5.执行

cs.execute();

//6.取出总记录数/这儿要注意,getInt(4)中的"4"是由该参数的位置决定的

int rowNum=cs.getInt(4);

int pageCount=cs.getInt(5);

ResultSet rs=(ResultSet)cs.getObject(6);

//显示一下,阶段检测

System.out.println("rowNum="+rowNum);

System.out.println("页数:"+pageCount);

while(rs.next()){

System.out.println("编号:"+rs.getInt(1)+" 名字:"+rs.getString(2)); 

//这里面的"1"是结果集的第一列!

}

}catch (Exception e){

e.printStackTrace();

}finally{

//关闭资源

}

}

}

 

-----新的需求,要求按薪水的从低到高排序!

结果:修改一下存储过程即可,添加一个 order by sal ///默认是 asc 升序!从低到高!

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值