java调用存储过程、存储函数
需要用到的接口
接口 CallableStatement
JDK文档对改接口的说明:
public interface CallableStatement
extends
PreparedStatement
用于执行 SQL 存储过程的接口。JDBC API 提供了一个存储过程 SQL 转义语法,该语法允许对所有 RDBMS 使用标准方式调用存储过程。此转义语法有一个包含结果参数的形式和一个不包含结果参数的形式。如果使用结果参数,则必须将其注册为 OUT 参数。其他参数可用于输入、输出或同时用于二者。参数是根据编号按顺序引用的,第一个参数的编号是 1。
{?= call <procedure-name>[(<arg1>,<arg2>, ...)]} -------存储函数的sql,第一个?代表返回类型
{call <procedure-name>[(<arg1>,<arg2>, ...)]} -------存储过程的sql
IN 参数值是使用继承自 PreparedStatement 的 set 方法设置的。在执行存储过程之前,必须注册所有 OUT 参数的类型;它们的值是在执行后通过此类提供的 get 方法获取的。
CallableStatement 可以返回一个 ResultSet 对象或多个 ResultSet 对象。多个 ResultSet 对象是使用继承自 Statement 的操作处理的。
为了获得最大的可移植性,某一调用的 ResultSet 对象和更新计数应该在获得输出参数的值之前处理。
例子程序
对oracle的scott/tiger用户的emp表操作
存储过程,查询员工信息
create or replace procedure queryEmpInfo(eno in number,
pename out varchar2,
psal out number,
pjob out varchar2)
as
begin
select ename,sal,job into pename,psal,pjob from emp where empno=eno;
end;
存储函数:
create or replace function queryEmpImcome(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+nvl(pcomm,0))*12; end;
jdbc工具类
package com.lhy.util;
import java.sql.*; /**
* JDBC工具类 ,一般工具类final。
* 工具类一般不需要new,不需要构造实例。(把构造方法私有)别人就new不了了。
* 此时使用类的方法:
* 1是单例模式(复杂点)
* 2是提供静态的public方法。(简单)
* 本例子是简单的提供public方法实现的。需要静态方法
*
* @author hy
*
*/
public final class JdbcUtils {
private static String url ="jdbc:oracle:thin:@127.0.0.1:1521:ORCL";
private static String user ="scott";
private static String passWord = "tiger"; //构造方法私有,别人不能构造,不会有实例出来.
private JdbcUtils(){ } /**
* 静态代码块,类加载到虚拟机是只执行一次。
*/
static {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) { e.printStackTrace();
} } public static Connection getConnection() {
Connection conn = null;
try {
conn = DriverManager.getConnection(url,user,passWord);
} catch (SQLException e) { e.printStackTrace();
}
return conn; } //释放资源,重载方法。
public static void close(Connection conn) {
try {
if(conn != null){
conn.close();
conn = null;
}
}catch(SQLException e){
e.printStackTrace();
}
}
public static void close(Statement stmt){
try{
if(stmt != null){
stmt.close();
stmt = null;
}
}catch(SQLException e){
e.printStackTrace();
}
}
public static void close(ResultSet rs){
try{
if(rs != null){
rs.close();
rs = null;
}
}catch (SQLException e) {
e.printStackTrace();
}
}
}
测试程序:
public class OracleTest {
/**
* 测试存储过程
* create or replace procedure queryEmpInfo(eno in number,
pename out varchar2,
psal out number,
pjob out varchar2)
as
begin
select ename,sal,job into pename,psal,pjob from emp where empno=eno;
end;
*/
@Test
public void testProcedure(){
//格式 {call <procedure-name>[(<arg1>,<arg2>, ...)]}
String sql = "{call queryEmpInfo(?,?,?,?)}";
Connection conn = null;
CallableStatement call = null;
try {
conn = JdbcUtils.getConnection();
call = conn.prepareCall(sql);
//赋值
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.err.println(name);
System.err.println(sal);
System.err.println(job);
}catch(Exception e){
e.printStackTrace();
}finally{
JdbcUtils.close(call);
JdbcUtils.close(conn);
}
}
/**
* 测试 存储函数
* create or replace function queryEmpImcome(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+nvl(pcomm,0))*12;
end;
*/
@Test
public void testFunction(){
//{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
//第一个?--> 输出参数,返回值, 第二个 ?-->输入参数
String sql = "{?= call queryEmpImcome(?)}";
Connection conn = null;
CallableStatement call = null;
try {
conn = JdbcUtils.getConnection();
call = conn.prepareCall(sql);
//注册输出参数
call.registerOutParameter(1, OracleTypes.NUMBER);
//输入参数
call.setInt(2, 7839);
//执行
call.execute();
//取出年收入,注意是get 1
double income = call.getDouble(1);
System.err.println("年收入:"+income);
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtils.close(call);
JdbcUtils.close(conn);
}
}
}
运行结果:

性能
Statement < preparedStatement < CallableStatement
在Out参数中使用游标

package:程序包
上边的例子的存储过程,输出参数只有三个,如果输出参数有很多,或者输出结果是一个结果集(如查询一个部门中所有员工的信息),此时就需要在out参数中使用游标
例子:查询某个部门所有员工的所有信息
使用PLSQL建包

