我需要在Spring Batch中使用JdbcCursorItemReader从select和exec Sybase查询中读取数据。虽然SELECT查询运行良好,但Exec查询运行时出现以下错误:
由:org.springframework.jdbc.UncategorizedSQLException引起:正在执行查询;SQL的未分类SQLException[execproc_1];SQL状态[ZZZZZ];错误代码[773];执行游标"jconnect_implicit_1"为在包含非SELECT或SELECT的过程中声明COMPUTE子句。为了使该游标的声明合法应该有一个不带COMPUTE子句的SELECT语句。
嵌套异常为com.sybase.jdbc4.jdbc.SybQLException:执行游标"jconnect_implicit_1"是在包含非SELECT或带有COMPUTE子句的SELECT。用于声明该游标要合法,就应该有一个SELECT语句没有COMPUTE子句。…省略了43个普通帧
引起原因:com.sybase.jdbc4.jdbc.SybQLException:执行游标"jconnect_implicit_1"是在包含非SELECT或带有COMPUTE子句的SELECT。用于声明该游标要合法,就应该有一个SELECT语句没有COMPUTE子句。
省略了45个普通帧
JdbcCursorItemReader的代码如下:
JdbcCursorItemReader itemReader = new JdbcCursorItemReader();
ColumnMapRowMapper rowMapper = new ColumnMapRowMapper();
itemReader.setDataSource(getDataSource());
itemReader.setRowMapper(rowMapper);
itemReader.setFetchSize(batchSize);
itemReader.setSql(dataSql); //datasql is passed Sybase query
即使在按照建议使用StoredProcedureItemReader之后,得到以下错误:
由:org.springframework.jdbc.UncategorizedSQLException引起:执行存储过程;SQL的未分类SQLException〔{callftsps_report(?,?(}];SQL状态[ZZZZZ];错误代码[773];在包含非SELECT或带COMPUTE的SELECT的过程条款为了使该游标的声明合法,它应该没有COMPUTE子句的单个SELECT语句。
嵌套异常为com.sybase.jdbc4.jdbc.SybQLException:执行游标"jconnect_implicit_1"是在包含非SELECT或带有COMPUTE子句的SELECT。用于声明该游标要合法,就应该有一个SELECT语句没有COMPUTE子句。
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:90) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:82) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:82) at org.springframework.batch.item.database.StoredProcedureItemReader.openCursor(StoredProcedureItemReader.java:226) at org.springframework.batch.item.database.AbstractCursorItemReader.doOpen(AbstractCursorItemReader.java:406) at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.open(AbstractItemCountingItemStreamItemReader.java:144) ... 43 common frames omitted
引起原因:com.sybase.jdbc4.jdbc.SybQLException:执行游标"jconnect_implicit_1"是在包含非SELECT或带有COMPUTE子句的SELECT。用于声明该游标要合法,就应该有一个SELECT语句没有COMPUTE子句。
at com.sybase.jdbc4.tds.Tds.processEed(Tds.java:4112) at com.sybase.jdbc4.tds.Tds.nextResult(Tds.java:3229) at com.sybase.jdbc4.tds.Tds.getResultSetResult(Tds.java:3974) at com.sybase.jdbc4.tds.TdsCursor.open(TdsCursor.java:333) at com.sybase.jdbc4.jdbc.SybCallableStatement.sendRpc(SybCallableStatement.java:2032) at com.sybase.jdbc4.jdbc.SybCallableStatement.execute(SybCallableStatement.java:241) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114) at com.sun.proxy.$Proxy83.execute(Unknown Source) at org.springframework.batch.item.database.StoredProcedureItemReader.openCursor(StoredProcedureItemReader.java:210)
已定义StoredProcedureItemReader如下:
StoredProcedureItemReader itemReader = new StoredProcedureItemReader();
ColumnMapRowMapper rowMapper = new ColumnMapRowMapper();
itemReader.setDataSource(getDataSource());
itemReader.setRowMapper(rowMapper);
itemReader.setFetchSize(batchSize);
itemReader.setProcedureName(dataSql);
SqlParameter[] parameter = {new SqlParameter("date1", Types.DATE),new SqlParameter("date2", Types.DATE)};
itemReader.setParameters(parameter);
itemReader.setPreparedStatementSetter(psSetter);
其中psSetter设置值我定义如下:
ps.setDate(1, Date.ValueOf(paramList.get(0));
ps.setDate(2, Date.ValueOf(paramList.get(1));
我也尝试了其他一些存储过程,但也遇到了类似的问题。这是定义错误吗。我只想最好通过索引来定义参数。有什么简单的方法吗?它是否将storedpoc中的参数命名为date1/date2,并因此而失败?
对于存储过程,您需要使用StoredProcedureItemReader
而不是JdbcCursorItemReader
,类似于:
@Bean
public StoredProcedureItemReader storedProcedureItemReader() {
StoredProcedureItemReader reader = new StoredProcedureItemReader();
reader.setProcedureName("yourProcedureName");
// set other properties
return reader;
}
有关更多详细信息,请参阅参考文档。