首页 > 解决方案 > SQL错误:过多coalesce导致BCD溢出

问题描述

出于某种原因从字段中消除空值,使用过多的合并会导致 BCD 溢出错误

我将错误消除到选择部分中的 1 行。

将 '/' 替换为 '-' 也会给出结果,但不是正确的值。

所有字段都是数字(10,4)。
这是火鸟版本 2.5.8

select 
coalesce(Field1, 0) * coalesce(Field2, 0) * ((100 - coalesce(Field3, 0)) / 100) * ((100 + coalesce(Field4, 0)) / 100)
from Table

预期为计算列,实际结果是 BCD 溢出

标签: sqlfirebird

解决方案


不完全是答案,只是一个测试。

Firebird 2.1.7,IBExpert,SQL 方言 3

create table t58096187 (
 f1 numeric(10,4),
 f2 numeric(10,4),
 f3 numeric(10,4),
 f4 numeric(10,4)
);

insert into t58096187 values ( 50, 50, 50, 50 );

select
 coalesce(F1, 0) * coalesce(F2, 0) * ((100 - coalesce(F3, 0)) / 100) * ((100 + coalesce(F4, 0)) / 100)
from t58096187;

错误:执行不成功......整数溢出......导致结果的最高有效位携带


•Dialect 3 数据库允许在精度大于 9 时将数字(DECIMAL 和 NUMERIC 数据类型)存储为 INT64


如果是内部数据类型Numeric(9,4),则应避免使用相同的错误。int64

如果我声明字段float,则select产生结果 1875,这在Numeric(10,4)数据类型范围内。

也许一些中间结果导致反向抛光超出范围?


如果要避免使用 INT64,这也适用

recreate table t58096187 (
 f1 numeric(6,2),
 f2 numeric(6,2),
 f3 numeric(6,2),
 f4 numeric(6,2)
)

似乎 Firebird 3.0.5 也受到影响 - https://dbfiddle.uk/?rdbms=firebird_3.0&fiddle=57729b31e0a5019aea68a136638d9f50

没有错误 - 但也没有结果!

Numeric-as-Int32 作品:https ://dbfiddle.uk/?rdbms=firebird_3.0&fiddle=c4a4230e855b0ce4fd2b0c7b3b697cda

报道为https://www.sql.ru/forum/1317439-a/


马克关于小数部分精度的假设可能是正确的。

recreate table t58096187 (
 f1 numeric(10,4),
 f2 numeric(10,4),
 f3 numeric(10,4),
 f4 numeric(10,3)
)

仍然有效。

https://dbfiddle.uk/?rdbms=firebird_3.0&fiddle=29a6c15d6e1854be230d29aea30307cf


Coalesce似乎与我的问题无关,不知道它是否与主题启动器的问题有关,因为他所说的“删除coalesce”的意思是模棱两可的。删除coalesce后就变成这样了

select
 F1 * F2 * F3 * F4
from t58096187

并且可能是同样的错误

https://dbfiddle.uk/?rdbms=firebird_3.0&fiddle=1f29aff4102ace57e8fa27d83e59b93f


推荐阅读