ORA-01406:获取的列值被截断 - 在Oracle中读取LONG RAW时出错

时间:2014-06-09 19:47:09

标签: oracle spring-batch long-integer truncated

我配置了一个Spring Batch作业,用于从Oracle数据库中读取数据。我遇到ORA-01406错误消息,指出已获取的列值被截断。以下是我到目前为止所做的一些额外细节和一些故障排除

  • 正在从配置为DBLINK(外部数据库)
  • 的数据库中检索数据
  • 要检索的列定义为LONG RAW dataype
  • 用于检索数据的查询在SqlPagingQueryProviderFactoryBean中使用
  • 我尝试让Mapper尝试将其映射为String,BinaryStream并始终看到此错误消息

有趣的是,当我在JdbcTemplate上使用query()并使用如下的简单查询时,我在检索值时没有问题 在某些条件下从某些选项中选择MY_COLUMN;

有人知道Spring Batch在检索LONG RAW列时是否有任何问题?或者如何解决这个问题?

以下是堆栈跟踪

DEBUG JdbcStepExecutionDao - Truncating long message before update of StepExecution, original message is: org.springframework.batch.core.step.skip.NonSkippableReadException: Non-skippable exception during read
at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:104)
at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:114)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:108)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:69)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:395)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:267)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:253)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:141)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:151)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:130)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:301)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:134)
at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.dao.DataIntegrityViolationException: StatementCallback; SQL [SELECT * FROM (SELECT MY_COLUMN FROM SOME_TABLE WHERE SOME CONDITION) ORDER BY SOME_COLUMN ASC) WHERE ROWNUM <= 100]; ORA-01406: fetched column value was truncated

嵌套异常是java.sql.SQLDataException:ORA-01406:获取的列值被截断

at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:413)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:468)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:478)
at org.springframework.batch.item.database.JdbcPagingItemReader.doReadPage(JdbcPagingItemReader.java:210)
at org.springframework.batch.item.database.AbstractPagingItemReader.doRead(AbstractPagingItemReader.java:108)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:83)
at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:91)
at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:87)
... 24 more
Caused by: java.sql.SQLDataException: ORA-01406: fetched column value was truncated

at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:440)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:837)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:445)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:191)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:523)
at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:193)
at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:999)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1185)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1275)
at oracle.jdbc.driver.OracleStatement.executeQuery(OracleStatement.java:1477)
at oracle.jdbc.driver.OracleStatementWrapper.executeQuery(OracleStatementWrapper.java:392)
at org.springframework.jdbc.core.JdbcTemplate$1QueryStatementCallback.doInStatement(JdbcTemplate.java:452)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:402)
... 31 more

1 个答案:

答案 0 :(得分:1)

经过大量的研究和试验,我最终将LONG RAW数据类型检索为byte []。以下是我为检索数据而编写的相关代码

    public byte[] getALongRawText(final SomeObject someObject) {

    byte[] result = myJdbcTemplate.query(getALongRawTextSql, new PreparedStatementSetter() {
                @Override
                public void setValues(PreparedStatement preparedStatement) throws SQLException {
                    preparedStatement.setLong(1, someObject.getProperty1());
                    preparedStatement.setLong(2, someObject.getProperty2());
                }
            }, new ResultSetExtractor<byte[]>() {
                @Override
                public byte[] extractData(ResultSet resultSet) throws SQLException, DataAccessException {
                    if(resultSet.next()) {
                        return resultSet.getBytes(1);
                    }
                    return null;
                }
            });      

    return result;
}