Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何处理由于分组函数而导致的JDBC数字类型的精度损失_Java_Oracle_Jdbc_Oracle11g - Fatal编程技术网

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

Java 如何处理由于分组函数而导致的JDBC数字类型的精度损失,java,oracle,jdbc,oracle11g,Java,Oracle,Jdbc,Oracle11g,Oracle(和其他一些DB)有一个数据类型编号,可以选择使用该编号设置精度和比例 假设以下查询: SELECT agent_code, AVG (opening_amt) FROM customer GROUP BY agent_code; 如果上述查询中的两个字段都被定义为数字(12,0),JDBC中的结果确实是agent_代码的结果,但在“AVG(opening_amt)”上,精度和比例都返回0(通过java.sql.ResultSetMetaData.getPrecision(co

Oracle(和其他一些DB)有一个数据类型编号,可以选择使用该编号设置精度和比例

假设以下查询:

SELECT agent_code, 
AVG (opening_amt)
FROM customer 
GROUP BY agent_code;
如果上述查询中的两个字段都被定义为数字(12,0),JDBC中的结果确实是agent_代码的结果,但在“AVG(opening_amt)”上,精度和比例都返回0(通过java.sql.ResultSetMetaData.getPrecision(col)和java.sql.ResultSetMetaData.getScale(col)

这与数字基本相同,没有任何精度或刻度规格,根据甲骨文的说法,等于数字(38,12)

上述精度损失给我带来了一个问题,即确定sql类型应转换为Double还是Integer


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

我认为您可以转换为任何所需的类型

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

SQL AVG()函数返回带默认小数位数的平均值。CAST()用于增加或减少值的小数位数。在转换十进制和数字数据类型时,CAST()函数更擅长保留小数位数。CAST()使用格式规范后面的“AS decimal”用于将数值设置为特定的小数位值


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

对于未指定的
数值
,数据库似乎不存储有关列的精度和比例的任何特定信息。这允许数据库以任何合适的方式在内部存储值。从

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

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

看起来情况是这样的。最大精度可能更高,但可移植性只能保证高达38位

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


至于解决问题中的问题,正如StanislavL指出的,您可以通过强制转换将值强制到特定的精度/比例。

仅仅因为原始值可以定义为
NUMBER(12,0)
,并不意味着它们的平均值必须是同一类型的。事实上,如果您需要以尽可能高的精度获得平均值,这将是一件非常糟糕的事情。如果您想控制它,您可以将平均值强制转换为特定类型。同意。但JDBC不应该返回字段的最大精度和比例吗(就像Oracle内部处理它一样),而不是0,0?我希望是这样。列的类型(通过
ResultSetMetaData.getColumnType()
)真的
Types.NUMERIC
?是的,java.sql.Types.NUMERIC(2)嗯……我查看了Postgres驱动程序如何处理这种情况,它似乎做了完全相同的事情。对于没有指定精度或刻度的
NUMERIC
列,内部
atttypmod
值设置为
-1
,导致从两种方法返回
0
,否则精度和刻度将被计算d基于
atttypmod
。这不仅仅是Oracle的错。是的,但这仍然留下了一个问题,为什么Oracle返回scale和precision为0,而它在内部使用这两个(38,12)的最大可用值。我想它会根据结果动态计算scale和precision。例如,如果你有数字(1)求和10行,结果可能是数字(2),如果是10k行…等等。因此我猜oracle会根据计算结果更改列类型。我只是猜测没有参考任何文档。很好的调查!似乎我们的猜测是合理的。+1