【问题标题】:How can an Oracle NUMBER have a Scale larger than the Precision?Oracle NUMBER 的 Scale 怎么可能大于 Precision?
【发布时间】:2010-03-18 21:30:29
【问题描述】:

文档指出:“精度范围可以从 1 到 38。比例范围可以从 -84 到 127”。

尺度怎么可能大于精度? Scale 的范围不应该是 -38 到 38 吗?

【问题讨论】:

    标签: oracle precision scale


    【解决方案1】:

    根据 Oracle 文档:

    比例可以大于精度,最常见的是使用 ex 表示法(其中小数部分可能很大)。当比例大于精度时,精度指定小数点右侧的最大有效位数。例如,定义为NUMBER(4,5) 的列要求小数点后的第一个数字为零,并将所有值四舍五入超过小数点后的第五个数字。

    这是我的看法:

    • Precision 大于Scale(例如NUMBER(8,5))时,没问题,这很简单。 Precision 表示数字共有 8 位,其中 5 位在小数部分 (.→),因此整数部分 (←.) 将有 3 位。这很容易。
    • 当您看到 Precision 小于 Scale(例如 NUMBER(2, 5))时,这意味着 3 件事:

      • 数字没有任何整数部分,只有小数部分。所以整数部分的 0 不计入计算中,你说的是 0.12345 而不是 0.12345。事实上,如果你在整数部分只指定 1 位,它总是会返回错误。
      • Scale 表示数字将具有的小数部分的总位数。 5 在这种情况下。所以它可以是 .12345 或 .00098,但总共不超过 5 位。
      • 小数部分分为两部分,有效数字和零。有效数字由Precision 指定,最小的零数等于 (Scale - Precision)。示例:

      here 数字的小数部分必须至少有 3 个零。后跟 2 个有效数字(也可以是零)。所以 3 个零 + 2 个有效数字 = 5,即 Scale 数字。

    简而言之,当您看到例如 NUMBER(6,9) 时,这告诉我们小数部分总共有 9 位数字,以强制性的 3 个零开头,后跟 6 个数字。

    这里有一些例子:

    SELECT CAST(.0000123 AS NUMBER(6,9)) FROM dual;   -- prints: 0.0000123; .000|012300
    SELECT CAST(.000012345 AS NUMBER(6,9)) FROM dual; -- prints: 0.0000123; .000|012345
    SELECT CAST(.123456 AS NUMBER(3,4)) FROM dual;    -- ERROR! must have a 1 zero (4-3=1)
    SELECT CAST(.013579 AS NUMBER(3,4)) FROM dual;    -- prints: 0.0136; max 4 digits, .013579 rounded to .0136
    

    【讨论】:

    • 这适用于其他 DBMS 吗?
    【解决方案2】:

    问题可能是为什么不呢? 试试下面的 SQL。

    select cast(0.0001 as number(2,5)) num, 
           to_char(cast(0.0001 as number(2,5))) cnum,
           dump(cast(0.0001 as number(2,5))) dmp
      from dual
    

    你看到的是你可以持有小数字是那种结构 可能不会经常需要它,但我确信在某个地方有人存储非常精确但非常小的数字。

    【讨论】:

    • @Gary,谢谢你的例子。文档说精度是总位数,比例是小数点后的数字。那么如何 NUMBER(2, 5) 的“总位数”为 2,但在小数点后存储 5 位?
    • 我认为是这样的:NUMBER(2,5) 例如0.00012 = 1.2E-4 或类似的东西
    【解决方案3】:

    感谢大家的回答。看起来精度是有效位数。

     select cast(0.000123 as number(2,5)) from dual
    

    结果:

    .00012
    

    在哪里

     select cast(0.00123 as number(2,5)) from dual
    

     select cast(0.000999 as number(2,5)) from dual
    

    两者都导致:

    ORA-01438: value larger than specified precision allowed for this column
    

    由于四舍五入,第二个。

    【讨论】:

      【解决方案4】:

      根据 Oracle 文档:

      比例可以大于精度,最常见于使用 e 表示法时。当比例大于精度时,精度指定小数点右侧的最大有效位数。例如,定义为 NUMBER(4,5) 的列要求小数点后的第一个数字为零,并将所有值四舍五入超过小数点后的第五个数字。

      最好指定定点数列的比例和精度,以便对输入进行额外的完整性检查。指定比例和精度不会强制所有值都为固定长度。如果一个值超过了精度,那么 Oracle 会返回一个错误。如果某个值超出了范围,则 Oracle 将其四舍五入。

      【讨论】:

        【解决方案5】:

        Scale大于Precision的情况可以这样概括:

        小数点右边的位数 = 刻度

        小数点右边的最小零个数 = 比例 - 精度

        --this will work 
        select cast(0.123456 as number(5,5)) from dual;
        

        返回 0.12346

        -- but this
        select cast(0.123456 as number(2,5)) from dual;
        --will return "ORA-1438 value too large".  
        --It will not return err with at least 5-2 = 3 zeroes:
        select cast(0.000123456 as number(2,5)) from dual;
        

        返回 0.00012

        -- and of course this will work too
        select cast(0.0000123456 as number(2,5)) from dual;
        

        返回 0.00001

        【讨论】:

          【解决方案6】:

          嗯,据我了解,精度是位数。
          maximum precision of 126 binary digits, which is roughly equivalent to 38 decimal digits

          在 oracle 中,您有类型 NUMBER(precision,scale),其中精度是总位数,比例是小数点右边的位数。刻度可以省略,但它意味着零。可以未指定精度(使用即 NUMBER(*,10)) - 这意味着总位数是需要的,但右边有 10 位数

          如果小数位数小于零,则该值将四舍五入为小数点后scale 位。
          我认为如果您保留的小数点右边的数字比整数中的数字多,这意味着像 0.00000000123456 但我不是 100% 确定。

          【讨论】:

          • Tobias:如果比例大于精度(例如NUMBER(1,2)),那么我们在尝试对其分配一个值时得到ORA-06502: PL/SQL: numeric or value error string - 而不是在时定义它...
          猜你喜欢
          • 2016-04-04
          • 1970-01-01
          • 2020-03-29
          • 2011-05-17
          • 1970-01-01
          • 2019-05-02
          • 1970-01-01
          • 2011-01-27
          • 2018-05-28
          相关资源
          最近更新 更多