【问题标题】:Unable to read REF_CURSOR with StoredProcedureItemReader无法使用 StoredProcedureItemReader 读取 REF_CURSOR
【发布时间】:2015-10-20 21:49:04
【问题描述】:

我尝试调用存储过程

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 并迭代结果?

【问题讨论】:

    标签: java spring oracle jdbc spring-batch


    【解决方案1】:

    我认为你需要在阅读器中添加一个参数,用于输出参数cur。在打开 storedProcedureItemReader 之前尝试添加以下行:

        storedProcedureItemReader.setParameters(new SqlParameter[] { new SqlParameter("cur", OracleTypes.CURSOR) });
    

    【讨论】:

      【解决方案2】:

      这就是我在这里使用的方式,我们必须设置光标的位置,否则 spring 将尝试执行 getObject(0)!

      @Bean
          public ItemReader<FailuredProcess> getFailuredProcessReader() throws BatchOMSException {
              StoredProcedureItemReader<FailuredProcess> reader;
      
              try {
                  reader = new StoredProcedureItemReader<FailuredProcess>();
      
                  reader.setDataSource(dataSource);
                  reader.setProcedureName(queryHelper.getQuery("query.oms.listFailuredProcessJobs"));
                  reader.setRowMapper(new AlarmRowMapper());
                  reader.setPreparedStatementSetter(new PreparedStatementSetterAdapter());
                  reader.setVerifyCursorPosition(false);
                  reader.setParameters(new SqlParameter[] { new SqlParameter("cur", OracleTypes.CURSOR) });
                  reader.setRefCursorPosition(NumberUtils.INTEGER_ONE);
                  reader.afterPropertiesSet();
      
                  return reader;
              } catch (Exception e) {
                  LOGGER.error(e.getMessage(), e);
                  throw new BatchOMSException(e);
              }
      

      【讨论】:

        【解决方案3】:

        @豆 @Profile("包") 公共 ItemReader readerProcedureCall() 抛出异常 { StoredProcedureItemReader reader = new StoredProcedureItemReader();

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

        【讨论】:

        • 请更新您的答案以提供更多详细信息,仅代码的答案没有那么有用 + 花一些时间格式化
        【解决方案4】:

        也许下面的代码可以帮助您创建一个输出参数为 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;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-21
          • 2020-10-07
          • 2022-08-02
          • 2016-02-22
          • 2011-12-25
          • 2013-12-15
          相关资源
          最近更新 更多