JDBC SQL Server十进制“发明”精度

问题描述 投票:0回答:1

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

谢谢。

java sql-server tsql jdbc bigdecimal
1个回答
1
投票

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

我怀疑在“所有”平台上工作的唯一解决方案是一个字符串,可能包含具有明确精度的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英寸显示为“23.12”。输入和输出处理“36.1”和“36.10”的差异为9/16? Oy公司。)

© www.soinside.com 2019 - 2024. All rights reserved.