Exec 存储过程无法与 JdbcCursorItemReader 一起使用

问题描述 投票:0回答:1

我需要在 Spring-Batch 中使用 JdbcCursorItemReader 从 select 和 exec Sybase 查询中读取数据。虽然 SELECT 查询运行完美,但 Exec 查询遇到以下错误:

由:org.springframework.jdbc.UncategorizedSQLException引起: 执行查询; SQL 的未分类 SQLException [exec proc_1]; SQL状态 [ZZZZZ];错误代码[7773];执行游标'jconnect_implicit_1'是 在包含非 SELECT 或带有 SELECT 的过程中声明 计算子句。为了使这个游标的声明合法 应该有一个不带 COMPUTE 子句的 SELECT 语句。

;嵌套异常是 com.sybase.jdbc4.jdbc.SybSQLException:执行 游标“jconnect_implicit_1”在包含以下内容的过程中声明 非 SELECT 或带有 COMPUTE 子句的 SELECT。对于声明 这个游标是合法的,它应该有一个 SELECT 语句 没有 COMPUTE 子句。 ...省略了43个常见框架

原因:com.sybase.jdbc4.jdbc.SybSQLException:执行游标 '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 [{call ftsps_report(?, ?)}]; SQL状态[ZZZZZ];错误代码 [7773];执行游标“jconnect_implicit_1”在 a 上声明 包含非 SELECT 或带有 COMPUTE 的 SELECT 的过程 条款。为了使该游标的声明合法,它应该具有 没有 COMPUTE 子句的单个 SELECT 语句。

;嵌套异常是 com.sybase.jdbc4.jdbc.SybSQLException:执行 游标“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.SybSQLException:执行游标 '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 setValues 我定义如下:

ps.setDate(1, Date.ValueOf(paramList.get(0));
ps.setDate(2, Date.ValueOf(paramList.get(1));

我也尝试了一些其他存储过程并遇到了类似的问题。 是不是定义有误。我只想最好通过索引定义参数。有没有直接的方法可以做到这一点?是否期望存储过程中的参数专门命名为 date1/date2 并因此失败?

java spring jdbc spring-batch sybase
1个回答
1
投票

对于存储过程,您需要使用

StoredProcedureItemReader
而不是
JdbcCursorItemReader
,例如:

@Bean
public StoredProcedureItemReader storedProcedureItemReader() {
    StoredProcedureItemReader reader = new StoredProcedureItemReader();
    reader.setProcedureName("yourProcedureName");
    // set other properties
    return reader;
}

请参阅参考文档了解更多详细信息。

© www.soinside.com 2019 - 2024. All rights reserved.