当前位置: 首页 > 知识库问答 >
问题:

如何处理由于分组函数而导致的JDBC数字类型精度损失

丌官运诚
2023-03-14

Oracle(和其他一些DB)有一个数据类型NUMBER,可以选择设置精度和规模。

假设以下查询:

SELECT agent_code, 
AVG (opening_amt)
FROM customer 
GROUP BY agent_code;

如果上述查询中的两个字段都定义为NUMBER(12,0),则JDBC中的结果确实是agent_code,但在AVG(opening_amt)上,精度和刻度都返回0(通过java.sql.ResultSetMetaData.get精度(col)和java.sql.ResultSetMetaData.get刻度(col)。

这基本上与NUMBER相同,没有任何精度或比例规范,根据甲骨文,将等于NUMBER(38,12)。

上面的精度损失给我一个问题来确定sql类型是否应该转换为双精度或整数。

所以,我想知道这是否是Oracle JDBC驱动程序中的一个bug,或者应该如何处理?(不,使用BigDecimal作为对应的java类型不是我的选择)。

共有2个答案

丁光华
2023-03-14

我认为你可以选择任何类型

CAST(AVG(opening_amt) AS DECIMAL(12,2))

参见示例

SQLAVG()函数返回具有默认小数位的平均值。CAST()用于增加或减少值的小数位。CAST()函数在转换小数和数字数据类型时更好地保留小数位。格式规范后跟的“AS DECIMAL”与CAST()一起用于将数值转换为特定的小数位值。

蒙洛华
2023-03-14

这是基于Postgres驱动程序postgresql-9.4-1204-jdbc42中类似行为的推测。jar。

对于未指定的数值,数据库似乎没有存储有关列精度和比例的任何特定信息。这允许数据库以任何合适的方式在内部存储值。从…起https://www.postgresql.org/docs/current/static/datatype-numeric.html

如果没有任何精度或比例,则创建一列,其中可以存储任何精度和比例的数值,最高可达精度的实现限制(小数点前最多131072位;小数点后最多16383位)

由于驱动程序不知道服务器的具体实现最大值是多少,因此无法返回实际值。它返回0表示它不知道实际值,也不想进行任何有根据的猜测。

Oracle的情况似乎也是如此。最大精度可能更高,但最多只能保证38位的可移植性。

可以存储几乎任何数量级的数字,并保证可在操作Oracle数据库的不同系统之间移植,精度高达38位。

至于解决问题中的问题,如StanislavL所示,可以通过铸造将值强制到特定的精度/比例。

 类似资料:
  • 问题内容: 在Golang中如何导出返回双精度数组的函数。现在以前似乎可以返回“运行时错误:cgo结果具有Go指针”的方式: 问题答案: 为了安全地将指针存储在C中,它指向的数据必须在C中分配。

  • 问题内容: 我的程序规格如下。1.所有四个数字都不同。2.千位数字是十位数的三倍。3.数字是奇数。4.数字的总和是27。我遗漏了整个程序的一些代码。它具有干净的编译器,但运行时会自动终止。我认为问题出在数据类型的转换中。 问题答案: 仅此一项就确保了while循环将永远不会进入,因为它是false。while循环中的任何内容都没有任何区别,因为它将永远不会执行。 你可能想写 除了此错误外,您的情况

  • 问题内容: 我有以下虚拟测试脚本: 这将打印结果,而仅打印结果(如果使用计算器)。据我了解,这是由于浮点乘法精度的错误。 有没有人有一个好的解决方案,这样在这种情况下我可以获得正确的结果?我知道还有类似的函数,或者四舍五入是另一种可能性,但是我真的想在不进行任何四舍五入的情况下打印出完整的数字。只是想知道你们中的一个人是否有一些不错的,优雅的解决方案。 当然,否则我将四舍五入到大约10位数字。 问

  • 我测试了一个SOAPHandler来截取响应,但我没有找到任何方法来更改消息属性的顺序。 这是签名类生成的节点时间戳的XML代码: 这是响应中发送的时间戳节点的XML代码:

  • 最近,我将我的项目从Hibernate版本3.1迁移到4.3,为了更好的性能,我试图使用注释而不是我的xml映射。在继承类的所有实体类中,我都有以下异常。错误是"org.hibernate.映射异常" 我试图将targetEntity添加到manytone类中,并添加了@Access(AccessType.PROPERTY),但没有任何效果。无法更改为字段注释,因为我有150个实体类。我试图删除扩

  • 在Angular 7/typescript 3-ish中使用EventEmitter获取“is not a function”。关于这个错误已经写了很多(a b),但很少有人赞成答案(a b c d e f)。我快到了,但需要一些帮助来完成这个。 这是一个有错误的堆栈闪电战。…和一个没有错误的类似的。 唯一的区别似乎是,对于错误,我的事件发射器和接收器位于同级文件夹中。在有效的情况下,事件接收器位