oracle number类型默认为0,ORACLE_NUMBER类型Scale为0引发的问题

摘要: 今天遇到了一个很有意思的NUMBER类型Scale引发的问题,我用一个简单的测试用例来展示一下这个案例。假如有个TEST的表,有个字段类型为NUMBER,我插入下面两条数据 CREATE TABLE TEST (      Category VARCHAR(12),      QTY  NUM

今天遇到了一个很有意思的NUMBER类型Scale引发的问题,我用一个简单的测试用例来展示一下这个案例。假如有个TEST的表,有个字段类型为NUMBER,我插入下面两条数据

CREATE TABLE TEST

(

Category VARCHAR(12),

QTY  NUMBER

)

INSERT INTO TEST

SELECT 'M', 12 FROM DUAL UNION ALL

SELECT 'C', 0.99999999999999999 FROM DUAL;

COMMIT;

此时直接查询表TEST,发现QTY字段值为1,

8f2c765b8ccee907d84a54188de3b9ec.png

使用下面SQL语句统计时,SUM_QTY的值也是1

d45e0594b950bac0438aef3f3e1646c3.png

但是如果在游标里面获取该值的时候,你会发现字段QTY的值为原来的值.99999999999999999

DECLARE  CURSOR c_test

IS

SELECT Category, SUM(QTY) AS SUM_QTY FROM TEST

GROUP BY Category;

c_row c_test%rowtype;

begin

for c_row in c_test loop

dbms_output.put_line('the result is ' || c_row.SUM_QTY);

end loop;

end;

the result is .99999999999999999

the result is 12

为什么会有这个奇怪的现象呢? 其实我们遇到这个案例时是按这个顺序反着的,最后发现是插入的值是0.999999999. 当然这个过程是非常纠结的。远非我们例子里面那样轻松简单。要解释这个问题,要从NUMBER类型说起,NUMBER (p, s) 声明一个定点数 p(precision)为精度,s(scale)表示小数点右边的数字个数,精度最大值为38,scale的取值范围为-84到127。 Number(p) 表示声明一个整数相当于Number(p, 0), 如果不指定p和s,NUMBER类型,它的默认精度值为38, 默认的scale值为0. 所以出现在SELECT语句中,一个值为.99999999999999999 的显示为1,但是在游标中,它获取的是这个字段的真实值,没有经过转化。所以出现了这个稀奇古怪的问题。虽然事后理顺过后觉得非常简单,但是当时不了解情 况下,觉得非常不可思议,非常纳闷!

另外附上定点数的精度(p)和刻度(s)遵循以下规则:

 当一个数的整数部分的长度 > p-s 时,Oracle就会报错

 当一个数的小数部分的长度 > s 时,Oracle就会舍入。

 当s(scale)为负数时,Oracle就对小数点左边的s个数字进行舍入。

 当s > p 时, p表示小数点后第s位向左最多可以有多少位数字,如果大于p则Oracle报错,小数点后s位向右的数字被舍入

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ORACLE中的数据类型.doc 当你在数据库中创建数据表的时候,你需要定义表中所有字段的类型ORACLE有许多种数据类型以满足你的需要。数据类型大约分为:character, number, date, LOB, 和RAW等类型。虽然ORACLE8i也允许你自定义数据类型,但是它们是最基本的数据类型。在下面的文章中你将了解到他们在oracle 中的用法、限制以及允许值。 l Character 数据类型 Character 数据类型用来存储字母数字型数据。当你在oracle 中定义一个character 数据时,通常需要制定字段的长度,它是该字段的最大长度。ORACLE提供以下几种character 数据类型: CHAR(<size>) CHAR数据类型是一种有固定长度和最大长度的字符串。存储在数据类型为CHAR字段中的数据将以空格的形式补到最大长度。长度定义在1——2000字节之间。 当你创建一个CHAR型字段,数据库将保证在这个字段中的所有数据是定义长度,如果某个数据比定义长度短,那么将用空格在数据的右边补到定义长度。如果长度大于定义长度将会触发错误信息。 VARCHAR(<size>) varchar型数据是varchar2型数据的快照。 VARCHAR2(<size>) varchar2数据类型是一种可变长度的、有最大长度的字母数字型数据。Varchar2类型的字段长度可以达到4000字节,Varchar2类型的变量长度可以达到32676字节。 一个空的varchar2(2000)字段和一个空的varchar2(2)字段所占用的空间是一样的。 NCHAR(<size>) 和 NVARCHAR2(<size>) NCHAR(<size>) 和 NVARCHAR2(<size>)数据类型分别与CHAR(<size>) 和 VARCHAR2(<size>)类型是相同的,只不过它们用来存储NLS(National Language Support)数据。 LONG LONG 数据类型是一个遗留下来的而且在将来不会被支持的数据类型。它将被LOB(Large Object)数据类型所代替。 比较规则 Varchar2和char数据类型根据尾部的空格有不同的比较规则。对Char型数据,尾部的空格将被忽略掉,对于Varchar2型数据尾部带空格的数据排序比没有空格的要大些。比如: Char 型数据: ‘YO’=‘YO ’ Varchar2型数据: ‘YO’<’YO ’

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值