java调用存储过程

近期查找java调用存储过程的时候发现了一些不错的文章,以下链接就是其中之一:

http://windmxf.iteye.com/blog/1391508#comments

JAVA执行存储过程(和参数顺序无关,使用oracle数据库) 写道
开发中遇到的问题:
1.本来CallableStatement 是提供setString(ParameterName,value)这样的方法的,
--但是看了ibm网站上的资料发现不支持oracle,是infomix的特性,所以无法用,只能麻烦点用index的方式注册输出参数
2.另外所有的参数包括存储过程名称、包名都要大写,否则不认得
3.使用getProcedureColumns(pckgName,"" , proc, null);时注意
--第一个参数catalog对应oracle的包名,
--第二个参数应该是schema名称,我一开始以为是用户名,但不对,只能写空,但不要写null,
--否则会得到这个实例里面所有这个存储过程的参数,当实例存在多个用户的使用会有问题。

 

参考这个思路自己也写了一个,以下是我写的代码:

 

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;

 

 

 

 

 

 

 

你可能感兴趣的:(java,oracle,procedure,CallableStament)