oracle pl/sql 分页
一、无返回值的存储过程
古人云:欲速则不达,为了让大家伙比较容易接受分页过程编写,我还是从简单到复杂,循序渐进的给大家讲解。首先是掌握最简单的存储过程,无返回值的存储过程。 案例:现有一张表book,表结构如下:书号、书名、出版社。
CREATE TABLE book(
ID NUMBER(4),
book_name VARCHAR2(30),
publishing VARCHAR2(30)
);
请写一个过程,可以向book表添加书,要求通过java程序调用该过程。

--注意:in->表示这是一个输入参数,默认为in --out->表示一个输出参数
CREATE OR REPLACE PROCEDURE ADD_BOOK(ID IN NUMBER,
NAME IN VARCHAR2,
PUBLISHING IN VARCHAR2) IS
BEGIN
INSERT INTO BOOK VALUES (ID, NAME, PUBLISHING);
COMMIT;
END;
/

java程序调用该存储过程的代码

package junit.test; import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager; /**
* 调用一个无返回值的存储过程
*
* @author jiqinlin
*
*/
public class ProcedureTest { 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:orcl", "scott", "oracle");
// 3.创建CallableStatement
CallableStatement cs = ct.prepareCall("call ADD_BOOK(?,?,?)");
//给?赋值
cs.setInt(1, 1);
cs.setString(2, "java");
cs.setString(3, "java出版社");
// 4.执行
cs.execute();
//5、关闭
cs.close();
ct.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

二、有返回值的存储过程(非列表)
案例:编写一个存储过程,可以输入雇员的编号,返回该雇员的姓名。
--输入和输出的存储过程
CREATE OR REPLACE PROCEDURE SP_PROC(SPNO IN NUMBER, SPNAME OUT VARCHAR2) IS
BEGIN
SELECT ENAME INTO SPNAME FROM EMP WHERE EMPNO = SPNO;
END;
/
java程序调用该存储过程的代码

package junit.test; import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager; /**
* 调用一个无返回值的存储过程
*
* @author jiqinlin
*
*/
public class ProcedureTest { 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:orcl", "scott", "oracle");
// 3.创建CallableStatement
CallableStatement cs = ct.prepareCall("{call sp_proc(?,?)}");
//给第一个?赋值
cs.setInt(1,7788);
//给第二个?赋值
cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);
//4、执行
cs.execute();
//取出返回值,要注意?的顺序
String name=cs.getString(2);
System.out.println("编号7788的名字:"+name);
//5、关闭
cs.close();
ct.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

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

--输入和输出的存储过程
CREATE OR REPLACE PROCEDURE SP_PROC(SPNO IN NUMBER,
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;
/

java程序调用该存储过程的代码

package junit.test; import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager; /**
* 调用一个无返回值的存储过程
*
* @author jiqinlin
*
*/
public class ProcedureTest { 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:orcl", "scott", "oracle");
// 3.创建CallableStatement
CallableStatement cs = ct.prepareCall("{call sp_proc(?,?,?,?)}");
//给第一个?赋值
cs.setInt(1,7788);
//给第二个?赋值
cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);
//给第三个?赋值
cs.registerOutParameter(3,oracle.jdbc.OracleTypes.DOUBLE);
//给第四个?赋值
cs.registerOutParameter(4,oracle.jdbc.OracleTypes.VARCHAR);
//4、执行
cs.execute();
//取出返回值,要注意?的顺序
String name=cs.getString(2);
double sal=cs.getDouble(3);
String job=cs.getString(4);
System.out.println("编号7788的名字:"+name+",职位:"+job+",薪水:"+sal+"");
//5、关闭
cs.close();
ct.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

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

CREATE OR REPLACE PROCEDURE SP_PROC(SPNO IN NUMBER,
P_CURSOR OUT TESTPACKAGE.TEST_CURSOR) IS
BEGIN
OPEN P_CURSOR FOR
SELECT * FROM EMP WHERE DEPTNO = SPNO;
END SP_PROC;
/

3)、如何在java 程序中调用该过程

package junit.test; import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet; /**
* 调用一个无返回值的存储过程
*
* @author jiqinlin
*
*/
public class ProcedureTest { 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:orcl", "scott", "oracle");
// 3.创建CallableStatement
CallableStatement cs = ct.prepareCall("{call sp_proc(?,?)}");
//给第一个?赋值
cs.setInt(1,10);
//给第二个?赋值
cs.registerOutParameter(2,oracle.jdbc.OracleTypes.CURSOR);
//4、执行
cs.execute();
//得到结果集
ResultSet rs = (ResultSet) cs.getObject(2);
while (rs.next()) {
System.out.println(rs.getInt(1) + " " + rs.getString(2));
}
//5、关闭
rs.close();
cs.close();
ct.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

四、编写分页过程
有了上面的基础,相信大家可以完成分页存储过程了。
要求,请大家编写一个存储过程,要求可以输入表名、每页显示记录数、当前页。返回总记录数,总页数,和返回的结果集。
--ROWNUM用法
SELECT o.*, ROWNUM RN FROM (SELECT * FROM EMP) o WHERE ROWNUM <= 10;
----oracle分页sql语句;在分页时,大家可以把下面的sql语句当做一个模板使用
SELECT *
FROM (SELECT o.*, ROWNUM RN FROM (SELECT * FROM EMP) o WHERE ROWNUM <= 10)
WHERE RN >= 6;
1)、开发一个包
建立一个包,在该包中定义类型为test_cursor的游标。

--建立一个包
CREATE OR REPLACE PACKAGE TESTPACKAGE AS
TYPE TEST_CURSOR IS REF CURSOR;
END TESTPACKAGE;
/ --开始编写分页的过程
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 ImMEDIATE V_SQL INTO MYROWS; --它解析并马上执行动态的SQL语句或非运行时创建的PL/SQL块.动态创建和执行SQL语句性能超前,
--EXECUTE IMMEDIATE的目标在于减小企业费用并获得较高的性能,较之以前它相当容易编码.
--尽管DBMS_SQL仍然可用,但是推荐使用EXECUTE IMMEDIATE,因为它获的收益在包之上。
--计算myPageCount
--if myrows%Pagesize=0 then 这样写是错的
IF MOD(MYROWS, PAGESIZE) = 0 THEN
MYPAGECOUNT := MYROWS/PAGESIZE;
ELSE
MYPAGECOUNT := MYROWS/PAGESIZE + 1;
END IF;
--关闭游标
--CLOSE P_CURSOR; --不要关闭,否则java调用该存储过程会报错
END;
/

java调用分页代码

package junit.test; import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet; /**
* 调用一个无返回值的存储过程
*
* @author jiqinlin
*
*/
public class ProcedureTest { 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:orcl", "scott", "oracle");
// 3.创建CallableStatement
CallableStatement cs = ct.prepareCall("{call fenye(?,?,?,?,?,?)}");
cs.setString(1, "emp"); //表名
cs.setInt(2, 5); //每页显示记录数
cs.setInt(3, 1);//页数
// 注册总记录数
cs.registerOutParameter(4, oracle.jdbc.OracleTypes.INTEGER); //总记录数
// 注册总页数
cs.registerOutParameter(5, oracle.jdbc.OracleTypes.INTEGER); //总页数
// 注册返回的结果集
cs.registerOutParameter(6, oracle.jdbc.OracleTypes.CURSOR); //返回的记录集
// 4、执行
cs.execute();
// 得到结果集
// 取出总记录数 /这里要注意,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) +
" 工资:" + rs.getFloat(6));
}
// 5、关闭
//rs.close();
cs.close();
ct.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

