代码之家  ›  专栏  ›  技术社区  ›  JYelton Melchior Blausand

在SQL中存储为十进制(4,1)之前,如何验证/验证浮点?

  •  1
  • JYelton Melchior Blausand  · 技术社区  · 14 年前

    我在SQL中定义了一列 decimal(4,1), null 这意味着我要存储四个数字,其中一个可以是小数点的右边。

    源数据应该始终在0到999.9的范围内,但由于超出我控制范围的错误,我收到了编号为38591844.0的数据。显然,这不会存储在SQL中,并给出错误“算术溢出错误,将实数转换为数据类型numeric”。

    如果值超出界限,我希望存储空值。

    验证值(C中的浮点)是否不超出上述定义的SQL列的界限的最佳方法是什么?

    虽然这似乎是最简单的方法…

    private bool Validate41Float(float f)
    {
        if (f >= 0 && f <= 999.9) return true;
        else return false;
    }
    

    我担心是否因为某种原因我得到了这个值:10.12345。在这种情况下,我只想存储10.1,但是额外的精度是否会导致相同的SQL错误?

    3 回复  |  直到 14 年前
        1
  •  2
  •   Tim Coker    14 年前

    我知道您可以将10.12345提交给SQL Server,它将接近10.1,不会抱怨。我不知道其他数据库供应商的情况,但我认为他们的工作原理是一样的。

    也可以有负值。为了清楚您正在做什么,您可能需要显式地舍入,然后像这样测试您的逻辑:

    private bool Validate41Float(float f)
    {
        float rounded = (float)Math.Round(f, 1);
        if (rounded > -1000 && rounded < 1000) return true;
        else return false;
    }
    
        2
  •  1
  •   Edwin Buck    14 年前

    ---评论后编辑,澄清问题---

    大多数数据库将对数字进行四舍五入以适应格式。我不确定这是SQL标准还是数据库供应商之间的一种常见做法。

    如果数字太大而无法存储在数据库中(如123456.7),大多数数据库都会产生一个错误,该数字无法满足精度要求。田野的

    ——原岗位如下---

    浮点数并不表示精确的数据值,它们只是表示可以正确表示为基2分数总和的数据值。

    例如,1.75完全可以表示,因为它是1+1/2+1/4。像1和1/3这样的数字不能精确表示,因为1/2^n形式的分数之和不能表示1/3。

    有鉴于此,如果这确实是一个关键问题,您需要执行以下操作之一:

    1. 四舍五入(或修剪)结果最接近.1,.2,.3等。这仍然有问题,但总比什么都没有要好。
    2. 将数字表示为整数,只需“记住”整数是十分之一的数字,而不是一的数字。

    银行应用程序通常使用第二种技术,以消除零头和舍入错误的可能性。

        3
  •  0
  •   JYelton Melchior Blausand    14 年前

    下面是我根据TimCoker的答案实现的扩展方法:

        private static float? ValidateDecimal41(this float? f)
        {
            if (!f.HasValue) return f;
            float rounded = (float)Math.Round((float)f, 1);
            if (rounded >= 0 && rounded <= 999.9) return rounded;
            else return null;
        }
    

    这使我能够:

    • 继续接受并存储空值,
    • 将被视为超出相关值界限的任何值转换为空值,以及
    • 四舍五入到一个小数点,以避免SQL中潜在的精度错误