近期查找java调用存储过程的时候发现了一些不错的文章,以下链接就是其中之一:
http://windmxf.iteye.com/blog/1391508#comments
JAVA执行存储过程(和参数顺序无关,使用oracle数据库) 写道 开发中遇到的问题:?
参考这个思路自己也写了一个,以下是我写的代码:
?
class="java" name="code">package com.fwy.db.util;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ProcedureExecuter {
/**
* @param procedureName --[包名.]存储过程名
* @param paramList --参数列表 -name-value 参数名为大写
* @return procParam --将结果放入参数类表中返回
*/
public static Map<String,Object> execute(String procedureName,Map<String,Object> paramList){
Connection conn=null;
ResultSet rs =null;
CallableStatement call=null;
DatabaseMetaData dbmd=null;
List<String> paramNames = new ArrayList<String>();//param-name
List<Integer> paramTypes = new ArrayList<Integer>();//in-out type
List<Object> inParamValues = new ArrayList<Object>();//param-value
List<Integer> outParamTypes = new ArrayList<Integer>();//param-type
try {
procedureName=procedureName.toUpperCase();
conn = DBUtil.getConnection();
if(paramList==null){
call = conn.prepareCall("{ call "+procedureName+"}");
call.execute();
return null;
}
dbmd = conn.getMetaData();
String sqlCall="{ call "+procedureName+"(";
String packageName = procedureName.lastIndexOf(".") > 0 ? procedureName.substring(0, procedureName.lastIndexOf(".")): null;// 有包体时
String procedure = procedureName.substring(procedureName.lastIndexOf(".") + 1);
rs = dbmd.getProcedureColumns(packageName, "", procedure, null);
//(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern)
while (rs.next()) {//获取参数类表
Integer columnType = rs.getInt("COLUMN_TYPE");
String columnName = rs.getString("COLUMN_NAME");
Integer dataType = rs.getInt("DATA_TYPE");
sqlCall += columnName + "=>?,";
paramTypes.add(columnType);//参数类型 in out in-out
inParamValues.add(paramList.get(columnName));//in参数的值
outParamTypes.add(dataType);//out参数数据类型
paramNames.add(columnName);//参数名--大写
}
sqlCall = sqlCall.substring(0, sqlCall.lastIndexOf(",")) + ")}";//调用语句
call = conn.prepareCall(sqlCall);
for (int i=1;i<=paramTypes.size();i++) {
Integer columnType = paramTypes.get(i-1);
if (columnType == DatabaseMetaData.procedureColumnIn) {// 给in参数赋值
call.setObject(i, inParamValues.get(i-1));
} else if (columnType==DatabaseMetaData.procedureColumnOut) {// 给out参数注册数据类型
call.registerOutParameter(i, outParamTypes.get(i-1));
}else if(columnType==DatabaseMetaData.procedureColumnInOut){//给in-out参数赋值,注册数据类型
call.setObject(i, inParamValues.get(i-1));
call.registerOutParameter(i, outParamTypes.get(i-1));
}
}
call.execute();//执行存储过程
for (int i=1;i<=paramTypes.size();i++) {
Integer paramType = paramTypes.get(i-1);
if (paramType != DatabaseMetaData.procedureColumnIn) {//获取输出值放到参数列表
String name=paramNames.get(i-1);
Object value=call.getObject(i);
paramList.put(name, value);
}
}
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}finally{
DBUtil.close(rs, call, conn);
}
return paramList;
}
public static void main(String[] args) {
String procName="findEmpById";
Map<String,Object> paramList =new HashMap<String,Object>();
paramList.put("P_ID", "gz1307001");
execute(procName, paramList);
for(String key:paramList.keySet()){
System.out.println(key+":"+paramList.get(key));
}
}
}
?
PS:调用到的存储过程
create or replace procedure findEmpById
(p_id in varchar2, v_name out varchar2, v_age out number,v_deptno out varchar2,v_description out varchar2 )
AS
begin
select name,age,deptno,description into v_name,v_age,v_deptno,v_description
from emp
where id=p_id;
exception
when no_data_found then
dbms_output.put_line('not such a emploee for this id');
end findEmpById;
?
?
?
?
?
?
?