为什么大数字在保存到Oracle DB时会更改值

Joo*_*imm 5 java oracle plsql spring-jdbc ojdbc

在一个软件项目中,我们偶然发现了一个错误,我们从Java中插入了大量(17位数)到Oracle DB过程.数字改变了它的值有时+1或-1.有时保持不变.我们检查了oracle DB驱动程序调试日志,看到它打印了正确的数字.我们还尝试在每个请求之间重新启动Java应用程序服务器,以消除奇怪的缓存错误.仍然得到相同的结果.

任何想法为什么会这样?

这是代码:

// Datasource configuration
<New class="oracle.jdbc.pool.OracleDataSource">
    <Set name="DriverType">thin</Set>
    <Set name="URL">jdbc:oracle:thin:@xxxx</Set>
    <Set name="User">uuuu</Set>
    <Set name="Password">pppp</Set>
</New>

// JAVA
SimpleJdbcCall testMsg = new SimpleJdbcCall(dataSource).
    withSchemaName(schema).
    withCatalogName(catalog).
    withProcedureName("test_msg");

public void testMessage(Long n) {
  testMsg.execute(n, n, n.toString());
}

// PL_SQL
procedure test_msg(
    i           integer,
    n           number,
    v           varchar2
) is
    log_prfx log_pkg.t_log_prfx := 'test_msg: ';
begin
    g_log.log_debug(log_prfx||'i='||to_char(i));
    g_log.log_debug(log_prfx||'n='||to_char(n));
    g_log.log_debug(log_prfx||'v='||v);
end test_msg;
Run Code Online (Sandbox Code Playgroud)

现在打电话

testMessage(10000000000000005L);
testMessage(10000000000000007L);
testMessage(10000000000000009L);
Run Code Online (Sandbox Code Playgroud)

最终得到像日志

test_msg: i=10000000000000005
test_msg: n=10000000000000005
test_msg: v=10000000000000005


test_msg: i=10000000000000008
test_msg: n=10000000000000008
test_msg: v=10000000000000007

test_msg: i=10000000000000008
test_msg: n=10000000000000008
test_msg: v=10000000000000009
Run Code Online (Sandbox Code Playgroud)

我们正在使用的版本.

  • 春季3.2.11
  • Oracle驱动程序ojdbc7_g-12.1.0.2(我们还测试了11.2.0.4)
  • Oracle DB是版本12.1.0.1.0
  • Jetty 9.2.2和JBoss 7(两者都出现相同的行为)

Joo*_*imm 0

所以最后我从 Java 传入 BigDecimal 并在 plsql 中使用 NUMBER (尽管整数也可以工作)。

感谢伊万的提示!