从Java将值作为数组传递到数据库存储过程

时间:2016-06-09 08:11:41

标签: java oracle stored-procedures jdbc oracle11g

我在数据库中有以下存储过程

CREATE OR REPLACE PROCEDURE my_proc (
   my_array         IN     my_array_type,
   my_var    IN OUT VARCHAR2)
   ....
   ....

在Java中,我有以下代码片段来调用上面的存储过程

 public void callProc(String prodCode, 
                      String prodName, 
                      String prodDesc, 
                      ) {
            callableStatement = 
            this.getOADBTransaction().getJdbcConnection().prepareCall("{call my_proc (?,?)}");
    Object[] object = 
      new Object[] { prodCode, prodName, prodDesc};
StructDescriptor structDescriptor = 
  StructDescriptor.createDescriptor("my_array_type",this.getOADBTransaction().getJdbcConnection());
STRUCT struct = 
 new STRUCT(structDescriptor, this.getOADBTransaction().getJdbcConnection(), 
object);
STRUCT[] structArray = { struct };
ArrayDescriptor arrayDescriptor = 
ArrayDescriptor.createDescriptor("my_array",this.getOADBTransaction().getJdbcConnection());

ARRAY array = 
new ARRAY(arrayDescriptor, this.getOADBTransaction().getJdbcConnection(), 
structArray);
callableStatement.setArray(1, array);
callableStatement.registerOutParameter(2, Types.VARCHAR);
callableStatement.execute();
....

上面的方法是从for循环

中的另一个类调用的
for(....){

Serializable[] param = 
{ prodCode, prodName, prodDesc};
db.callProc(param )
}

我想要实现的是在for循环中调用db.callProc而不是 我想使用ListArray或其他一些集合对象并将值传递给db.callProc方法,并在db.callProc方法中我想迭代并作为数组传递给数据库过程,以便我的存储过程可以处理数组和做处理。

2 个答案:

答案 0 :(得分:1)

首先,我们将创建一个Pojo

public class ParamHolder{

   private String param1;

   private String param2;

   private String param3;

   //getters and setters.
}

在DB端创建一个相同类型的Object

CREATE OR REPLACE TYPE PARAM_HOLDER_OBJ 
AS OBJECT ( PARAM1 VARCHAR2(200), PARAM2 VARCHAR2(200), PARAM3 VARCHAR3(200));

创建Object后,我们可以创建这些对象的表格

CREATE OR REPLACE TYPE PARAM_HOLDER_OBJ_TABLE
IS TABLE OF PARAM_HOLDER_OBJ

我们的程序可能需要输入parajm,如

custom(p_param_holder_tab IN TYPE PARAM_HOLDER_OBJ_TABLE)
例如,假设我们的proc看起来像这样,我们需要做的是从我们的java代码调用这个proc并传入一个ParamHolder数组。

Code Snippet:
//variable declaration
//ParamHolder[] paramHolders = ..getTheParamHolderArray();
        try (Connection con = createConnWithDbDetails(getDBDetails());
             CallableStatement stmnt =
             con.prepareCall("{ call custom(?) }")) {
            //Create a arrayDescriptor
            ArrayDescriptor descriptor =
                ArrayDescriptor.createDescriptor("PARAM_HOLDER_OBJ_TABLE", con);
            Array array = new ARRAY(descriptor , con, paramHolders);
            stmnt.setArray(1, array );
          }Catch(Exception e){
              e.printStackTrace();
          }

+++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++ 已编辑 - 2016年6月21日 用于添加调用方法。 下午5点IST。

你可以做的是你可以创建一个这样的方法

public void callProc(ParamHolder[] paramHolders){

try (Connection con = createConnWithDbDetails(getDBDetails());
             CallableStatement stmnt =
             con.prepareCall("{ call custom(?,?) }")) {
            //Create a arrayDescriptor
            ArrayDescriptor descriptor =
                ArrayDescriptor.createDescriptor("PARAM_HOLDER_OBJ_TABLE", con);
            Array array = new ARRAY(descriptor , con, paramHolders);
            stmnt.setArray(1, array );
            stmnt.registerOutParameter(2,OracleType.VARCHAR,"p_out_var");           //Register any output variable if your procedure returns any thing.
            stmmnt.execute();                                              //this will take the Array of ParamHolder straight to the DB for processing.
            String result = stmnt.getString(2);                                  //Will fetch yuou the result form the DB to your local String.
          }Catch(Exception e){
              e.printStackTrace();
          }
}

将使用一个ParamHolder类数组,它将直接传递给你的db proc,你将得到相应的结果。 因为当前的proc定义没有指定任何out参数,但你可以定义并注册以捕获它。

让我们假设您有一个可以使用它的调用代码

public class ProcDaoImpl{

    public void executeProc(){

         ParamHolder[] paramArray = new ParamHolder[]{                                          //create an array of four elements
                                      new ParamHolder("param1","param2","param3"),
                                      new ParamHolder("param1","param2","param3"),
                                      new ParamHolder("param1","param2","param3"),            
                                      new ParamHolder("param1","param2","param3")                                                   //Each array element represents a set of InputParams
                                   }

     //call the DB procedure now..
     SomeClass.callProc(paramArray);                                                                     // pass in the created array to it.
    }

}

希望它有所帮助。 :)

由于

答案 1 :(得分:0)

这可能有所帮助:

import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Types;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.internal.OracleTypes;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor; 

public class TestSP{
    public static void arrayDataToSP()
    {
        try{
            Class.forName("oracle.jdbc.OracleDriver");

            Connection con = DriverManager.getConnection("jdbc:oracle:thin:url ","[user]","[password]");

            String alphabets[] = {"a", "b", "c","d","e","f","g"}; 

            //use ARRAY_TABLE as ArrayDescriptor 
            ArrayDescriptor des = ArrayDescriptor.createDescriptor("SchemaName.ARRAY_TABLE", con);

            ARRAY array_to_pass = new ARRAY(des,con,alphabets);

            CallableStatement cst = con.prepareCall("call SchemaName.my_proc(?,?)");

            // Passing an alphabets array to the procedure 
            cst.setArray(1, array_to_pass);
            st.registerOutParameter(2, Types.VARCHAR);
            cst.execute();

            // Retrive output of procedure execute
            ARRAY output = ((OracleCallableStatement)cst).getARRAY(2);

             BigDecimal[] outputArray = (BigDecimal[])(output.getArray());

            for(int i=0;i<outputArray.length;i++)
                System.out.println("element" + i + ":" + outputArray[i] + "\n");

        } catch(Exception e) {
            System.out.println(e);
        }
    }

public static void main(String args[]){ arrayDataToSP(); } }