NUMERIC(5,2) 应该为插入的 123 返回 123 还是 123.00?

Posted

技术标签:

【中文标题】NUMERIC(5,2) 应该为插入的 123 返回 123 还是 123.00?【英文标题】:Should NUMERIC(5,2) return 123 or 123.00 for the inserted 123? 【发布时间】:2015-11-26 20:29:21 【问题描述】:

假设我们有一个带有NUMERIC(5,2) 的表,并且我们将123 插入为BigDecimal

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


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

在 1.8.0.10 中,我得到了插入值的比例(123 表示插入的 123)。

在 2.3.3 中,无论如何我都会获得列的比例(123.00 用于插入的 123)。

我有reported this as a bug,但得到以下回复:

但 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();

【问题讨论】:

响应正确,基于标准 SQL 定义为 NUMERIC(5,2) 的列应始终返回两位小数。 @dnoeth 你有这方面的参考吗? 【参考方案1】:

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

From SQL-1992 standard: 4.4.1 Characteristics of numbers

规模是 非负整数。刻度为 0 表示该数字是 整数。

[...]

每当一个精确或近似的数值被分配给一个 表示精确数值的数据项或参数, 其价值的近似值,保留领先的显着 dig- 舍入或截断后的数据类型表示 的目标。该值被转换为具有精度和 目标的规模。截断还是舍入的选择是 实现定义。

[...]

每当一个精确或近似的数值被分配给一个 表示近似数值的数据项或参数, 其值的近似值以 目标。该值被转换为具有 目标。

想象一个VARCHAR(50) 列将返回VARCHAR(3) 类型,用于存储在其中的仅包含3 个字符的字符串。会不会很奇怪?

以上示例是有效的,因为如果我们将值 123.00 修剪为 123,它将不再是有效的 numeric(5,2) 数据类型。转换已到位,可让您插入该值而不会引发错误。

此外,在这种特殊情况下,2005.07.11 的旧版本 HSQL 1.8.0.1 显然没有遵循 SQL 标准。从您可以在他们的site 上看到的内容:

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

【讨论】:

行为与@lexicore 发布的相同,即使我使用 Decimal(5,2) 而不是 Numeric(5,2),我也通过测试示例进行了检查。当我为小数(5,2)插入 123 时,我可以考虑将上述相同的描述作为具有 123.00 的答案吗? @TechMaster 是的

以上是关于NUMERIC(5,2) 应该为插入的 123 返回 123 还是 123.00?的主要内容,如果未能解决你的问题,请参考以下文章

Postgres - 在较低的 UNION 选择语句中插入 NUMERIC[] 值“0”

NUMERIC和DECIMAL的区别

PHP漏洞函数

numeric是啥类型?

Java 中应该使用啥数据类型来代表价格

速达 将numeric转换为数据类型numeric时发生算术溢出错误