Java代码调用Oracle的存储过程,存储函数和包
Java代码调用存储过程和存储函数要使用CallableStatement接口
查看API文档:
上代码:
java代码调用如下的存储过程和函数:
查询某个员工的姓名 月薪 职位
create or replace procedure queryEmpinfo(eno in number,
pename out varchar2,
psal out number,
pjob out varchar2)
as
begin
select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;
end;
--查询某个员工的年收入
create or replace function queryEmpIncome(eno in number)
return number
as
psal emp.sal%type;
pcomm emp.comm%type;
begin
select sal,comm into psal,pcomm from emp where empno=eno; --返回年收入
return psal*12+nvl(pcomm,0); end;
--在out参数中使用光标
查询某个部门中所有员工的所有信息 包头
CREATE OR REPLACE PACKAGE MYPACKAGE AS type empcursor is ref cursor;
procedure queryEmpList(dno in number,empList out empcursor); END MYPACKAGE; 包体
CREATE OR REPLACE
PACKAGE BODY MYPACKAGE AS procedure queryEmpList(dno in number,empList out empcursor) AS
BEGIN
open empList for select * from emp where deptno=dno;
END queryEmpList; END MYPACKAGE;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException; import oracle.jdbc.driver.OracleCallableStatement;
import oracle.jdbc.driver.OracleTypes; import org.junit.Test; public class TestOracle { /*
* CallableStatement 接口
* 调用存储函数,等号左边有一个返回值
* {?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
* 调用存储过程. 没有返回值
{call <procedure-name>[(<arg1>,<arg2>, ...)]} *
*/ /*存储过程 查询某个员工的姓名 月薪 职位
* create or replace procedure queryEmpinfo(eno in number,
pename out varchar2,
psal out number,
pjob out varchar2)
*/ @Test
public void testProcedure(){
//{call <procedure-name>[(<arg1>,<arg2>,...)]}
String sql = "{call queryEmpinfo(?,?,?,?)}";//4个问号中,第一个是输入参数,其余是输出参数
Connection conn = null;
//要用CallableStatement这个接口,用于执行 SQL 存储过程的接口
CallableStatement call = null; try {
conn = JDBCUtils.getConnection();
call = conn.prepareCall(sql);
//对于in参数,需要赋值
call.setInt(1,7839);
//对于out参数,需要声明
call.registerOutParameter(2, OracleTypes.VARCHAR);//第二个是字符串
call.registerOutParameter(3, OracleTypes.NUMBER);//第三个是数字
call.registerOutParameter(4, OracleTypes.VARCHAR);//第四个是字符串 call.execute();
//取出结果
String name = call.getString(2);
double sal = call.getDouble(3);
String job = call.getString(4);
System.out.println(name+"\t"+sal+"\t"+job+"\t");
} catch (SQLException e) {
e.printStackTrace();
}finally{
JDBCUtils.release(conn, call, null);//没有最后一个参数就传入null
}
} /*存储函数 查询某个员工的姓名,月薪和职位
* create or replace function queryEmpIncome(eno in number)
return number
*/
@Test
public void testFunction(){
//{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
//第一个问号是函数的返回值,第二个问号是输入参数. 返回值的作用和输出参数是一样的.
String sql = "{?=call QUERYEMPINCOME(?)}";//这个call后面的存储过程名或者是存储函数名大写或者是小写是没有要求的.
Connection conn = null;
//要用CallableStatement这个接口,用于执行 SQL 存储过程的接口
CallableStatement call = null; try {
conn = JDBCUtils.getConnection();
call = conn.prepareCall(sql); //对于in参数,赋值
call.setInt(2,7839); //对于out参数,申明
call.registerOutParameter(1, OracleTypes.NUMBER);
call.execute();
//取出结果
//取出结果
double income = call.getDouble(1);
System.out.println(income);
} catch (SQLException e) {
e.printStackTrace();
}finally{
JDBCUtils.release(conn, call, null);//没有最后一个参数就传入null
} } /*
查询某个部门中所有员工的所有信息
包头
CREATE OR REPLACE PACKAGE MYPACKAGE AS type empcursor is ref cursor;
procedure queryEmpList(dno in number,empList out empcursor); END MYPACKAGE; 包体
CREATE OR REPLACE
PACKAGE BODY MYPACKAGE AS procedure queryEmpList(dno in number,empList out empcursor) AS
BEGIN
open empList for select * from emp where deptno=dno;
END queryEmpList; END MYPACKAGE;
*/
@Test
public void testCursor(){
//{call <procedure-name>[(<arg1>,<arg2>, ...)]}
String sql = "{call MYPACKAGE.queryEmpList(?,?)}"; Connection conn = null;
CallableStatement call = null;
//有游标,就有结果集
ResultSet rest = null;
try {
conn = JDBCUtils.getConnection();
call = conn.prepareCall(sql); //对于in参数,赋值
call.setInt(1, 20); //对于out参数,申明
call.registerOutParameter(2, OracleTypes.CURSOR);
call.execute();
//取出集合
//这个地方要强转!!!OracleCallableStatement是抽象类,继承了CallableStatement
//不强转没有getCursor()方法...
rest = ((OracleCallableStatement)call).getCursor(2);
while(rest.next()){
String name = rest.getString("ename");
double sal = rest.getDouble("sal");
System.out.println(name+"\t"+sal);
}
}catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.release(conn, call, rest);//上面打开了光标,再这个地方关闭结果集rest,也就关闭了光标
}
}
}
关于Oracle中的包对象:
之前的存储函数中查询的是某一个员工的信息:
create or replace procedure queryEmpinfo(eno in number,
pename out varchar2,
psal out number,
pjob out varchar2)
as
begin
select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;
end;
但是①如果要查询一个员工的所有信息,而这个员工的信息对应的有几百列
在存储函数中括号的函数要把这几百列都声明出来?
②如果要查询某个部门中所有员工的所有信息...这个信息对应的是一个集合.
第二个问题解决了第一个问题也就解决了.
怎么在存储过程或者存储函数中返回一个集合.
学到现在有多少种方式可以代表一个集合?
第一个是表,第二个是select语句也可以.第三个是光标.
在out参数中使用光标.但是有一个要求,必须要声明一个包,包分为包头和包体.也是数据库的对象.跟表,视图,等是一样的是数据库的对象.
包头只负责声明,包体只负责实现.