参见:http://www.cnblogs.com/linjiqin/archive/2012/02/28/2372096.html
oracle pl/sql 分页的更多相关文章
- 二十六、oracle pl/sql 分页
一.无返回值的存储过程 古人云:欲速则不达,为了让大家伙比较容易接受分页过程编写,我还是从简单到复杂,循序渐进的给大家讲解.首先是掌握最简单的存储过程,无返回值的存储过程. 案例:现有一张表book, ...
- [oracle]pl/sql --分页过程demo
这句sql能够用来查询一张表中的特定位置的记录 --查询的方法获取分页的语句 select *from (select t1.*,rownum rn from (select *from books) ...
- oracle15 pl/sql 分页
PL/SQL分页 编写分页过程 无返回值的存储过程 古人云:欲速则不达,为了让大家伙比较容易接受分页过程编写,我还是从简单到复杂,循序渐进的给大家讲解.首先是掌握最简单的存储过程,无返回值的存储过程: ...
- ORACLE PL/SQL编程详解
ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...
- [强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)
原文:[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) [强烈推荐]ORACLE PL/SQL编程详解之七: 程序包的创建与应用(聪明在于学习,天 ...
- ORACLE PL/SQL编程之八:把触发器说透
原文:ORACLE PL/SQL编程之八:把触发器说透 ORACLE PL/SQL编程之八: 把触发器说透 大家一定要评论呀,感谢!光发表就花了我将近一个下午. 本篇主要内容如下: 8.1 触发器类型 ...
- [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)
原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...
- ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)
原文:ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) ORACLE PL/SQL编程之六: 把过程与函数说透(穷追猛打,把根儿都拔起!) 继上篇:ORACLE P ...
- [推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)
原文:[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆) [推荐]ORACLE PL/SQL编程详解之三: PL/SQL流程控制语句(不给规则,不成方圆) ...
随机推荐
- Codeforces Round #429 (Div. 2) 补题
A. Generous Kefa 题意:n个气球分给k个人,问每个人能否拿到的气球都不一样 解法:显然当某种气球的个数大于K的话,就GG了. #include <bits/stdc++.h> ...
- 九天学会Java,第四天,循环结构
变量和数据类型,赋值和输出 算术运算 选择结构 循环结构 函数定义,函数调用 变量作用域 栈,程序运行的基石 面向对象 异常处理 语言提供的公用包 这次我们讲Java的循环结构.循环结构在编程中广泛使 ...
- Java入门(2) —— 变量详解、运算符、定义类和定义方法以及方法的调用
1.变量 1.定义变量 1.声明的同时直接赋值 数据类型 变量名 = 值; 2.先声明,后赋值 声明: 数据类型 变量名; 赋值: 变量名 = 值; 2.数据类型 基本数据类型:4类8种 整数 --- ...
- RPC框架实现思路浅析
第一部分,设计分析 远程调用要解决的主要问题: 1,序列化 : 如何将对象转化为二进制数据进行传输,如何将二进制数据转化对象 2,数据的传输(协议,第三方框架) 3,服务的注册/发现,单点故障,分布式 ...
- zTree勾选状态的禁用节点不在选中节点里
问题描述: 由于业务需求,需要将一部分节点设置为选中并且是禁用的状态.设置这部分节点的chkDisabled和checked属性值都为true.在zTree树上这部分节点是选中且禁用的状态,但是在保存 ...
- java读取txt文件内容
package read; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; public ...
- 201521123052《Java程序设计》第6周学习总结
1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...
- 2015211230554《Java程序设计》第6周学习总结
1. 本周学习总结 2. 书面作业 1.1 Object对象中的clone方法是被protected修饰,在自定义的类中覆盖clone方法时需要注意什么? 克隆方法用于创建对象的拷贝,为了使用clon ...
- 201521123013 《Java程序设计》第3周学习总结
1. 本章学习总结 2. 书面作业 Q1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; ...
- JAVA课程设计个人博客 学生成绩管理 201521145048 林健
1. 团队课程设计博客链接 http://www.cnblogs.com/kawajiang/p/7062407.html 2.个人负责模块或任务说明 本人主要负责支持用户登录.验证操作,显示设计界面 ...