Spring Сохраненная процедура - результаты, возвращаемые из процедуры, всегда пусты

Я использую классы Spring JdbcTemplate и StoredProcedure. У меня возникла проблема с тем, чтобы класс хранимой процедуры работал у меня.

У меня есть хранимая процедура в базе данных оракула. Его подпись

CREATE OR REPLACE PROCEDURE PRC_GET_USERS_BY_SECTION
(user_cursor OUT Pkg_Types.cursor_type
 , section_option_in IN Varchar2
 , section_in IN Varchar2) AS ....

где

TYPE cursor_type IS REF CURSOR;

Я создал следующий класс хранимой процедуры для получения информации из процедуры оракула

    private class MyStoredProcedure extends StoredProcedure 
{
    public MyStoredProcedure(JdbcTemplate argJdbcTemplate) 
    {
        super(argJdbcTemplate, "PRC_GET_USERS_BY_SECTION");
        declareParameter(new SqlOutParameter("output", OracleTypes.CURSOR));
        declareParameter(new SqlParameter("input1", Types.VARCHAR));
        declareParameter(new SqlParameter("input2", Types.VARCHAR));
        compile();          
    }


    public Map<String, Object> execute() {

        Map<String, Object> inParams = new HashMap<String, Object>();
        inParams.put("input1", "BG");
        inParams.put("input2", "FE");
        Map output = execute(inParams);
        return output;
    }
}

Я вызываю это в методе в одном из моих классов DAO

    public List<String> getUserListFromProcedure() throws BatchManagerException
{
    MyStoredProcedure sp = new MyStoredProcedure( this.jdbcTemplate );
    Map<String, Object> result = new HashMap<String, Object>();
    try
    {
        result = sp.execute();
    }

    catch( DataAccessException dae) 
    {

    }
    System.out.println(result.size());
    return null;
}

Однако размер карты всегда равен 0, поэтому ничего не возвращается. Я знаю, что в базе данных есть строки, соответствующие моим входным критериям. Кроме того, у меня была работа с кодом, которая использовала java.sql.CallableStatement для взаимодействия с хранимой процедурой оракула - так что процесс хорош. Неправильно ли смешивать OraceleTypes.CURSOR с Spring хранимой процедурой? Что еще я могу использовать? Я также пробовал SqlReturnResultSet, и это тоже не сработало.

Ответы

Ответ 1

Проблема здесь в том, что Oracle способ выполнения хранимых процедур не соответствует JDBC. Oracle SPs возвращают данные результатов через параметры OUT или возвращают значения, которые являются курсорами, и их нужно обрабатывать специально. Это означает, что вы не можете использовать какой-либо материал Spring JDBC, который предполагает соответствие JDBC, вы должны сделать это самостоятельно.

На практике это означает, что вы должны использовать JdbcTemplate и CallableStatementCallback, что означает гораздо более ручную кодировку JDBC, чем вам хотелось бы, но мне еще предстоит найти способ избежать этого.

В небольшом аспекте я скорее подозреваю, что спецификация JDBC была написана так, чтобы она соответствовала способу выполнения Sybase (и, благодаря ассоциации, SQL Server), потому что способ хранения хранимых процедур в JDBC - замечательно хороший подходит для этих систем (и плохо подходит для Oracle).

Ответ 2

Проблема проста, если вы не передаете RowMapper при объявлении outparam, который является CURSOR. Spring будет возвращать {} I. пустой символ.

 declareParameter(new SqlOutParameter("output", OracleTypes.CURSOR)); - returns empty {}
 declareParameter(new SqlOutParameter("output", OracleTypes.CURSOR, new ApplicationMapper()); - returns result

Где ApplicationMapper - это мой настраиваемый mapper, который реализует RowMapper.