JDBC SQL Server Decimal"发明"精确

时间:2018-03-02 16:31:15

标签: java sql-server tsql jdbc bigdecimal

注意:这可以与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)这样的字符串中解析它。但我更喜欢以小数形式存储。

感谢。

1 个答案:

答案 0 :(得分:1)

以下代码演示了SQL Server中的sql_variant数据类型。 (以及如何显示有关表达式的数据类型信息。)由于解决方案需要应用于能够保留位的任何内容,它不会解决您的所有问题,但它可能是一些值。

我怀疑唯一可以解决的问题是&#34;所有&#34; platforms是一个字符串,可能包含具有显式精度的XML。

declare @Samples as Table ( Value sql_variant );
insert into @Samples ( Value ) values
  ( Cast( 3.14 as Decimal( 10, 2 ) ) );
insert into @Samples ( Value ) values
  ( Cast( 3.14 as Decimal( 10, 3 ) ) );
insert into @Samples ( Value ) values
  ( Cast( 3.14 as Decimal( 10, 4 ) ) );
insert into @Samples ( Value ) values
  -- NB: Both values are inserted with scale 5 when they are included in a single INSERT.
  ( Cast( 42 as Decimal( 10, 1 ) ) ),
  ( Cast( 42 as Decimal( 10, 5 ) ) );
insert into @Samples ( Value ) values
  ( Cast( 1.618 as Decimal( 10, 6 ) ) );
insert into @Samples ( Value ) values
  ( 'Edgar' );

select Value, SQL_Variant_Property( Value, 'BaseType' ) as BaseType,
  SQL_Variant_Property( Value, 'Precision' ) as Precision,
  SQL_Variant_Property( Value, 'Scale' ) as Scale
  from @Samples;

(然后是钢厂,他们想要一英寸到十六分之间的点,例如23 3/4英寸显示为&#34; 23.12&#34;处理&#34; 36.1&#34;和&#34; 36.10&#34;输入和输出的差异为9/16?Oy。)