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

标签 java spring oracle stored-procedures bulk-load

这是在以下位置发布的问题的延续: Java program to pass List of Bean to a oracle stored procedure - Pass entire list at one shot rather than appending objects one after the other

我一直在尝试增强上述链接位置中提到的存储过程,但在实现过程中感到困惑。而不是 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<String, Object> inParams = new HashMap<String, Object>();
        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<ExcelListenerBean> execute(final RevAppViewBean appViewBean$Session, DataSource dataSource) throws Exception {
        dataSource = ds;
        List<ExcelListenerBean> beans = new ArrayList<ExcelListenerBean>();

        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<objArr.length;i++){
            STRUCT st = (STRUCT)objArr[i];
            ExcelListenerBean bean = new ExcelListenerBean();
            Object[] obj = st.getAttributes();
            bean.setPrntGdwIdN(((BigDecimal)obj[1]).longValue());
            bean.setChldGdwIdN(((BigDecimal)obj[2]).longValue());
            bean.setChldAsetPrcntN(Double.valueOf(String.valueOf(obj[4])));
            bean.setStatus(String.valueOf(obj[8]));
            bean.setStatusMessage(String.valueOf(obj[9]));
            beans.add(bean);
        }

        if (log.isDebugEnabled()) {
            log.info("Finised processing SP output values to ExcelListenerBeans");
        }

        return beans;
    }
}

关于java - 如何使用 java 读取从存储过程返回的类型数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16937775/

相关文章:

java - 如何转换unix日期,如20140222T08 :27:11 to Date() in java

java - 命令行 Java 项目助手/生成器

sql - ORA-01843 : not a valid month error when using to_date function

sql - "<>"在 Oracle 中是什么意思

java - Spark 中 Oracle 表之间的联接

java - 如何将我自己的插件添加到 Cooja

java - Eclipse Windowbuilder动态更改面板内容

java - 无法找到 Spring NamespaceHandler util

java - Guava LoadingCache中的load()方法是什么?

spring - HTTP session 和 Web session 有什么区别?