如何使用java读取从存储过程返回的类型的ARRAY?

这是在以下位置发布的问题的延续: 将Bean列表传递给oracle存储过程的Java程序 – 一次性传递整个列表而不是一个接一个地追加对象

我一直在尝试增强上面链接位置中提到的存储过程,并在实现中感到困惑。 而不是VARCHAR2作为过程的输出,我现在想要返回NUM_ARRAY作为过程的输出。 你能帮我实现逻辑来读取我的java代码中的NUM_ARRAY吗? 通常使用Map out = super.execute(inParams)返回输出; 我现在如何将NUM_ARRAY提取到我的bean?

The source code implementation is as follows. import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; import oracle.jdbc.OracleTypes; import oracle.sql.ARRAY; import oracle.sql.ArrayDescriptor; import org.apache.log4j.Logger; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.core.SqlTypeValue; import org.springframework.jdbc.object.StoredProcedure; public class RevPrdBrkDwnSP extends StoredProcedure{ private final Logger log = Logger.getLogger(this.getClass().getName()); public RevPrdBrkDwnSP(DataSource dataSource, String storeProcName) { // Run the Parent super(dataSource, storeProcName); // Declare the Parameter Details declareParameter(new SqlParameter("IN_ARRAY", OracleTypes.ARRAY, "****.PROD_PRCT_BRKDWN_TYPE_ARRAY")); declareParameter(new SqlOutParameter("OUT_ARRAY", OracleTypes.ARRAY, "****.PROD_PRCT_BRKDWN_TYPE_ARRAY")); // Compile the SP compile(); } public boolean execute(final RevAppViewBean appViewBean$Session, final DataSource dataSource) throws Exception { boolean returnVal = false; Map inParams = new HashMap(); log.info("Setting up the Store Procedure Params"); inParams.put("IN_ARRAY", new SqlTypeValue() { public void setTypeValue(PreparedStatement cs, int index, int sqlType, String typeName) throws SQLException { Connection con = cs.getConnection(); ArrayDescriptor des = ArrayDescriptor.createDescriptor("****.PROD_PRCT_BRKDWN_TYPE_ARRAY", con); ARRAY a = new ARRAY(des, con, appViewBean$Session.getExcelRecLst().toArray()); cs.setObject(1, (Object)a); } }); inParams.put("OUT_ARRAY", identifier); // what should the identifier be ????????? if (log.isDebugEnabled()) { log.debug("Executing the **** Store Procedure "); } Map out = super.execute(inParams); // how to get the same array as value ?????? log.info("output size is --------------------->>>>>>>>>> "+out.size()); for(Object o : out.keySet()){ log.info((String)out.get(o)); returnVal = Boolean.parseBoolean((String)out.get(o)); } if (log.isDebugEnabled()) { log.info("Output from **** Store Procedure :" + out); } return returnVal; } } 

更新:在使用Spring Data JDBC Extension之后,必须更改源代码以适应下面粘贴的新响应,但是当调用bean.getAttributes()方法时,连接问题仍然存在。 在连接关闭之前,需要找到一种不关闭连接或访问值的方法。

 Map out = super.execute(inParams); log.info("output size is --------------------->>>>>>>>>> "+out.size()); //prints the actual value Object[] idOutArraz = (Object[])out.get("OUT_ARRAY"); log.info("size of returnValue is "+idOutArraz.length); //prints the right number of results for(int i= 0; i<idOutArraz.length;i++){ Object[] attrs = null; Struct bean = (Struct) idOutArraz[i]; attrs = bean.getAttributes(); if (attrs != null) { System.out.println(Arrays.asList(attrs)); } } 

经过多次试验和不同方法的错误后回答 。 在尝试实现很多解决方案后,Callable语句对我有用。 看起来像是一种解决方法,但欢迎任何解决实际实施的解决方案。

请在下面找到实施的工作副本。

 import java.math.BigDecimal; import java.sql.Array; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.sql.DataSource; import oracle.jdbc.OracleTypes; import oracle.sql.ARRAY; import oracle.sql.ArrayDescriptor; import oracle.sql.STRUCT; import org.apache.log4j.Logger; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.SqlParameter; import org.springframework.jdbc.object.StoredProcedure; import com.****.****.****.ExcelListenerBean; import com.****.****.****.RevAppViewBean; public class RevPrdBrkDwnSP extends StoredProcedure{ private final Logger log = Logger.getLogger(this.getClass().getName()); private Connection con = null; private DataSource ds = null; public RevPrdBrkDwnSP(DataSource dataSource, String storeProcName) throws SQLException { // Run the Parent super(dataSource, storeProcName); con = dataSource.getConnection(); ds = dataSource; if (log.isInfoEnabled()) { log.info("Stored Procedure Name : "+ storeProcName); } // Declare the Parameter Details declareParameter(new SqlParameter("IN_ARRAY", OracleTypes.ARRAY, "****.PROD_PRCT_BRKDWN_TYPE_ARRAY")); declareParameter(new SqlOutParameter("OUT_ARRAY", OracleTypes.ARRAY, "****.PROD_PRCT_BRKDWN_TYPE_ARRAY")); // Compile the SP compile(); } public List execute(final RevAppViewBean appViewBean$Session, DataSource dataSource) throws Exception { dataSource = ds; List beans = new ArrayList(); log.info("Setting up the Store Procedure Params"); String getDBUSERByUserIdSql = "{call ****.PRCS_PROD_PRCT_BRKDWN_ENTRIES(?,?)}"; CallableStatement cs = con.prepareCall(getDBUSERByUserIdSql); ArrayDescriptor des = ArrayDescriptor.createDescriptor("PBAREV.PROD_PRCT_BRKDWN_TYPE_ARRAY", con); ARRAY a = new ARRAY(des, con, appViewBean$Session.getExcelRecLst().toArray()); cs.setObject(1, (Object)a); cs.registerOutParameter(2, OracleTypes.ARRAY, "****.PROD_PRCT_BRKDWN_TYPE_ARRAY"); if (log.isDebugEnabled()) { log.debug("Executing the PBAREV Store Procedure "); } cs.execute(); log.info("Executed ****.PRCS_PROD_PRCT_BRKDWN_ENTRIES... Processing values to beans"); Array arr = cs.getArray(2); Object[] objArr = (Object[]) arr.getArray(); for(int i=0; i 

在Oracle方面,您的代码可能如下所示:

全球类型decration:

 CREATE OR REPLACE TYPE NUM_ARRAY AS TABLE OF NUMBER; 

存储过程:

 CREATE OR REPLACE PROCEDURE PROD_PRCT_BRKDWN_TYPE_ARRAY ( in_array IN NUM_ARRAY, out_status OUT VARCHAR2) IS ... 

简单的JDBC代码(包含一些Oracle特定部分):

 Connection con = ...; CallableStatementcs = con.prepareCall(" ... "); ArrayDescriptor des = ArrayDescriptor.createDescriptor("PBAREV.PROD_PRCT_BRKDWN_TYPE_ARRAY", con); Integer[] idArray = new Integer[50000]; // fill the array of integers here for (int i = 0; i < idArray.length; i++) idArray[i] = ....; ARRAY a = new ARRAY(des, con, idArray); cs.setObject(1, (Object)a); cs.registerOutParameter(2, OracleTypes.ARRAY, "PBAREV.PROD_PRCT_BRKDWN_TYPE_ARRAY"); cs.execute(); ARRAY outArray = (ARRAY)cs.getArray(2); Integer[] idOutArraz = (Integer[])outArray.getArray(); 

我还没有测试过代码。 但它应该给你一个想法。

更新:

对于转换到Spring Framework,您可能希望查看包含类org.springframework.data.jdbc.support.oracle.SqlReturnArraySpring Data JDBC Extension项目,并声明您的参数如下:

 declareParameter(new SqlOutParameter("OUT_ARRAY", Types.ARRAY, "PBAREV.PROD_PRCT_BRKDWN_TYPE_ARRAY", new SqlReturnArray())); 

我想知道execute方法的Map包含out数组的原因是什么,因为文档没有说什么。