--在out参数中使用光标
查询某个部门中所有员工的所有信息 包头
CREATE OR REPLACE PACKAGE MYPACKAGE AS type empcursor is ref cursor;
procedure queryEmpList(dno in number,empList out empcursor); END MYPACKAGE; 包体
CREATE OR REPLACE
PACKAGE BODY MYPACKAGE AS procedure queryEmpList(dno in number,empList out empcursor) AS
BEGIN
open empList for select * from emp where deptno=dno;
END queryEmpList; END MYPACKAGE;
分析图:

参看包:

包无法在plsqldeveloper和sqldeveloper等工具中右键运行....必须通过java代码应用程序来调用执行(代码在上面)
Java代码调用Oracle的存储过程,存储函数和包的更多相关文章
- 【学习】java下实现调用oracle的存储过程和函数
在oracle下创建一个test的账户,然后按一下步骤执行: 1.创建表:STOCK_PRICES --创建表格CREATETABLE STOCK_PRICES( RIC VARCHAR(6) PRI ...
- java下实现调用oracle的存储过程和函数
在Oracle下创建一个test的账户,然后 1.创建表:STOCK_PRICES --创建表格 CREATE TABLE STOCK_PRICES( RIC VARCHAR() PRIMARY KE ...
- java代码调用oracle存储过程
一.简介 与调用mysql存储过程类型过程都是如下 1.创建连接 Connection conn = DriverManager.getConnection(url, user, password); ...
- Java 如何调用 oracle 的存储过程
通过命令行创建存储过程 create or replace procedure emp_sal(eno emp.empno%type,esal out emp.sal%type) as begin s ...
- Oracle学习(十二):存储过程/存储函数
1.知识点 --第一个存储过程 /* 打印Hello World create [or replace] PROCEDURE 过程名(參数列表) AS PLSQL子程序体: 调用存储过程: 1. ex ...
- Oracle03——游标、异常、存储过程、存储函数、触发器和Java代码访问Oracle对象
作者: kent鹏 转载请注明出处: http://www.cnblogs.com/xieyupeng/p/7476717.html 1.游标(光标)Cursor 在写java程序中有集合的概念,那么 ...
- oracle 存储过程,存储函数,包,
http://heisetoufa.iteye.com/blog/366957 认识存储过程和函数 存储过程和函数也是一种PL/SQL块,是存入数据库的PL/SQL块.但存储过程和函数不同于已经介绍过 ...
- java代码调用数据库存储过程
由于前边有写java代码调用数据库,感觉应该把java调用存储过程也写一下,所以笔者补充该篇! package testSpring; import java.sql.CallableStatemen ...
- Oracle学习2 视图 索引 sql编程 游标 存储过程 存储函数 触发器
---视图 ---视图的概念:视图就是提供一个查询的窗口,来操作数据库中的数据,不存储数据,数据在表中. ---一个由查询语句定义的虚拟表. ---查询语句创建表 create table emp a ...
随机推荐
- ICMP协议、DNS、ARP协议、ping、DHCP协议
1.ICMP协议 1)ICMP协议,即:网络控制消息协议(Internet Control Message Protocol) 2)ICMP是网络层协议,因为ICMP报文是装在IP数据报中,作为它的数 ...
- 最全js表单验证
/***************************************************************** 表单校验工具类 (linjq) ***************** ...
- 第23章:MongoDB-聚合操作--聚合命令
①count() 范例:统计students表中的数据量 db.students.count(); 范例:模糊查询 db.students.count("name":/张/i); ...
- C#时间操作总结
命名空间:System.Diagnostics Stopwatch 实例可以测量一个时间间隔的运行时间,也可以测量多个时间间隔的总运行时间.在典型的 Stopwatch 方案中,先调用 Start 方 ...
- Swift:用UICollectionView整一个瀑布流
本文的例子和Swift版本是基于Xcode7.2的.以后也许不知道什么时候会更新. 我们要干点啥 用新浪微博的Open API做后端来实现我们要提到的功能.把新浪微博的内容,图片和文字展示在colle ...
- noip第17课作业
1. 召见骑士 [问题描述] 某王国有5位骑士,每位骑士都有自己的编号,且这个王国的编号都为奇数,分别为1,3,5,7,9,在国王召见他们之前他们都必须经过只能从一边进出的长廊,长廊的宽度只能坐一个 ...
- Alpha冲刺 - (10/10)
Part.1 开篇 队名:彳艮彳亍团队 组长博客:戳我进入 作业博客:班级博客本次作业的链接 Part.2 成员汇报 组员1(组长)柯奇豪 过去两天完成了哪些任务 本人负责的模块(共享编辑)的前端代码 ...
- MEAN 27
添加评论主题页,在26的基础上. 新建了很多文件 Error: Cannot find module './controllers/customers_c' 解决办法:../ 接下来做function ...
- Android自适应屏幕的实现方法
首先我们先了解下手机分辨率 分辨率是指屏幕上有横竖各有多少个像素目前手机分辨率大概情况如下: QVGA 分辨率:320×240 简 介:QVGA即"Quarter VGA". ...
- NODE-WEBKIT教程(5)NATIVE UI API 之FRAMELESS WINDOW
node-webkit教程(5)Native UI API 之Frameless window 文/玄魂 原文链接:http://www.xuanhun521.com/Blog/2014/4/15/n ...