需要用到的接口

接口 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调用存储过程、存储函数的更多相关文章

  1. Java 调用存储过程、函数

     一.Java调用存储Oracle存储过程 测试用表: --创建用户表 create table USERINFO ( username ) not null, password ) not null ...

  2. java调用存储过程和函数

    以对表test进行增,删,改,查进行说明:1.新建表test create table TEST ( TID NUMBER not null, TNAME VARCHAR2(32), TCODE VA ...

  3. 【转】java调用存储过程和函数

    一.概述 如果想要执行存储过程,我们应该使用 CallableStatement 接口. CallableStatement 接口继承自PreparedStatement 接口.所以CallableS ...

  4. JDBC第二篇--【PreparedStatment、批处理、处理二进制、自动主键、调用存储过程、函数】

    这是我JDBC的第一篇 http://blog.csdn.net/hon_3y/article/details/53535798 1.PreparedStatement对象 PreparedState ...

  5. JDBC【PreparedStatment、批处理、处理二进制、自动主键、调用存储过程、函数】

    1.PreparedStatement对象 PreparedStatement对象继承Statement对象,它比Statement对象更强大,使用起来更简单 Statement对象编译SQL语句时, ...

  6. Oracle数据库游标,序列,存储过程,存储函数,触发器

    游标的概念:     游标是SQL的一个内存工作区,由系统或用户以变量的形式定义.游标的作用就是用于临时存储从数据库中提取的数据块.在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理, ...

  7. Oracle学习(十二):存储过程/存储函数

    1.知识点 --第一个存储过程 /* 打印Hello World create [or replace] PROCEDURE 过程名(參数列表) AS PLSQL子程序体: 调用存储过程: 1. ex ...

  8. JDBC(13)—JDBC调用存储过程和函数

    步骤: JDBC调用存储过程和函数 步骤: ①:通过Connection对象的prepareCall()方法创建一个CallableStatement对象的实例,在使用Connection对象的pre ...

  9. Oracle学习2 视图 索引 sql编程 游标 存储过程 存储函数 触发器

    ---视图 ---视图的概念:视图就是提供一个查询的窗口,来操作数据库中的数据,不存储数据,数据在表中. ---一个由查询语句定义的虚拟表. ---查询语句创建表 create table emp a ...

  10. oracle 存储过程,存储函数,包,

    http://heisetoufa.iteye.com/blog/366957 认识存储过程和函数 存储过程和函数也是一种PL/SQL块,是存入数据库的PL/SQL块.但存储过程和函数不同于已经介绍过 ...

随机推荐

  1. Nginx中间件使用心得(二)

    一.基础知识补充 1. 历史由来补充: Nginx是俄罗斯第二大网站的开源项目. 淘宝团队发行了 tengine 增加了很多第三方的包. 2.下载相关的主键 (1)nginx下载地址          ...

  2. nginx 配置图片服务器 (window版本)

    配置nginx二级域名 ①找到配置文件 例如:%nginx_home%/conf/nginx.conf ②配置 #user nobody; worker_processes 1; #error_log ...

  3. POP介绍与使用实践(快速上手动画)[转]

    前言 动画在APP开发过程中 大家多多少少都会接触到 而且随着ios7的扁平化风格启用之后 越来越多的APP开始尝试加入各种绚丽的动画交互效果以增加APP的用户体验(当然 还是以国外的APP居多) 有 ...

  4. APUE(5)---标准I/O库 (3)

    十.定位流 #include <stdio.h> long ftell(FILE *fp); //若成功,返回当前文件位置指示:若出错,返回-1L int fseek(FILE *fp, ...

  5. 用Java取指定时区的时间 北京时间,纽约时间,班加罗尔时间

    /** * 取北京时间 * @return */ public static String getBeijingTime(){ return getFormatedDateString(8); } / ...

  6. delphi自带的SHA1算法

    delphi自带的SHA1算法 uses IdHashSHA, IdGlobal; function SHA1(Input: String): String; begin with TIdHashSH ...

  7. CUDA开发 - CUDA 版本

    "CUDA runtime is insufficient with CUDA driver"CUDA 9.2: 396.xx CUDA 9.1: 387.xx CUDA 9.0: ...

  8. Gzip压缩和解压

    /// <summary> /// 将传入字符串以GZip算法压缩后,返回Base64编码字符 /// </summary> /// <param name=" ...

  9. [C#学习笔记]lock锁的解释与用法

    写在前面 前几时在写业务代码的时候,看到有用到lock这个方法的,而我竟然并不知道是做什么用的,所以查找了许多博客文章,弄懂了百分之七八十,在此做下笔记. 感谢博客 http://www.cnblog ...

  10. netcore问题总结

    1. webclient在在netcore异步文件下载的时候,下载进度为空,只有最后下载完了,进度才会是100%,但是在netframework中就没有这个问题,异步文件下载进度会正常提醒. 2. n ...