无法使用StoredProcedureItemReader读取REF_CURSOR

时间:2015-10-20 21:49:05

标签: java spring oracle jdbc spring-batch

我尝试调用存储过程

create or replace PROCEDURE "PROC"(cur OUT SYS_REFCURSOR)

使用这个bean。

@Bean
    StoredProcedureItemReader<?> itemReader() {
        StoredProcedureItemReader<?> storedProcedureItemReader = new StoredProcedureItemReader<>();
        storedProcedureItemReader.setDataSource(dataSource);
        storedProcedureItemReader.setProcedureName("PROC");
        storedProcedureItemReader.setRefCursorPosition(1);
        storedProcedureItemReader.setRowMapper(new ColumnMapRowMapper());
        storedProcedureItemReader.open(new ExecutionContext());
        return storedProcedureItemReader;
    }

但是我得到了

org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:134)
    ... 54 more
Caused by: java.sql.SQLException: Invalid column index
    at oracle.jdbc.driver.OracleCallableStatement.registerOutParameterInternal(OracleCallableStatement.java:125)
    at oracle.jdbc.driver.OracleCallableStatement.registerOutParameter(OracleCallableStatement.java:304)
    at oracle.jdbc.driver.OracleCallableStatement.registerOutParameter(OracleCallableStatement.java:393)
    at oracle.jdbc.driver.OracleCallableStatementWrapper.registerOutParameter(OracleCallableStatementWrapper.java:1569)
    at org.springframework.batch.item.database.StoredProcedureItemReader.openCursor(StoredProcedureItemReader.java:202)
    ... 56 more

如何只用一个光标调用PROC并迭代结果?

4 个答案:

答案 0 :(得分:0)

我认为您需要为读取器cur添加一个参数。在打开storedProcedureItemReader

之前,请尝试添加以下行
    storedProcedureItemReader.setParameters(new SqlParameter[] { new SqlParameter("cur", OracleTypes.CURSOR) });

答案 1 :(得分:0)

多数民众赞成我在这里使用,我们必须设置光标的位置,否则spring会尝试做一个getObject(0)!

List<PersonEvent> findEventsForPerson(List<Integer> ids)

答案 2 :(得分:0)

@Bean     @profile(&#34;包&#34)     public ItemReader readerProcedureCall()抛出异常{         StoredProcedureItemReader reader = new StoredProcedureItemReader&lt;&gt;();

    LOGGER.info("***** About getting ResultSet From Procedure **** ");
    reader.setDataSource(omniflowDataSource);
    reader.setProcedureName("proce name");
    reader.setRowMapper(new CustomRowMapper());
    reader.setPreparedStatementSetter(new PreparedStatementSetter(){
        @Override
        public void setValues(PreparedStatement ps) throws SQLException{
             CallableStatement eventCallableSt=(CallableStatement)ps;
                eventCallableSt.registerOutParameter(1, OracleTypes.CURSOR);
        }
    });
    reader.setVerifyCursorPosition(false);
    reader.setParameters(new SqlParameter[] {new SqlParameter("pCusRecOut",OracleTypes.CURSOR)});
    reader.setRefCursorPosition(NumberUtils.INTEGER_ONE);
    reader.afterPropertiesSet();

    return reader;
}

答案 3 :(得分:0)

也许下面的代码可以帮助您创建一个输出参数为SYS_REFCURSOR的过程:

StoredProcedureItemReader<?> reader = new StoredProcedureItemReader<>();
reader.setDataSource(dataSource_instance);
reader.setProcedureName("procedurename");
reader.setRowMapper(new CustomRowMapper());
reader.setPreparedStatementSetter(new PreparedStatementSetter(){
    @Override
    public void setValues(PreparedStatement ps) throws SQLException{
         CallableStatement eventCallableSt=(CallableStatement)ps;
            eventCallableSt.registerOutParameter(1, OracleTypes.CURSOR);
    }
});
reader.setVerifyCursorPosition(false);
reader.setParameters(new SqlParameter[] {new SqlParameter(<name>,OracleTypes.CURSOR)});
reader.setRefCursorPosition(1);
reader.open(new ExecutionContext());
try {
    reader.afterPropertiesSet();
} catch (Exception e) {
    e.printStackTrace();
}
return reader;