当序列号存储在Java变量中时,Oracle Sequence Generator返回一个负值

问题描述

我有一个名为Record ID的数据库列。这是一个主键,其值是使用具有以下属性的oracle序列生成的 序列细节 最低价值:1 最大值:9999999999999999999999999999 增加:10

在我的Java应用程序中,我在应用一些业务逻辑后将记录插入表中。字段Record ID的值是从序列生成获取

在插入记录之前,我先在Java代码中使用以下代码(从序列生成获取)在Java Long变量中设置其ID

public static final String recordSequencesql= "SELECT RECORD_ID_SEQ.NEXTVAL FROM DUAL"

Long recordID = jdbcTemplate.queryForObject(SELECT_EVENT_LOG_SEQUENCE_sql,Long.class);

recordDao.save(recordID,record_name,age);

recordID的值显示为-8742538778(在我从序列生成器收到此值之后),其前面带有减号。

我需要确保没有收到负值。我不确定根本原因,也需要解决相同的问题

解决方法

要排除故障,请尝试以下步骤

检查序列

与您的应用程序用户连接并运行以下查询:

select SEQUENCE_OWNER,SEQUENCE_NAME,MIN_VALUE,MAX_VALUE,INCREMENT_BY,CACHE_SIZE,LAST_NUMBER
from all_sequences 
where SEQUENCE_NAME = 'RECORD_ID_SEQ';

SEQUENCE_OWNER                 SEQUENCE_NAME                   MIN_VALUE  MAX_VALUE                   INCREMENT_BY CACHE_SIZE LAST_NUMBER
------------------------------ ------------------------------ ---------- ---------------------------- ------------ ---------- -----------
<owner>                        RECORD_ID_SEQ                           1 9999999999999999999999999999           10         20     1202020

重要值在LAST_NUMBER列中,大约是您通过调用NEXTVAL获得的值。

您将看不到一个号(如果如此,则立即获得Oracle支持)。

您应该看到的是一个适中的数字,如示例中所示。

一个潜在的问题是,如果您看到一个大于9223372036854775807的数字,该数字是Long的最大值,但在 sequence {{1 }}。

但是即使在这种情况下,您也不会从MAX_VALUE查询中得到负数-而是会得到JdbcTemplate异常

Numeric Overflow

摘要

负值问题很可能是在Caught: org.springframework.jdbc.UncategorizedSQLException: StatementCallback; uncategorized SQLException for SQL [SELECT RECORD_ID_SEQ.NEXTVAL FROM DUAL]; SQLstate [99999]; error code [17026]; Numeric Overflow; nested exception is java.sql.SQLException: Numeric Overflow 查询中(您未显示)。

其他建议

SELECT_EVENT_LOG_SEQUENCE_SQL列中使用Long类型的同时,将序列的MAX_VALUE调整为ID的最大值,请参见here进行进一步的讨论

如果您希望使用频繁的序列,请不要使用LONG 10,而要使用INCREMENT_BY

,

在Marmite Bomber指出问题可能出在SQL之后。进行了以下更正 之前
public void saveRecordData(Long RecordId,RecordLog RecordLog) { Object[] parameters = {recordID,RecordLog.getRouteId(),RecordLog.getRecordType().getRecordTypeId(),RecordLog.getOrderId(),RecordLog.getIncomingRecordTimestamp(),RecordLog.getOutgoingRecordTimestamp(),RecordLog.getStatus()}; int[] types = {Types.INTEGER,Types.INTEGER,Types.VARCHAR,Types.TIMESTAMP,Types.VARCHAR}; int rowsAffected = jdbcTemplate.update(INSERT_Record_LOG_SQL,parameters,types); }

之后(将SQL类型从TYPES.INTEGER更改为TYPES.BIGINT) public void saveRecordData(Long RecordId,RecordLog.getStatus()}; int[] types = {Types.BIGINT,types); }