有一个列具有data_type编号,data_length 22,data_precision 5,data_scale 1。这意味着它可以容纳最大值,就像9999.9 Requirement is -我必须使该列容纳最大值为9999.99,即data_precision 6和data_scale 2。我想知道data_length在这里的意义是什么?我是否需要改变它的精度和比例,或者它可以容纳9999.99,而不作任何改变,因为它的长度已经是22。
发布于 2020-07-03 12:41:26
考虑到Oracle的定义:
DATA_LENGTH是列的长度(以字节为单位)。DATA_PRECISION是数字数据类型的十进制精度,对于浮点数据类型是二进制精度,对于所有其他数据类型是null。DATA_SCALE是数字中小数点右边的数字。
让我们举一个例子:
SQL> create table check_size ( c1 number, c2 number(6) , c3 number(6,3) );
Table created.
SQL> set lines 200
SQL> r
1 SELECT COLUMN_NAME,
2 DATA_TYPE,
3 DATA_LENGTH,
4 DATA_PRECISION,
5 DATA_SCALE
6 FROM ALL_TAB_COLS
7 WHERE OWNER='TEST'
8* AND TABLE_NAME = 'CHECK_SIZE'
COLUMN_NAME DATA_TYPE DATA_LENGTH DATA_PRECISION DATA_SCALE
------------------------------ ------------------------------ ----------- -------------- ----------
C1 NUMBER 22
C2 NUMBER 22 6 0
C3 NUMBER 22 6 3正如你所看到的,data_length总是22岁。这是因为数字是以数据包的形式存储的,所以字典将始终显示22,但我可以插入大于22位的数字。
SQL> insert into check_size values ( 99999999999999999999999999999999999999999999 , 999999, 999.99 );
1 row created.
SQL> select dump(c1) as content from check_size ;
CONTENT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Typ=2 Len=2: 215,2但是,在您的例子中,您说的是数据精度5和数据比例尺1,所以让我们截断表并修改列:
SQL> truncate table check_size ;
Table truncated.
SQL> alter table check_size modify c3 number ( 5,1 );
Table altered.
SQL> insert into check_size values ( 99999999999999999999999999999999999999999999 , 999999, 99 );
1 row created.
SQL> insert into check_size values ( 99999999999999999999999999999999999999999999 , 999999, 9999.9 );
1 row created.
SQL> insert into check_size values ( 99999999999999999999999999999999999999999999 , 999999, 9999.99 );
insert into check_size values ( 99999999999999999999999999999999999999999999 , 999999, 9999.99 )
*
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column总之,使用数据比例尺5和数据精度1,可以将任何类型的数字存储到这个最大精度+比例尺。所以我可以存储9999.9和99 (比例和精度是咨询的),但我不能9999.99,因为我的比例尺是1,这里的数字有2个小数点。
希望它能澄清你的问候
发布于 2020-07-03 15:03:43
因为您的列的数据长度是(22,5),所以它也可以容纳(6,2)。如果您仍然希望针对任何技术/业务需求将数据长度限制为(6,2),则可以使用下面的alter语句来修改您的列。
alter table table_name modify column_name number(6, 2);发布于 2021-11-05 21:30:58
基本上,DATA_LENGTH对数值列没有意义。它适用于CHAR/VARCHAR类型。如果类型是数字的,只需查看DATA_PRECISION和DATA_SCALE。
对于数值类型,DATA_LENGTH是以字节为单位的最大存储大小。然而,与CHAR/VARCHAR类型不同的是,类型参数(在本例中是精度和缩放)没有被考虑:值22是为所有数字类型设置的,即使它们受到如此的限制,以至于它们实际上永远无法达到22字节。
我相信价值22的原因如下:
可以使用VSIZE函数检查存储长度:
SELECT VSIZE(-12345678901234567890123456789012345678)
FROM DUAL结果是21 (如预期的)。没有减号,是20。
不幸的是,我无法通过增加更多的数字来获得22的值。如果再加一个数字,则得到一个正数的值21:
SELECT VSIZE(123456789012345678901234567890123456789)
FROM DUAL这个看起来不错。但是,如果现在使这个数字为负数,结果仍然是21 (而对于我测试的所有较小的数字,使数字负数增加了一个字节)。我使用了Oracle 18c XE。
https://stackoverflow.com/questions/62715325
复制相似问题