近期查找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,
--否则会得到这个实例里面所有这个存储过程的参数,当实例存在多个用户的使用会有问题。
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调用存储过程知识点详解 #### 一、无结果集返回的存储过程调用 在Java中调用不返回结果集的存储过程时,主要步骤包括建立连接、准备调用语句、设置输入参数、执行存储过程以及处理可能产生的警告信息。 1...
值得注意的是,上述代码中的文件名列表(如Project1.cfg、Unit1.dcu等)与Java调用存储过程无关,它们看起来像是Delphi或FreePascal项目的文件,这些文件通常用于描述项目配置、单元信息、表单布局等,而不是与Java...
### Java调用存储过程实例:详解 #### 存储过程简介 存储过程是一种在数据库中编写的SQL程序,可以接受输入参数,执行一系列操作,并返回结果或输出参数。它们可以提高应用程序的性能、安全性和复用性。在Oracle...
总之,调用存储过程是Java开发中处理数据库操作的重要环节。理解如何设置`IN`和`OUT`参数,并正确地执行和获取结果,将有助于提高代码的效率和可维护性。希望这个详细讲解对你有所帮助,如果你在实践中遇到任何问题...
java调用存储过程,支持获取return值,output返回值,以及查询的表数据,表数据允许有多个查询结果集
总结来说,Java调用存储过程并处理返回数组,需要理解存储过程的定义,正确使用`CallableStatement`或其子类如`OracleCallableStatement`,以及处理Oracle特定数据类型的方法。通过这些技巧,我们可以有效地在Java...
Java调用存储过程是数据库操作中的常见任务,特别是在复杂业务逻辑和数据处理中。存储过程是一种预编译的SQL语句集合,可以在数据库服务器端执行,提高了效率并减少了网络通信量。本文将详细讲解Java如何调用存储...
### Java调用存储过程——传入集合参数:深入解析与实践 #### 核心知识点概览 在Java应用中,调用数据库存储过程时,往往需要处理复杂的参数传递,特别是当参数为集合类型时,这一过程变得更加具有挑战性。本文将...
Java 调用存储过程小结 Java 调用存储过程是指在 Java 程序中调用数据库中的存储过程,以便实现复杂的业务逻辑和数据处理。存储过程是指保存在数据库并在数据库端执行的程序,可以使用特殊的语法在 Java 类中调用...
### Java调用存储过程的两种方法 在Java中调用数据库中的存储过程是常见的操作之一,这不仅可以提高程序性能和代码可维护性,还可以更好地利用数据库的功能。根据提供的标题、描述以及部分内容,本文将详细介绍Java...