【发布时间】:2018-08-10 22:02:34
【问题描述】:
注意:这可能与 SQL Server、Oracle、DB2 或 MySQL 数据库一起运行。但是对于这个例子,我只是使用 SQL Server。该解决方案需要足够通用,才能应用所有提到的数据库。
在 SQL Server 中,我有一个定义为 decimal(32, 16) 的列,因为该列必须能够存储潜在的大值或精确值。但是,它也可能存储小的或不精确的值。但是当我选择 BigDecimal 时,它会返回原始中没有的尾随零。我认为这是因为我的列定义允许高精度。
我不希望以“发明”的比例/精度来存储或返回任何值,但我仍然需要考虑那么大的比例/精度。
// ... set up ...
// precision 2, scale 2
BigDecimal bdInsert = new BigDecimal("0.51");
preparedStatement.insertBigDecimal(1, bdInsert);
// ... insert/commit ... select ...
// precision 0, scale 16 <-- Grrrrrrr!
BigDecimal bdResult = resultSet.getBigDecimal(1);
System.out.println(bdResult);
// prints "0.5100000000000000" <-- Grrrrrrr!
SQL Server 是否不存储或 JDBC 不发送也不选择插入的 BigDecimal 的精度和小数位数?
我不能只截断零,因为 BigDecimal 可能存储有尾随零以表明它是精确的。
// "0.510000" indicating that this value is accurate to the 6th place
BigDecimal bdPrecise = new BigDecimal("0.510000");
preparedStatement.insertBigDecimal(1, bdPrecise);
// precision 0, scale 16
BigDecimal bdResult = resultSet.getBigDecimal(1);
System.out.println(bdResult);
// prints "0.5100000000000000" loses information
System.out.println(bdResult.stripTrailingZeros());
// prints "0.51", loses information
// What I want is "0.510000"
有没有办法通过 SQL Server 或 JDBC 获得原始 BigDecimal 的比例/精度?
请不要告诉我,我必须创建一个单独的列来存储这些信息...
我想另一种方法是仅将 BigDecimals 插入/选择为字符串,然后从字符串中解析它,例如 new BigDecimal(val)。但我更喜欢存储为小数。
谢谢。
【问题讨论】:
-
您是否考虑过使用
sql_variant列? -
@HABO 看起来很有趣。但是,我忘了提到此代码可用于多种数据库,并且该解决方案应该足够通用,以便能够跨 SQL Server、Oracle、DB2 或 MySQL 数据库工作。 (所以主要是 ANSI SQL) 我知道这很受限制。更新问题以包含此要求。
-
几年前也有过类似的情况,精度不同,也可以作为指标。这有点 hack,但我将值存储为 VARCHAR,因此 0.510000 与尾随零一起存储
-
@JohnCappelletti 是的.. 那是我的替代想法。他们不存储原始比例/精度真是太可惜了
-
根据定义,
decimal(32, 16)的比例为 16,因此 SQL 标准可以预期甚至要求该行为。对于 DB2,您可能希望改用DECFLOAT(它在 SQL:2016 中指定,但据我所知,目前仅在 DB2 中受支持)。
标签: java sql-server tsql jdbc bigdecimal