Java 调用存储过程 怎么知道完成了 jdbc调用存储过程的对象
转载
JDBC调用存储过程之实例讲解
【说明】:本文主要讲解使用JDBC调用存储过程的各种方案,数据库使用Oracle(其他数据库类似)涉及到的数据表均为Oracle自带的Scott帐号的数据表。
【引言】:存储过程是数据库使用的重要技术之一,以其高效率、高安全性见长,而JDBC调用存储过程也是Java程序员必掌握的技能之一。JDBC调用存储过程主要使用CallableStatement接口,而对于输入(in)和输出(out)参数的处理也比较复杂,本文使用案例并有详细注解来说明各种情况。
一、调用带输入\输出参数的存储过程
1. 建立存储过程
-- 输入职工号(zgh)、输出姓名(xm)和工资(gz)
create or replace procedure getNameSalByNo(zgh in emp.empno%type,xm out emp.ename%type,gz out emp.sal%type)
is
begin
select ename,sal into xm,gz from emp where empno=zgh;
end;
|
2. JDBC的调用
package com.tjxz.proc;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;
public class CallProcedure {
/**
* 调用带普通参数的存储过程
* @author icer
* @web http://www.tjxz.com
*/
public static void main(String[] args) {
// 设置JDBC参数信息
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
String uid = "scott";
String pwd = "triger";
try {
// 创建接受返回值的变量(姓名:xm,工资:gz)
String xm="";
float gz=0.0f;
/*
* 准备SQL语句
|
* 格式为: {call 存储过程名{?,?,?}}
* 括号中的问号和存储过程参数进行匹配
*/
String sql = "{call getNameSalByNo(?,?,?)}";
// 加载驱动程序
Class.forName("oracle.jdbc.driver.OracleDriver");
// 获取连接对象
Connection con = DriverManager.getConnection(url, uid, pwd);
// 获取执行对象
CallableStatement cst = con.prepareCall(sql);
// 执行之前要使用setXXX来替换SQL语句中的问号参数
cst.setInt(1, 7788);
// 注册输出参数类型(注意索引要和问号的位置对应)
cst.registerOutParameter(2, Types.VARCHAR);
cst.registerOutParameter(3, Types.FLOAT);
// 执行SQL命令
cst.execute();
// 提取输出参数
xm = cst.getString(2);
gz = cst.getFloat(3);
// 控制台输出
System.out.println("姓名:" + xm);
System.out.println("工资:" + gz);
// 关闭相关对象
cst.close();
con.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
|
3. 输出结果
二、调用带参数及返回值的函数
1. 建立函数
-- 输入职工号(zgh),输出工资(gz)
create or replace function getSalByNo(zgh in emp.empno%type) return emp.sal%type
is
|
gz emp.sal%type;
begin
select sal into gz from emp where empno=zgh;
return gz;
exception
when others then
return -1;
end;
|
2. JDBC调用
package com.tjxz.proc;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;
public class CallFunction {
/**
* 调用带参数及返回值的函数
* @author icer
* @web http://www.tjxz.com
*/
public static void main(String[] args) {
// 设置JDBC参数信息
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
String uid = "scott";
String pwd = "triger";
try {
// 创建接受返回值的变量(工资:gz)
float gz=0.0f;
/*
* 准备SQL语句
* 格式为: {?=call 函数名{?,?,?}}
* 括号中的问号和函数参数进行匹配,使用?=接受返回值
*/
String sql = "{?=call getSalByNo(?)}";
// 加载驱动程序
Class.forName("oracle.jdbc.driver.OracleDriver");
// 获取连接对象
Connection con = DriverManager.getConnection(url, uid, pwd);
// 获取执行对象
CallableStatement cst = con.prepareCall(sql);
|
// 执行之前要使用setXXX来替换SQL语句中的问号参数
cst.setInt(2, 7788);
// 注册输出参数类型(注意索引要和问号的位置对应)
cst.registerOutParameter(1, Types.FLOAT);
// 执行SQL命令
cst.execute();
// 提取输出参数
gz = cst.getFloat(1);
// 控制台输出
System.out.println("工资:" + gz);
// 关闭相关对象
cst.close();
con.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
|
3. 输出结果
三、调用输出参数为游标的存储过程
1. 创建存储过程
-- 输入部门编号(dno),输出此部门的所职工信息
/*说明:sys_refcursor为系统已定义的动态游标类型声明*/
create or replace procedure getEmpByDeptno(dno in emp.deptno%type,emps out sys_refcursor)
is
begin
open emps for select * from emp where deptno=dno;
end;
|
2. JDBC调用
package com.tjxz.proc;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import oracle.jdbc.internal.OracleTypes;
|
public class CallProcedureOfCursor {
/**
* 调用输出参数为游标的存储过程
* @author icer
* @web http://www.tjxz.com
*/
public static void main(String[] args) {
// 设置JDBC参数信息
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
String uid = "scott";
String pwd = "triger";
try {
/*
* 准备SQL语句 格式为: {call 存储过程名{?,?,?}}
* 括号中的问号和存储过程参数进行匹配
*/
String sql = "{call getEmpByDeptno(?,?)}";
// 加载驱动程序
Class.forName("oracle.jdbc.driver.OracleDriver");
// 获取连接对象
Connection con = DriverManager.getConnection(url, uid, pwd);
// 获取执行对象
CallableStatement cst = con.prepareCall(sql);
// 执行之前要使用setXXX来替换SQL语句中的问号参数
cst.setInt(1, 10);
// 注册输出参数类型(注意索引要和问号的位置对应)
cst.registerOutParameter(2, OracleTypes.CURSOR);
// 执行SQL命令
cst.execute();
// 提取输出参数(输出游标使用ResultSet类型接收)
ResultSet rst = (ResultSet) cst.getObject(2);
// 控制台输出
System.out.println("EMPNO\tENAME");
System.out.println("----------------------");
while (rst.next()) {
System.out.println(rst.getInt("empno") + "\t"
+ rst.getString("ename"));
}
// 关闭相关对象
rst.close();
cst.close();
con.close();
} catch (ClassNotFoundException e) {
|
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
|
3. 输出结果
EMPNO ENAME
----------------------
7782 CLARK
7839 KING
7934 MILLER
|
四、 调用返回值为游标的函数
1. 创建函数
-- 输入部门编号(dno),返回此部门的所职工信息
/*说明:sys_refcursor为系统已定义的动态游标类型声明*/
create or replace function getEmpsByDeptno(dno in emp.deptno%type) return sys_refcursor
is
emps sys_refcursor;
begin
open emps for select * from emp where deptno=dno;
return emps;
end;
|
2. JDBC调用
package com.tjxz.proc;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import oracle.jdbc.internal.OracleTypes;
public class CallFunctionOfCursor {
/**
* 调用返回值为游标的函数 *
* @author icer
* @web http://www.tjxz.com
*/
|
public static void main(String[] args) {
// 设置JDBC参数信息
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
String uid = "scott";
String pwd = "triger";
try {
/*
* 准备SQL语句,格式为: {?=call 函数名{?,?,?}}
* 括号中的问号和函数参数进行匹配,使用?=接受返回值
*/
String sql = "{?=call getEmpsByDeptno(?)}";
// 加载驱动程序
Class.forName("oracle.jdbc.driver.OracleDriver");
// 获取连接对象
Connection con = DriverManager.getConnection(url, uid, pwd);
// 获取执行对象
CallableStatement cst = con.prepareCall(sql);
// 执行之前要使用setXXX来替换SQL语句中的问号参数
cst.setInt(2, 10);
// 注册输出参数类型(注意索引要和问号的位置对应)
cst.registerOutParameter(1, OracleTypes.CURSOR);
// 执行SQL命令
cst.execute();
// 提取输出参数(输出游标使用ResultSet类型接收)
ResultSet rst = (ResultSet) cst.getObject(1);
// 控制台输出
System.out.println("EMPNO\tENAME");
System.out.println("----------------------");
while (rst.next()) {
System.out.println(rst.getInt("empno") + "\t"
+ rst.getString("ename"));
}
// 关闭相关对象
rst.close();
cst.close();
con.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
|
3. 输出结果同上
五、 调用自声明游标类型的存储过程
1. 创建存储过程
/*不使用系统已声明的动态游标类型,在程序包中自己声明动态游标类型*/
-- 创建程序包首部,声明游标和存储过程
create or replace package pk_scott
as
-- 声明动态游标类型
type dcur is ref cursor;
-- 声明存储过程
procedure getEmpByDeptno(dno in emp.deptno%type,emps out dcur);
end;
-- 创建程序包体,并实现存储过程
create or replace package body pk_scott
as
-- 实现存储过程,输入部门号返回此部门所有雇员信息
procedure getEmpByDeptno(dno in emp.deptno%type,emps out dcur)
is
begin
open emps for select * from emp where deptno=dno;
end;
end;
|
2. JDBC调用:同上
3. 显示结果:同上
补充:如果调用不带任何参数的存储过程格式为{call 存储过程名}。
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。