1,新建包
create or replace package MYPACKAGE as type empcursor is ref cursor; procedure queryEmpList(dno in number,empList out empcursor); end MYPACKAGE;
2,新建包体
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;
使用java程序测试:
@Test
public void testCursor(){
String sql = "{call MYPACKAGE.queryEmpList(?,?)}";
Connection conn = null;
CallableStatement call = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
call = conn.prepareCall(sql); call.setInt(1, 10);
call.registerOutParameter(2, OracleTypes.CURSOR); //执行
call.execute();
//取出集合,转换为OracleCallableStatement,去除游标
rs = ((OracleCallableStatement)call).getCursor(2);
while(rs.next()){
String name = rs.getString("ename");
String job = rs.getString("job");
double salary = rs.getDouble("sal"); System.err.println("姓名:"+name+",职位:"+job+",薪水:"+salary); } } catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtils.close(rs);
JdbcUtils.close(call);
JdbcUtils.close(conn);
}
}

光标当ResultSet关闭的时候就关闭了
java调用存储过程、存储函数的更多相关文章
- Java 调用存储过程、函数
一.Java调用存储Oracle存储过程 测试用表: --创建用户表 create table USERINFO ( username ) not null, password ) not null ...
- java调用存储过程和函数
以对表test进行增,删,改,查进行说明:1.新建表test create table TEST ( TID NUMBER not null, TNAME VARCHAR2(32), TCODE VA ...
- 【转】java调用存储过程和函数
一.概述 如果想要执行存储过程,我们应该使用 CallableStatement 接口. CallableStatement 接口继承自PreparedStatement 接口.所以CallableS ...
- JDBC第二篇--【PreparedStatment、批处理、处理二进制、自动主键、调用存储过程、函数】
这是我JDBC的第一篇 http://blog.csdn.net/hon_3y/article/details/53535798 1.PreparedStatement对象 PreparedState ...
- JDBC【PreparedStatment、批处理、处理二进制、自动主键、调用存储过程、函数】
1.PreparedStatement对象 PreparedStatement对象继承Statement对象,它比Statement对象更强大,使用起来更简单 Statement对象编译SQL语句时, ...
- Oracle数据库游标,序列,存储过程,存储函数,触发器
游标的概念: 游标是SQL的一个内存工作区,由系统或用户以变量的形式定义.游标的作用就是用于临时存储从数据库中提取的数据块.在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理, ...
- Oracle学习(十二):存储过程/存储函数
1.知识点 --第一个存储过程 /* 打印Hello World create [or replace] PROCEDURE 过程名(參数列表) AS PLSQL子程序体: 调用存储过程: 1. ex ...
- JDBC(13)—JDBC调用存储过程和函数
步骤: JDBC调用存储过程和函数 步骤: ①:通过Connection对象的prepareCall()方法创建一个CallableStatement对象的实例,在使用Connection对象的pre ...
- Oracle学习2 视图 索引 sql编程 游标 存储过程 存储函数 触发器
---视图 ---视图的概念:视图就是提供一个查询的窗口,来操作数据库中的数据,不存储数据,数据在表中. ---一个由查询语句定义的虚拟表. ---查询语句创建表 create table emp a ...
- oracle 存储过程,存储函数,包,
http://heisetoufa.iteye.com/blog/366957 认识存储过程和函数 存储过程和函数也是一种PL/SQL块,是存入数据库的PL/SQL块.但存储过程和函数不同于已经介绍过 ...
随机推荐
- Nginx的两种负载均衡搭建(Tomcat版)
前言 Nginx的负载均衡一般采用upstream来实现,但是,还有另一种文件拓展的方式,同样可以实现负载均衡. 一.一般的负载均衡 upstream my_server { server local ...
- js继承——扩展Object方式实现继承
function Parent(name,sex){ this.name = name; this.sex = sex; this.sayName = function(){ console.log( ...
- python 实现排列组合
1.python语言简单.方便,其内部可以快速实现排列组合算法,下面做简单介绍. 2.一个列表数据任意组合 2.1主要是利用自带的库 #_*_ coding:utf-8 _*_ #__author__ ...
- Cadence丢失了csdCommon.dll
http://bbs.elecfans.com/jishu_450237_1_1.html
- 新浪微博mid和url的互算
我们在使用新浪微博API时,有时需要得到一个微博的url,但是如statuses/public_timeline等接口中取得的微博status的字段中并没有包含.不过,status中包含了一个mid字 ...
- Spring bean是如何加载的
Spring bean是如何加载的 加载bean的主要逻辑 在AbstractBeanFactory中doGetBean对加载bean的不同情况进行拆分处理,并做了部分准备工作 具体如下 获取原始be ...
- ENVI数据格式
选择一个或多个感兴趣的图层: 分类:目视解译.非监督分类 投影 哪里需要七参数,没有必要七参数吧?如果精度要求不高的话
- MFC自动生成代码详解(一)
首先声明这篇博客是给MFC刚刚上路的coder准备的,老鸟们就自觉无视我吧! 大家有没有感觉,创建MFC工程时他总会生成一大堆文件一大堆代码.虽然给我们带来了便利,但是调试的时候碰到这些代码总是畏首畏 ...
- web.xml文件中context-param、listener、filter、servlet的执行顺序
首先可以肯定的是,加载顺序与它们在 web.xml 文件中的先后顺序无关.即不会因为 filter 写在 listener 的前面而会先加载 filter.最终得出的结论是:listener -> ...
- 循环读取list 的几种方法?
1.最常用的方法.循环找出该位子的list元素for(int i = 0;i < list.size(); i ++){System.out.println(list.get(i));}2.利用 ...