【问题标题】:ORA-01406: fetched column value was truncated - error reading a LONG RAW in OracleORA-01406: 提取的列值被截断 - 在 Oracle 中读取 LONG RAW 时出错
【发布时间】:2014-06-09 19:47:09
【问题描述】:

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

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

有趣的是,当我在 JdbcTemplate 上使用 query() 并使用如下所示的简单查询时,检索值没有问题 SELECT MY_COLUMN FROM SOME_TABLE WHERE Some CONDITION;

有人知道 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: fetched column value was truncated

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

【问题讨论】:

  • 代码片段请......弹簧批处理配置会有所帮助

标签: oracle spring-batch long-integer truncated


【解决方案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;
}

【讨论】:

  • 您有没有确定确切的原因是什么?我们有一个非常相似的例外,虽然来自 DB2,但在 SELECT 上。只有当我们尝试将 20 个字符的列与传入的大于 20 个字符的参数进行比较时,它才会失败。 DB2 会通过传入参数的截断错误似乎很奇怪。
  • 不,我没有。对我来说,这似乎是 Spring Batch 的问题。我不确定它是否在内部尝试将 LONG RAW 类型转换为字符串。 LONG RAW 是过时的数据类型,无论如何都不应该使用它,但由于遗留系统,我们不得不使用它。
  • 在我们的例子中,似乎正在发生的事情是 DB2 驱动程序在通过 JDBC 驱动程序执行 Prepared Statement 时设置了定义的参数。对于 varchar,它似乎是使用列上的元数据来确定所述定义参数的长度。在我们的例子中,我们试图将一个 21 个字符长度的字符串与一个 20 个字符长度定义的参数进行比较。这会导致截断错误。当我们手动运行它时,我们并没有将其作为准备好的语句执行,这就是它在控制台中工作但在代码中不起作用的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
  • 2023-03-06
  • 2021-11-30
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多