如何在SQL中处理非常大的值?

时间:2017-11-23 13:56:46

标签: sql sybase-ase

使用Sybase ASE 15.7,我被要求评估复杂计算的可行性。实际上,计算并不复杂,但它需要处理非常大的数字并同时保持非常高的小数精度。

以下是我的约束:

  • 一切都必须在存储过程中执行。没有数据可以导入数据库或导出到数据库之外(使用其他工具或编程语言会是一个笑话)。
  • 我必须保持小数点右边不小于18位的精度(使用DECIMAL数字类型,我最多可以使用38位数,这意味着我可以在小数点左边只有20个。)

以下是我的原型现在的样子:

CREATE PROCEDURE dbo.MyProc
(
    @X DECIMAL(38,18),
    @ALPHA DECIMAL(38,18),
    @BETA_1 DECIMAL(38,18),
    @BETA_2 DECIMAL(38,18),
    @BETA_3 DECIMAL(38,18),
    @BETA_4 DECIMAL(38,18),
    @BETA_5 DECIMAL(38,18)
)
AS
BEGIN

    DECLARE @POLY_1 DECIMAL(38,18)
    SET @POLY_1 = @ALPHA

    DECLARE @POLY_2 DECIMAL(38,18)
    SET @POLY_2 = @BETA_1 * @X

    DECLARE @POLY_3 DECIMAL(38,18)
    SET @POLY_3 = @BETA_2 * POWER(@X,2.0)

    DECLARE @POLY_4 DECIMAL(38,18)
    SET @POLY_4 = @BETA_3 * POWER(@X,3.0)

    DECLARE @POLY_5 DECIMAL(38,18)
    SET @POLY_5 = @BETA_4 * POWER(@X,4.0)

    DECLARE @POLY_6 DECIMAL(38,18)
    SET @POLY_6 = @BETA_5 * POWER(@X,5.0)

    DECLARE @POLY_SUM DECIMAL(38,18)
    SET @POLY_SUM = @POLY_1 + @POLY_2 + @POLY_3 + @POLY_4 + @POLY_5 + @POLY_6

    SELECT @POLY_SUM

END       
GO

以下是使用实际数据的示例:

 EXEC dbo.MyProc 360, 0.000000000000000000, 3.001691154643420000, -0.004000558548191020, 0.000003108186568058, 0.000000000639528525, -0.000000000000517669

上述示例查询的结果是NULL。稍微调整一下我的程序后:

CREATE PROCEDURE dbo.MyProc
(
    @X DECIMAL(38,18),
    @ALPHA DECIMAL(38,18),
    @BETA_1 DECIMAL(38,18),
    @BETA_2 DECIMAL(38,18),
    @BETA_3 DECIMAL(38,18),
    @BETA_4 DECIMAL(38,18),
    @BETA_5 DECIMAL(38,18)
)
AS
BEGIN

    DECLARE @POLY_1 DECIMAL(38,18)
    SET @POLY_1 = @ALPHA

    DECLARE @POLY_2 DECIMAL(38,18)
    SET @POLY_2 = @BETA_1 * @X

    DECLARE @POLY_3 DECIMAL(38,18)
    SET @POLY_3 = @BETA_2 * CONVERT(DECIMAL(38,18),POWER(@X,2.0))

    DECLARE @POLY_4 DECIMAL(38,18)
    SET @POLY_4 = @BETA_3 * CONVERT(DECIMAL(38,18),POWER(@X,3.0))

    DECLARE @POLY_5 DECIMAL(38,18)
    SET @POLY_5 = @BETA_4 * CONVERT(DECIMAL(38,18),POWER(@X,4.0))

    DECLARE @POLY_6 DECIMAL(38,18)
    SET @POLY_6 = @BETA_5 * CONVERT(DECIMAL(38,18),POWER(@X,5.0))

    DECLARE @POLY_SUM DECIMAL(38,18)
    SET @POLY_SUM = @POLY_1 + @POLY_2 + @POLY_3 + @POLY_4 + @POLY_5 + @POLY_6

    SELECT @POLY_SUM

END       
GO

我终于设法获得了正确的结果:714.763457289478656

现在,真正的问题是存储过程的第一个参数变量X的范围从最小1到最大10000000。一旦X值增加到他的最大值,我开始得到算术溢出问题,因为...... 500000^4(只是我范围内的随机值)增长到{{1没有数字类型可以存储这么大的值。

我几乎阅读了每篇博客文章/关于如何处理非常大数字的SO帖子/教程是SQL,但我发现没有什么可以帮助我。实际上......这个问题有解决方案吗?如果是的话,哪一个?

我正在考虑所有可能的方法......将31250000000000000000000000000除以X并将所有测试值乘以相同的值(这只会延迟失败时刻),使用对数基数(不可能,因为贝塔可以是负数),分解函数以减少指数......我不知道...

0 个答案:

没有答案