Как прочитать массив типов, возвращаемых из хранимого процесса с использованием Java?

Это продолжение вопроса, размещенного в следующем месте:Java-программа для передачи List of Bean в хранимую процедуру оракула - Передача всего списка одним выстрелом, а не добавление объектов один за другим

Я пытался улучшить хранимую процедуру, упомянутую в расположении ссылки выше, и запутался в реализации. Вместо VARCHAR2 в качестве вывода из процедуры я теперь хочу вернуть NUM_ARRAY в качестве вывода из процедуры. Не могли бы вы помочь мне в реализации логики, чтобы прочитать NUM_ARRAY в моем коде Java. Обычно выходные данные возвращаются с использованием Map out = super.execute (inParams); Как теперь я могу извлечь NUM_ARRAY для моего бина?

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;
    }
}

Обновить: После использования расширения JDBC Spring Data необходимо было изменить исходный код, чтобы он соответствовал новому ответу, который вставлен ниже, но проблема соединения все еще существует, когда вызывается метод 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

Ответы на вопрос(2)

Глобальный тип деления:

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 вы можете посмотреть наРасширение JDBC Spring Data проект, который содержит классorg.springframework.data.jdbc.support.oracle.SqlReturnArray и объявить вам параметр следующим образом:

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

Интересно, чтоMap изexecute метод содержит для массива out, потому что документация неничего не скажешь.

 sandy07 июн. 2013 г., 16:11
Фактическая проблема в реализации Spring заключается в том, что соединение недоступно при вызове метода getArray ().
 sandy08 июн. 2013 г., 10:56
Я обновил вопрос с предложенной вами реализацией, но та же проблема все еще существует. Пожалуйста, дайте мне знать, если есть какие-либо другие обходные пути.
 sandy06 июн. 2013 г., 10:49
Спасибо за то, что выложили реализацию. Я постараюсь отработать конверсию.
 sandy07 июн. 2013 г., 09:15
Out_status, который я ищу, это out_status OUT NUM_ARRAY. Я сделал некоторые изменения, и следующий код дает мне количество строк ARRAY returnValue = (ARRAY) out.get ("OUT_ARRAY»); но проблема заключается в Object [] idOutArraz = (Object []) returnValue.getArray (); returnValue.getArray () генерирует исключение nullPointerException
 Codo08 июн. 2013 г., 01:06
Посмотрите на обновленный вопрос.
Решение Вопроса

Ответил после много проб и ошибок с разными подходами, После попытки реализовать много решений 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;="" <="" code=""></objarr.length;i++){></excellistenerbean></excellistenerbean></excellistenerbean>

Ваш ответ на вопрос