Jdbc Firebird数字/十进制精度和比例(以Jaybird为单位)

Jdbc Firebird数字/十进制精度和比例(以Jaybird为单位),jdbc,decimal,firebird,numeric,jaybird,Jdbc,Decimal,Firebird,Numeric,Jaybird,我正在用Java测试JDBC(Jaybird)中Firebird数字/十进制字段的行为 使用FBResultSetMetaData检查列属性时(用于使用ResultSet.getObject方法,例如SELECT*FROM NUMERICTESTquery),我得到精度(FBResultSetMetaData.getPrecision)和比例(FBResultSetMetaData.getScale)与Firebird中的表定义中声明的完全相同,例如 NUMERIC(3,2) field ...

我正在用Java测试JDBC(Jaybird)中Firebird数字/十进制字段的行为

使用
FBResultSetMetaData
检查列属性时(用于使用
ResultSet.getObject
方法,例如
SELECT*FROM NUMERICTEST
query),我得到精度(
FBResultSetMetaData.getPrecision
)和比例(
FBResultSetMetaData.getScale
)与Firebird中的表定义中声明的完全相同,例如

NUMERIC(3,2) field ... precision 3, scale 2
DECIMAL(3,2) field ... precision 3, scale 2
使用
FBParameterMetaData
检查参数属性时(用于使用
PreparedStatement.setObject
方法,例如
插入数值测试值(?)
查询),对于相同字段,我得到不同的精度值(
FBParameterMetaData.getPrecision
)和比例(
FBParameterMetaData.getScale

我知道这些值以某种方式对应于这些字段的内部db存储类型(
smallint
在第一个示例中,在第二个示例中,
integer

当与同一字段相关时,
FBResultSetMetaData
FBParameterMetaData
的行为不同的原因是什么?这很容易引起误解


Java 8 u 181、Jaybird 3.0.4、Firebird 2.5

问题在于,prepare本身仅为数值列(参数和结果集列)提供以下信息:

  • 键入(
    SQL\u SHORT
    SQL\u LONG
    SQL\u INT64
  • 子类型(0表示
    SMALLINT
    /
    INTEGER
    /
    BIGINT
    ,1表示
    NUMERIC
    ,2表示
    DECIMAL
  • 鳞片
  • 以字节为单位的长度(2、4或8)
换句话说,声明的精度不可用

对于参数,无法知道与之进行比较或指定给它的列的声明精度,因为Firebird没有提供允许发现实际精度的信息。因此,Jaybird使用列类型的最大精度(即
SQL\u SHORT
:4、
SQL\u LONG
:9和
SQL\u INT64
:18)

对于结果集列,Firebird可以提供(在某些情况下)基础列名和表,而Jaybird使用此信息查询元数据表以获取实际精度信息。此信息并不总是可用的,例如,计算/派生列或涉及
联合的查询列不具有e基础列名和表名。如果此信息不可用,Jaybird将以与参数相同的方式进行估计

此信息的精度没有实质差异:即使一个列为“代码>十进制(6/2)< /CUT>(或<代码>数字(6/2)< /代码>)的列,也可以存储和返回最大精度为9的值(如果考虑到<代码> SqLyLoun< /Cux>是32位有符号整数),则可以存储10的值。。就Firebird中的所有意图和目的而言,

十进制(6,2)
实际上是
十进制(9,2)
。但是,我们决定在该信息可用时提供实际声明的精度信息

换句话说:Jaybird尽可能精确,如果没有足够的信息,它会优雅地退化

披露:我是Jaybird的开发者之一

NUMERIC(3,2) field ... precision 4, scale 2
DECIMAL(3,2) field ... precision 9, scale 2