英文:
Oracle Sequence generator returns a negative value , when the sequence number is stored in Java variable
问题
以下是翻译好的内容:
我有一个名为“Record ID”的数据库列。这是一个主键,其值是使用Oracle序列生成的,该序列具有以下属性
序列详情
最小值:1
最大值:9999999999999999999999999999
增量:10
在我的Java应用程序中,我在应用一些业务逻辑后将记录插入表中。字段“Record ID”的值是从序列生成器获取的。
在插入记录之前,在Java代码中,我首先使用以下代码将其ID设置为Java Long变量中(从序列生成器获取)。
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(在我从序列生成器接收此值之后),其前面有一个负号。
我需要确保不会收到负值。我不确定根本原因,也需要解决方法。
英文:
I have a database column named Record ID . This is a primary key and its value is generated using an oracle sequence which has the below properties
Sequence Details
Min Value : 1
max Value : 9999999999999999999999999999
increment by : 10
In my Java application , I insert records into the table after applying some business logic . The value for the field Record ID , is got from a sequence generator
Before inserting a record , in Java code I first set its ID in a Java Long Variable with below code ( got from a sequence generator )
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);
The recordID value shows as -8742538778 ( after I receive this value from sequence generator) , which has a minus sign in front of it .
I need to make sure that there is no negative values received . I'm not sure of the root cause and also need a solution to the same
答案1
得分: 2
故障排除时,请尝试以下步骤
检查序列
连接到应用程序用户并运行以下查询:
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
类型的最大值,但它是序列 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。
英文:
To trouble shoot try the following steps
Check the Sequence
Connect with your application user and run the following query:
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
The important value is in the column LAST_NUMBER
which is approximately the value you get by calling the NEXTVAL
.
You will not see a negative number (if so contanct Oracle support immediately).
What you should see is a modest number as in may example.
One potential problem is if you see a number that is higher than 9223372036854775807
which is the max value for Long
, but is valid number below the sequence MAX_VALUE
.
But even in this case you will not get a negative number from your JdbcTemplate
query - instead you will get an Numeric Overflow
exception
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
Summary
The problem with the negative value is most probably in the SELECT_EVENT_LOG_SEQUENCE_SQL
query (which you did not show).
Further Suggestions
While using the Long
type for the ID
column adjust the MAX_VALUE of the sequence to the max value of LONG
see here for further discussion
If you expect heavy used sequence, do not use INCREMENT_BY
10, but stay on 1
答案2
得分: 0
在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);
}
英文:
After Marmite Bomber pointed out that issue might be in the SQL. Made the below corrections
Before
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);
}
After ( changed the SQL Type from TYPES.INTEGER to 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);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论