Oracle NUMBER 的 Scale 怎么可能大于 Precision?
Posted
技术标签:
【中文标题】Oracle NUMBER 的 Scale 怎么可能大于 Precision?【英文标题】:How can an Oracle NUMBER have a Scale larger than the Precision? 【发布时间】:2010-03-18 21:30:29 【问题描述】:文档指出:“精度范围可以从 1 到 38。比例范围可以从 -84 到 127”。
尺度怎么可能大于精度? Scale 的范围不应该是 -38 到 38 吗?
【问题讨论】:
【参考方案1】:根据 Oracle 文档:
比例可以大于精度,最常见的是使用 ex 表示法(其中小数部分可能很大)。当比例大于精度时,精度指定小数点右侧的最大有效位数。例如,定义为
NUMBER(4,5)
的列要求小数点后的第一个数字为零,并将所有值四舍五入超过小数点后的第五个数字。
这是我的看法:
当Precision
大于Scale(例如NUMBER(8,5)
)时,没问题,这很简单。 Precision
表示数字共有 8 位,其中 5 位在小数部分 (.→),因此整数部分 (←.) 将有 3 位。这很容易。
当您看到 Precision
小于 Scale
(例如 NUMBER(2, 5)
)时,这意味着 3 件事:
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
- 而不是在时定义它...以上是关于Oracle NUMBER 的 Scale 怎么可能大于 Precision?的主要内容,如果未能解决你的问题,请参考以下文章