Oracle 序列生成器 returns 一个负值,当序列号存储在 Java 变量中时
Oracle Sequence generator returns a negative value , when the sequence number is stored in Java variable
我有一个名为 Record ID 的数据库列。这是一个主键,它的值是使用具有以下属性的 oracle 序列生成的
序列详细信息
最小值:1
最大值:999999999999999999999999999
递增:10
在我的 Java 应用程序中,我在应用一些业务逻辑后将记录插入 table。字段 Record ID 的值来自序列生成器
在插入记录之前,在 Java 代码中,我首先将其 ID 设置在一个 Java 长变量中,代码如下(从序列生成器中获取)
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 支持)。
您应该看到的是一个适度的数字,如 5 月示例中所示。
一个潜在的问题是,如果您看到一个数字高于 9223372036854775807
,这是 Long
的最大值,但有效数字低于 序列 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
查询中(您没有显示)。
进一步的建议
在 ID
列使用 Long
类型时,将序列的 MAX_VALUE 调整为 LONG
的最大值,请参阅 了解更多信息讨论
如果您预计会大量使用序列,请不要使用 INCREMENT_BY
10,而应使用 1
在 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.INTEGER, Types.VARCHAR, Types.TIMESTAMP, 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 RecordLog) { Object[] parameters = {recordID, RecordLog.getRouteId(), RecordLog.getRecordType().getRecordTypeId(), RecordLog.getOrderId(), RecordLog.getIncomingRecordTimestamp(), RecordLog.getOutgoingRecordTimestamp(), RecordLog.getStatus()}; int[] types = {Types.BIGINT, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.TIMESTAMP, Types.TIMESTAMP, Types.VARCHAR}; int rowsAffected = jdbcTemplate.update(INSERT_Record_LOG_SQL, parameters, types); }
我有一个名为 Record ID 的数据库列。这是一个主键,它的值是使用具有以下属性的 oracle 序列生成的 序列详细信息 最小值:1 最大值:999999999999999999999999999 递增:10
在我的 Java 应用程序中,我在应用一些业务逻辑后将记录插入 table。字段 Record ID 的值来自序列生成器
在插入记录之前,在 Java 代码中,我首先将其 ID 设置在一个 Java 长变量中,代码如下(从序列生成器中获取)
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 支持)。
您应该看到的是一个适度的数字,如 5 月示例中所示。
一个潜在的问题是,如果您看到一个数字高于 9223372036854775807
,这是 Long
的最大值,但有效数字低于 序列 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
查询中(您没有显示)。
进一步的建议
在 ID
列使用 Long
类型时,将序列的 MAX_VALUE 调整为 LONG
的最大值,请参阅
如果您预计会大量使用序列,请不要使用 INCREMENT_BY
10,而应使用 1
在 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.INTEGER, Types.VARCHAR, Types.TIMESTAMP, 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 RecordLog) { Object[] parameters = {recordID, RecordLog.getRouteId(), RecordLog.getRecordType().getRecordTypeId(), RecordLog.getOrderId(), RecordLog.getIncomingRecordTimestamp(), RecordLog.getOutgoingRecordTimestamp(), RecordLog.getStatus()}; int[] types = {Types.BIGINT, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.TIMESTAMP, Types.TIMESTAMP, Types.VARCHAR}; int rowsAffected = jdbcTemplate.update(INSERT_Record_LOG_SQL, parameters, types); }