如果插入的123,NUMERIC(5,2)应返回123或123.00吗?

lex*_*ore 1 java sql jdbc hsqldb bigdecimal

假设我们有同一个表NUMERIC(5,2),我们要插入123BigDecimal.

当我们选择返回值时 - 它应该是123(当我们插入它时)或者123.00


我在其中一个项目中从HSQLDB 1.8.0.10迁移到2.3.3时遇到过这个问题.

使用1.8.0.10我得到了插入值的比例(123对于插入的123).

使用2.3.3我得到了列的比例,无论是什么(123.00插入123).

我已将此报告为错误但得到以下响应:

但是NUMERIC(5,2)表示无论插入什么,总有2个小数位.版本1.8未遵循SQL标准定义.

我不知道这是否正确,但这对我来说似乎不合逻辑.

我们真的应该在小数部分得到这些零,"无论如何"?

这是我的测试用例:

    Connection conn = DriverManager.getConnection(...);
    Statement stmt = conn.createStatement();
    stmt.executeUpdate("create table test (value NUMERIC(5,2));");
    String sql = "INSERT INTO test (value) VALUES(?)";
    PreparedStatement pstmt = conn.prepareStatement(sql);
    pstmt.setBigDecimal(1, BigDecimal.ONE);
    pstmt.executeUpdate();
    ResultSet rs = stmt.executeQuery("SELECT * FROM test");
    while (rs.next()) {
        Assert.assertEquals(BigDecimal.ONE, rs.getBigDecimal(1));
    }
    rs.close();
    stmt.close();
    conn.close();
Run Code Online (Sandbox Code Playgroud)

Kam*_*ski 6

正确的值是123.00当你插入123到一个NUMERIC(5,2)列.这是事实,因为对于数字,值总是被转换为具有目标数据类型的精度.在您的情况下,指定的精度为5,您的比例为2.只有标度为0的数字才是整数.

从SQL-1992标准:4.4.1数字的特征

比例是非负整数.标度为0表示该数字是整数.

[...]

每当精确或近似数值被分配给表示精确数值的数据项或参数时,在目标的数据类型中表示在舍入或截断之后保留前导有效数据的值的近似值.该值将转换为具有目标的精度和比例.是否截断或舍入的选择是实现定义的.

[...]

每当将精确或近似数值分配给表示近似数值的数据项或参数时,其值的近似值将在目标的数据类型中表示.该值将转换为具有目标的精度.

想象一个VARCHAR(50)列,它将返回VARCHAR(3)存储在其中的字符串的类型,该字符串只包含3个字符.这不奇怪吗?

上面的例子是有效的,因为如果我们修剪值123.00123它将不再是一个有效的numeric(5,2)数据类型.转换就在那里,让您插入该值而不会抛出错误.

此外,在这种特殊情况下,您的旧版本的HSQL 1.8.0.1from 2005.07.11显然不遵循SQL Standard.您可以在他们的网站上阅读:

HyperSQL 2支持SQL标准92,1999,2003,2008和2011定义的SQL方言.这意味着支持标准功能的地方,例如左外连接,语法是标准文本指定的语法.几乎支持SQL-92到高级的所有语法功能,以及SQL:2011核心和本标准的许多可选功能.