Oracle序列生成器在序列号存储在Java变量中时返回负值。

huangapple go评论63阅读模式
英文:

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 = &#39;RECORD_ID_SEQ&#39;;

SEQUENCE_OWNER                 SEQUENCE_NAME                   MIN_VALUE  MAX_VALUE                   INCREMENT_BY CACHE_SIZE LAST_NUMBER
------------------------------ ------------------------------ ---------- ---------------------------- ------------ ---------- -----------
&lt;owner&gt;                        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_SQLquery (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);
}

huangapple
  • 本文由 发表于 2020年9月24日 15:09:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/64041211.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定