二十六、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();
}
}
}
复制代码
二十六、oracle pl/sql 分页的更多相关文章
- 二十、oracle pl/sql基础
一.pl/sql developer开发工具pl/sql developer是用于开发pl/sql块的集成开发环境(ide),它是一个独立的产品,而不是oracle的一个附带品. 二.pl/sql介绍 ...
- oracle学习笔记(十六) PL/SQL 异常和goto语句
PL/SQL 异常和goto语句 异常 预定义异常 oracle常见预定义异常: 错误号 异常错误信息名称 说明 ORA-0001 DUP_VAL_ON_INDEX 试图破坏一个唯一性限制 ORA-0 ...
- oracle pl/sql 分页
一.无返回值的存储过程 古人云:欲速则不达,为了让大家伙比较容易接受分页过程编写,我还是从简单到复杂,循序渐进的给大家讲解.首先是掌握最简单的存储过程,无返回值的存储过程. 案例:现有一张表book, ...
- 二十三、oracle pl/sql分类三 包
包用于在逻辑上组合过程和函数,它由包规范和包体两部分组成.1).我们可以使用create package命令来创建包,如:i.创建一个包sp_packageii.声明该包有一个过程update_sal ...
- [oracle]pl/sql --分页过程demo
这句sql能够用来查询一张表中的特定位置的记录 --查询的方法获取分页的语句 select *from (select t1.*,rownum rn from (select *from books) ...
- 二十一、oracle pl/sql分类一 存储过程
存储过程用于执行特定的操作,当建立存储过程时,既可以指定输入参数(in),也可以指定输出参数(out),通过在过程中使用输入参数,可以将数据传递到执行部分:通过使用输出参数,可以将执行部分的数据传递到 ...
- [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)
原文:[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日 ...
- [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)
原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下 ...
- Oracle PL/SQL入门之慨述
Oracle PL/SQL入门之慨述 一.PL/SQL出现的目的 结构化查询语言(Structured Query Language,简称SQL)是用来访问关系型数据库一种通用语言,它属于第四代语言( ...
随机推荐
- hdu 4515 年月份模拟题
小Q系列故事——世界上最遥远的距离 Time Limit: 500/200 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) ...
- [C++STDlib基础]关于C标准输入输出的操作——C++标准库头文件<cstdio>
网上实例 总结 /* _STD_BEGIN using _CSTD clearerr; using _CSTD fclose; using _CSTD feof; using _CSTD ferror ...
- Js-Html 前端系列--checkbox
今天搞全选按钮,设置Checkbox的时候,处于Checked状态但是不显示勾.最后得出解决方案: var c = boxcList.eq(i).attr("checked"); ...
- JS算法之快排&冒泡
1.快速排序思想: 1.1 先找数组的最中间的一个数为基准 1.2 把数组通过此基准分为小于基准的left数组和大于基准的right数组, 1.3 递归重复上面的两个步骤, 代码如下: functio ...
- 多目标遗传算法 ------ NSGA-II (部分源码解析)介绍
NSGA(非支配排序遗传算法).NSGA-II(带精英策略的快速非支配排序遗传算法),都是基于遗传算法的多目标优化算法,是基于pareto最优解讨论的多目标优化. 在官网: http://www.ii ...
- Date类型常用概念及方法总结(1)
Date类型使用UTC(国际协调时间)1970年1月1日零时开始经过的毫秒数来保存时间. (1)创建当前日期 调用Date不传递参数的情况下,创建的新对象自动获得当前日期和时间 ...
- react-gulp-browserify
环境搭配参照 http://www.cnblogs.com/guolaomao/p/6276877.html 前半部分的内容. 首先安装browserify npm install --save-de ...
- Win32窗口
#include <Windows.h> #include <CommCtrl.h> #pragma comment(lib, "comctl32.lib" ...
- SVN版本控制的使用
下面说一说本人对SVN工具使用的理解: SVN就是一个工具,一个用来便于多人(或说团队)开发代码的版本控制工具,我们可以用它很好的把多个程序员开发出来的代码统一起来,并且保证在这个工程中不出现任何差错 ...
- Html5浏览器端less应用
之前的一个布局是用rem来做的 我上一段代码 div { margin: 0.833333333rem 0; } /* 去处a标签的下划线*/ a { text-decoration: none; } ...