`
kongfwy
  • 浏览: 1673 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

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;

 

 

 

 

 

 

 

分享到:
评论
2 楼 luzuoqi 2015-03-13  
Ting_qing 写道
我在使用的时候,mysql数据库会提示错误信息,验证了一下,不能在mysql数据库下使用=>


mysql不支持命名参数,只支持位置参数。
可以通过 dbmd.supportsNamedParameters();来查询,返回false说明不支持命名参数。
1 楼 Ting_qing 2014-06-18  
我在使用的时候,mysql数据库会提示错误信息,验证了一下,不能在mysql数据库下使用=>

相关推荐

    JAVA调用存储过程

    ### JAVA调用存储过程知识点详解 #### 一、无结果集返回的存储过程调用 在Java中调用不返回结果集的存储过程时,主要步骤包括建立连接、准备调用语句、设置输入参数、执行存储过程以及处理可能产生的警告信息。 1...

    java 调用存储过程

    值得注意的是,上述代码中的文件名列表(如Project1.cfg、Unit1.dcu等)与Java调用存储过程无关,它们看起来像是Delphi或FreePascal项目的文件,这些文件通常用于描述项目配置、单元信息、表单布局等,而不是与Java...

    java调用存储过程实例

    ### Java调用存储过程实例:详解 #### 存储过程简介 存储过程是一种在数据库中编写的SQL程序,可以接受输入参数,执行一系列操作,并返回结果或输出参数。它们可以提高应用程序的性能、安全性和复用性。在Oracle...

    java调用存储过程(含out参数)

    总之,调用存储过程是Java开发中处理数据库操作的重要环节。理解如何设置`IN`和`OUT`参数,并正确地执行和获取结果,将有助于提高代码的效率和可维护性。希望这个详细讲解对你有所帮助,如果你在实践中遇到任何问题...

    java调用存储过程同时返回值和多个table

    java调用存储过程,支持获取return值,output返回值,以及查询的表数据,表数据允许有多个查询结果集

    java调用存储过程返回数组

    总结来说,Java调用存储过程并处理返回数组,需要理解存储过程的定义,正确使用`CallableStatement`或其子类如`OracleCallableStatement`,以及处理Oracle特定数据类型的方法。通过这些技巧,我们可以有效地在Java...

    Java调用存储过程

    Java调用存储过程是数据库操作中的常见任务,特别是在复杂业务逻辑和数据处理中。存储过程是一种预编译的SQL语句集合,可以在数据库服务器端执行,提高了效率并减少了网络通信量。本文将详细讲解Java如何调用存储...

    Java调用存储过程--传入集合参数

    ### Java调用存储过程——传入集合参数:深入解析与实践 #### 核心知识点概览 在Java应用中,调用数据库存储过程时,往往需要处理复杂的参数传递,特别是当参数为集合类型时,这一过程变得更加具有挑战性。本文将...

    java调用存储过程小结.pdf

    Java 调用存储过程小结 Java 调用存储过程是指在 Java 程序中调用数据库中的存储过程,以便实现复杂的业务逻辑和数据处理。存储过程是指保存在数据库并在数据库端执行的程序,可以使用特殊的语法在 Java 类中调用...

    Java调用存储过程的2种方法

    ### Java调用存储过程的两种方法 在Java中调用数据库中的存储过程是常见的操作之一,这不仅可以提高程序性能和代码可维护性,还可以更好地利用数据库的功能。根据提供的标题、描述以及部分内容,本文将详细介绍Java...

Global site tag (gtag.js) - Google Analytics