使用Simba ODBC驱动查询AWS Athena特定DECIMAL值失败问题咨询
根本原因
该问题是Unix版本Simba Athena ODBC驱动的已知实现缺陷,结合二进制浮点数精度特性导致:
- 十进制小数转双精度浮点数(R中
double类型)时大多为非精确值,2.4的二进制舍入结果刚好和R字面量解析的结果完全一致,所以等值校验通过;而2.3的二进制表示本身存在舍入误差,Unix版驱动将Athena返回的精确DECIMAL值转为double时,使用的舍入规则和R本地解析字面量的规则不一致,仅最低位存在可忽略的数值差,因此直接判等失败,转字符串或保留3位小数后结果一致。 - Windows版本驱动的DECIMAL转
double逻辑和R匹配,因此无法复现问题。
可行解决方案
- 方案1:修改连接配置避免驱动自动转浮点数
在dbConnect参数中新增两项配置,强制驱动将DECIMAL以字符串形式返回,本地自行转换即可避免精度损失:
拿到查询结果后按需用con <- DBI::dbConnect(odbc::odbc(), Driver = "/opt/simba/athenaodbc/lib/64/libathenaodbc_sb64.so", # 原有其他配置不变 DecimalAsDouble = FALSE, StringColumnLength = 256)as.numeric()或者高精度数值包转换即可。 - 方案2:改用容忍浮点误差的判等逻辑
不修改现有配置的前提下,不要直接用==做等值校验,改用R内置的all.equal()函数,默认会忽略1e-7级别的浮点误差:
批量校验可以自定义判等函数:all.equal(result[[1]], 2.3) # 返回TRUE即为相等equal_decimal <- function(x, y, tolerance = 1e-6) { abs(x - y) < tolerance } - 方案3:SQL侧直接返回字符串
查询时将DECIMAL字段强转为VARCHAR返回,完全绕开驱动的数值转换逻辑:select CAST(your_decimal_column AS VARCHAR) from test
之前排查操作无效的原因
- 切换DECIMAL/DOUBLE类型无效:两类数值的转换逻辑均由驱动控制,Unix版驱动的舍入缺陷同样会作用于DOUBLE类型
- 修改
DriverManagerEncoding无效:该参数用于控制字符集编码,和数值类型转换逻辑无关
内容的提问来源于stack exchange,提问作者Jrm_FRL
相关产品推荐
相关产品推荐

