Oracle支持的各种数字数据类型的声明大致如下:
create table numbers (
number_u number,
numeric_u numeric,
decimal_u decimal,
integer_u integer,
smallint_u smallint,
number_p number(9),
numeric_p numeric(9),
decimal_p decimal(9),
number_ps number(9,2),
numeric_ps numeric(9,2),
decimal_ps decimal(9,2),
number_s number(*,2),
numeric_s numeric(*,2),
decimal_s decimal(*,2),
float_u float,
float_p float(30),
real_u real,
double_u double precision);
select column_name, data_type, data_precision, data_scale
from user_tab_columns where table_name = 'NUMBERS';
/
COLUMN_NAME DATA_T DATA_PRECISION DATA_SCALE
------------------------------ ------ -------------- ----------
NUMBER_U NUMBER
NUMERIC_U NUMBER 0
DECIMAL_U NUMBER 0
INTEGER_U NUMBER 0
SMALLINT_U NUMBER 0
NUMBER_P NUMBER 9 0
NUMERIC_P NUMBER 9 0
DECIMAL_P NUMBER 9 0
NUMBER_PS NUMBER 9 2
NUMERIC_PS NUMBER 9 2
DECIMAL_PS NUMBER 9 2
NUMBER_S NUMBER 2
NUMERIC_S NUMBER 2
DECIMAL_S NUMBER 2
FLOAT_U FLOAT 126
FLOAT_P FLOAT 30
REAL_U FLOAT 63
DOUBLE_U FLOAT 126
对于NUMBER, NUMERIC,DECIMAL列,scale声明必须支持的小数位数,超出地将被截掉。并且必须位于-84到127之间,对于INTEGER和SMALLINT列,隐示为0。对于仅仅声明了precision的NUMBER, NUMERIC,DECIMAL列,其默认为0。
对于NUMBER, NUMERIC,DECIMAL列,precision表示了最大支持的有效数字位数,并且必须位于1-38之间。如果小数点左边的位数大于precision-scale,那么将返回"ORA-01438: 值大于为此列指定的允许精度"错误。如果没有声明精度,存储的位数受具体的实施限制。
对于单独的NUMBER,Oracle实施了所有的声明格式。
FLOAT, REAL和DOUBLE PRECISION的区别是ANSI要求它们的精度根据二进制位数而不是数字位数来声明。FLOAT默认为126位,REAL和DOUBLE PRECISION分别为63和126位。Oracle使用number实施了这些声明,可以通过dump函数验证存储:
select dump(number_u), dump(float_u) from numbers;
二进制精度列在USER_TAB_COLUMNS家族视图中仅存储为FLOAT以保持它们精度的语义。
Oracle在实际操作这类数据时,实际上用下一个最大的数字精度代替。Oracle使用一个字节存储两位数字使用以下公式:
decimal_precision = ceil(binary_precision * log(10, 2))
SQL> create table float_check (f float(2));
Table created.
SQL> insert into float_check values (7);
1 row created.
SQL> insert into float_check values (11);
1 row created.
SQL> insert into float_check values (999);
SQL> select * from float_check;
F
----
7
10
1000
因此数据库应用程序应该显示截断数据,而不应依赖于数据类型的精度隐示进行截断。
阅读(4442) | 评论(0) | 转发(0) |