转--Oracle数据类型及存储方式【C】
生活随笔
收集整理的這篇文章主要介紹了
转--Oracle数据类型及存储方式【C】
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
第二部分 數(shù)值類型
§ 2.1? number
Number類型是oralce的數(shù)值類型,存儲的數(shù)值的精度可以達到38位。Number是一種變長類型,長度為0-22字節(jié)。取值范圍為:10e-130 – 10e 126(不包括)
Number(p,s)
P和s都是可選的。
P指精度(precision),即總位數(shù)。默認情況下精度為38。精度的取值范圍為1~38.
S指小數(shù)位(scale).小數(shù)點右邊的位數(shù)。小數(shù)點位數(shù)的合法值為-48~127。小數(shù)位的默認值由精度來決定。如果沒有指定精度,小數(shù)位默認為最大的取值區(qū)間.如果指定了精度,沒有指定小數(shù)位。小數(shù)位默認為0(即沒有小數(shù)位).
精度和小數(shù)位不會影響數(shù)據(jù)如何存儲,只會影響允許哪些數(shù)值及數(shù)值如何舍入。
1.新建一個表
SQL> create table test_number(col_number number(6,2));
Table created
2.插入一些不同的數(shù)據(jù)
SQL> insert into test_number values(-1);
1 row inserted
SQL> insert into test_number values(0);
1 row inserted
SQL> insert into test_number values(1);
1 row inserted
SQL> insert into test_number values(2);
1 row inserted
SQL> insert into test_number values(11.00);
1 row inserted
SQL> insert into test_number values(11.11);
1 row inserted
SQL> insert into test_number values(1234.12);
1 row inserted
SQL> insert into test_number values(-0.1);
1 row inserted
SQL> insert into test_number values(-11.11);
1 row inserted
SQL> insert into test_number values(-1234.12);
1 row inserted
SQL> commit;
Commit complete
3.查看結(jié)果
SQL> select * from test_number;
COL_NUMBER
----------
???? -1.00
????? 0.00
????? 1.00
????? 2.00
???? 11.00
???? 11.11
?? 1234.12
???? -0.10
??? -11.11
? -1234.12
10 rows selected
5. 查看存儲結(jié)構(gòu)
SQL> select col_number, dump(col_number) from test_number;
COL_NUMBER DUMP(COL_NUMBER)
---------- --------------------------------------------------------------------------------
???? -1.00 Typ=2 Len=3: 62,100,102
????? 0.00 Typ=2 Len=1: 128
????? 1.00 Typ=2 Len=2: 193,2
????? 2.00 Typ=2 Len=2: 193,3
???? 11.00 Typ=2 Len=2: 193,12
???? 11.11 Typ=2 Len=3: 193,12,12
?? 1234.12 Typ=2 Len=4: 194,13,35,13
???? -0.10 Typ=2 Len=3: 63,91,102
??? -11.11 Typ=2 Len=4: 62,90,90,102
? -1234.12 Typ=2 Len=5: 61,89,67,89,102
10 rows selected
由此可見:
Number類型的內(nèi)部編碼為:2
根據(jù)每一行的len值可以看出,number是一個變長類型。不同的數(shù)值占用不同的空間。
如果指定了精度,顯示結(jié)果與精度相關(guān)。
就像我插入語句寫為
insert into test_number values(0);
但是顯示結(jié)果為:0.00
如果數(shù)值是負數(shù),在最后一位上填充一個補碼102.即表示該數(shù)值為負數(shù)。
0是一個特殊的值,它在oracle中存儲為128.
第一位為標志位。以128為比較。如果數(shù)值大于128,則它大于0。如果小于128小于0。
-1的內(nèi)部存儲為:
-1.00 Typ=2 Len=3: 62,100,102
最后一位是102,是一個負數(shù)。
第一位小于128,所以小于10.
除了第一位標志位外,其它的都是數(shù)值為了。
如果該值是一個正數(shù)。每一位的存儲值減1為每一位的實際值。
1.0的存儲結(jié)構(gòu)為:
1.00 typ=2 Len=2: 193,2
實值上1.00的存儲結(jié)果與1相同。
第一位193為標志位,大于128,大于0.
第二位為數(shù)值為,因為是正數(shù),實際值為存儲值減1。2-1 = 1。
如是該值是一個負數(shù),每一位的實際值為101 減去存儲的值。
-1.00的存儲結(jié)構(gòu)為:
-1.00 Typ=2 Len=3: 62,100,102
最后一位102為補位。
第一位62為標志位,小于128。實際值小于0.
第二位為數(shù)值為,因為是負數(shù)。實際值為:101 – 100? =1.
§2.2 小數(shù)位在哪里?
從上面的存儲結(jié)果看,對小數(shù)存儲時,它并沒有一個小數(shù)的標志位。但是它實際上是由第一位標志位,和數(shù)值位(第二位)來決定的。
當(dāng)存儲的數(shù)是一個正數(shù),該數(shù)值的前幾位為:第一位 * power(100 , (標志位 - 193));
當(dāng)存儲的數(shù)是一個負數(shù),該數(shù)值的前幾位為:第一位 * power(100,(62 – 標志位));
11.11的存儲結(jié)果為:
11.11 Typ=2 Len=3: 193,12,12
第一位數(shù)值位為:12 實際數(shù)值為11
標志位為:193
12 * power(100, (193- 193);
?? 100的零次方為1.
12 乘1 等于12.
所以這個數(shù)的前幾位為:12。從這后面就是小數(shù)了。
1234.12的存儲結(jié)構(gòu)為:
1234.12 Typ=2 Len=4: 194,13,35,13
第一位數(shù)值位為:13,實際值為12
標志位為:193
13 * power(100,(194-193)) = 1300
所以前四位為整數(shù)位,后面的為小數(shù)位。
-0.10的存儲結(jié)構(gòu)為:
-0.10 Typ=2 Len=3: 63,91,102
標志位為:63
第一位數(shù)值為:91 ,實際值為:10
91 * (100,(62-63)) =-9100.
所以小數(shù)位在91之前。
-1234.12的存儲結(jié)構(gòu)為:
-1234.12 Typ=2 Len=5: 61,89,67,89,102
標志位為:61
第一位數(shù)值為:89
89*(100,(62-61)) =8900
所以小數(shù)位在67之后。
§2.3 number的精度和小數(shù)位
Number類型的精度最多可是38位。小數(shù)位-84--127位。
SQL> create table test_number1(col_number number(39));
create table test_number1(col_number number(39))
ORA-01727: numeric precision specifier is out of range (1 to 38)
指定小數(shù)位時,精度只能是1-38。不能是0
SQL> create table test_number1(col_number number(0,127));
create table test_number1(col_number number(0,127))
ORA-01727: numeric precision specifier is out of range (1 to 38)
SQL> create table test_number1(col_number number(1,128));
create table test_number1(col_number number(1,128))
ORA-01728: numeric scale specifier is out of range (-84 to 127)
精度與小數(shù)位的關(guān)系。精度并不是小數(shù)位加整數(shù)位之和。
我們先看看小數(shù)位為0的情況。
SQL> create table test_number1(col_char varchar2(200), col_num number(10));
Table created
Number(10).只定義了精度,小數(shù)位為0.
看看它可以存放的數(shù)據(jù)。
SQL> insert into test_number1 values('9999999999',9999999999);
1 row inserted
插入了10個9,沒有問題,再插入多一位看看
SQL> insert into test_number1 values('99999999991',99999999991);
insert into test_number1 values('99999999991',99999999991)
ORA-01438: value larger than specified precision allowed for this column
報錯了,精度不夠。
再看看能不能再插入小數(shù)?
SQL> insert into test_number1 values('0.9',0.9);
1 row inserted
SQL> select * from test_number1;
Col_char COL_NUM
-------------------- --------------
9999999999 9999999999
0.9 ???????????? 1
注意插入數(shù)值0.9后,存儲為1.這就是小數(shù)位的作用。在哪里進行舍入。
帶小數(shù)位和精度的情況。
SQL> create table test_number2(col_char varchar(20),col_num number(1,3));
Table created
精度是1,小數(shù)位是3.
可見,精度不是小數(shù)位加整數(shù)位了。但是精度和小數(shù)位倒底什么關(guān)系呢?
SQL> insert into test_number2 values('0.111',0.111);
insert into test_number2 values('0.111',0.111)
ORA-01438: value larger than specified precision allowed for this column
插入3位小數(shù),0.111竟然報錯了,說精度不夠。
SQL> insert into test_number2 values('0.001',0.001);
1 row inserted
插入0.001時,成功了。
SQL> insert into test_number2 values('0.001',0.0015);
1 row inserted
插入0.0015也成功了。
看看插入的值。
SQL> select * from test_number2;
COL_CHAR???????????? COL_NUM
-------------------- -------
0.001????????????????? 0.001
0.0015???????????????? 0.002
需要注意的是0.0015被舍入為0.002
精度大于小數(shù)位
SQL> create table test_number3 (col_char varchar(20), col_number number(5,3));
Table created
SQL> insert into test_number3 values('99.899',99.899);
1 row inserted
SQL> insert into test_number3 values('99.999',99.999);
1 row inserted
SQL> insert into test_number3 values('99.9999',99.9999);
insert into test_number3 values('99.9999',99.9999)
ORA-01438: value larger than specified precision allowed for this column
注意,當(dāng)插入99.9999時,系統(tǒng)報錯。因為小數(shù)位為3位。第四位小數(shù)位是9,于是往前入。最終變成100.000.就已經(jīng)超過了精度。
Number(5,3)可存儲的數(shù)值最大為99.999.
現(xiàn)在終于有點明白小數(shù)位與精度的關(guān)系了。
number(38,127)
可以存儲的最大小數(shù)為:127位小數(shù),最后38為9.
即:0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099999999999999999999999999999999999999
小數(shù)位為負數(shù)。
我們從前面知道,小數(shù)位的取值為-48 ~127
為什么小數(shù)位會為負數(shù)?這有點怪異了。像上面的number(5,3)將值舍入為最接近0.001
Number(5,-3)就是將值舍入為最接近的1000
SQL> create table test_number5 (col_char varchar(20), col_num number(5,-3));
Table created
插入值10999
SQL> insert into test_number5 values('10999',10999);
1 row inserted
查看一下結(jié)果
SQL> select * from test_number5;
COL_CHAR???????????? COL_NUM
-------------------- -------
10999????????????????? 11000
存儲的結(jié)果為:11000
當(dāng)小數(shù)部分為負數(shù)時,是對小數(shù)部分進行舍入。
那么精度在這時起到什么作用呢?與小數(shù)位又有什么關(guān)系?
SQL> insert into test_number5 values('111111111',111111111);
insert into test_number5 values('111111111',111111111)
ORA-01438: value larger than specified precision allowed for this column
插入9個1時,報錯精度不夠。
SQL> insert into test_number5 values('11111111',11111111);
1 row inserted
插入8個1時,正確插入。
我們看看它的結(jié)果,看它是怎么舍入的。
SQL> select * from test_number5;
COL_CHAR???????????? COL_NUM
-------------------- -------
11111111???????????? 11111000
結(jié)果是1111100而不是1111100
無限接近1000,就是從百位開始進行四舍五入,后面的值全部為0。
所以看出number(5,-3)可存儲的最大值為:99999000
SQL> insert into test_number5 values('99999499.999999',99999499.999999);
1 row inserted
SQL> select * from test_number5;
COL_CHAR???????????? COL_NUM
-------------------- -------
99999999???????????? 99999000
99999499.999999????? 99999000
現(xiàn)在應(yīng)該明白了精度和小數(shù)位的關(guān)系了吧。
小數(shù)位告訴系統(tǒng)保留多少位小數(shù),從哪里開始舍入。
精度舍入后,從舍入的位置開始,數(shù)值中允許有多少位。
§2.4? binary_float 和binary_double
這兩種類型是oracle 10g新引進的數(shù)值類型。在oracle 10g之前是沒有這兩種類型的。
Number類型是由oracle軟件支持的類型。而浮點數(shù)用于近似數(shù)值。但是它浮點數(shù)允許由在硬盤上(CPU,芯片)上執(zhí)行運行。而不是在oracel進程中運算。如果希望在一個科學(xué)計算中執(zhí)行實數(shù)處理,依賴于硬件的算術(shù)運算速度要快得多。但是它的精度卻很小。如果希望用來存儲金融數(shù)值,則必須用number.
BINARY_FLOAT是一種IEEE固有的單精度浮點數(shù)。可存儲6位精度,取值范圍在~±1038.25的數(shù)值。
BINARY_DOUBLE是一種IEEE固有的雙精度浮點數(shù)。可存儲12位精度。取值范圍在~±10308.25的數(shù)值
SQL> create table test_floatdouble(col_number number, col_float binary_float, col_double binary_double);
Table created
SQL> insert into test_floatdouble values(9876543210.0123456789,9876543210.0123456789,9876543210.0123456789);
1 row inserted
2 SQL> select to_char(col_number), to_char(col_float), to_char(col_double) from test_floatdouble;
3
4 TO_CHAR(COL_NUMBER)????????????????????? TO_CHAR(COL_FLOAT)?????????????????????? TO_CHAR(COL_DOUBLE)
5 ---------------------------------------- ---------------------------------------- ----------------------------------------
6 9876543210.0123456789??????????????????? 9.87654349E+009????????????????????????? 9.8765432100123463E+009
由此可見,binary_float無法表示這個數(shù)。Binary_float和binary_double無法用于對精度要求高的數(shù)據(jù)。
SQL> select dump(col_float)from test_floatdouble;
DUMP(COL_FLOAT)
--------------------------------------------------------------------------------
Typ=100 Len=4: 208,19,44,6
BINARY_FLOAT 類型編碼為100
Len=4 占用4個字節(jié)。它是采用固定字節(jié)進行存儲的。
SQL> select dump(col_double)from test_floatdouble;
DUMP(COL_DOUBLE)
--------------------------------------------------------------------------------
Typ=101 Len=8: 194,2,101,128,183,80,25,73
BINARY_DOUBLE 類型編碼為101
Leng= 8 占用8個字節(jié)。也是采用固定字節(jié)進行存儲。
注意:number 類型使用的CPU時間是浮點數(shù)類型的50倍。浮點數(shù)是數(shù)值的一個近似值,精度在6-12位之間。從Number類型得到的結(jié)果要比從浮點數(shù)得到的結(jié)果更精確。但在對科學(xué)數(shù)據(jù)進行數(shù)據(jù)挖掘和進行復(fù)雜數(shù)值分析時,精度的損失是可以接受的,還會帶來顯著的性能提升。
這時需要使用內(nèi)置CAST函數(shù),對NUMBER類型執(zhí)行一種實時的轉(zhuǎn)換,在執(zhí)行復(fù)雜數(shù)學(xué)運算之前先將其轉(zhuǎn)換為一種浮點數(shù)類型。CPU使用時間就與固有浮點類型使用的CPU時間非常接近了。
Select ln(cast(number_col as binary_double)) from test_number.
§2.5 Oracle在語法上還支持的數(shù)值數(shù)據(jù)類型
NUMERIC(p,s):完全映射到NUMBER(p,s)。如果p未指定,則默認為38.
DECIMAL(p,s)或DEC(p,s):同NUMERIC(p,s).
INTEGER或int:完全映射至NUMBER(38)
SMALLINT:完全映射至NUMBER(38)
FLOAT(b):映射至NUMBER
DOUBLE PRECISION:映射到NUMBER
REAL:映射到NUMBER.
§ 2.1? number
Number類型是oralce的數(shù)值類型,存儲的數(shù)值的精度可以達到38位。Number是一種變長類型,長度為0-22字節(jié)。取值范圍為:10e-130 – 10e 126(不包括)
Number(p,s)
P和s都是可選的。
P指精度(precision),即總位數(shù)。默認情況下精度為38。精度的取值范圍為1~38.
S指小數(shù)位(scale).小數(shù)點右邊的位數(shù)。小數(shù)點位數(shù)的合法值為-48~127。小數(shù)位的默認值由精度來決定。如果沒有指定精度,小數(shù)位默認為最大的取值區(qū)間.如果指定了精度,沒有指定小數(shù)位。小數(shù)位默認為0(即沒有小數(shù)位).
精度和小數(shù)位不會影響數(shù)據(jù)如何存儲,只會影響允許哪些數(shù)值及數(shù)值如何舍入。
1.新建一個表
SQL> create table test_number(col_number number(6,2));
Table created
2.插入一些不同的數(shù)據(jù)
SQL> insert into test_number values(-1);
1 row inserted
SQL> insert into test_number values(0);
1 row inserted
SQL> insert into test_number values(1);
1 row inserted
SQL> insert into test_number values(2);
1 row inserted
SQL> insert into test_number values(11.00);
1 row inserted
SQL> insert into test_number values(11.11);
1 row inserted
SQL> insert into test_number values(1234.12);
1 row inserted
SQL> insert into test_number values(-0.1);
1 row inserted
SQL> insert into test_number values(-11.11);
1 row inserted
SQL> insert into test_number values(-1234.12);
1 row inserted
SQL> commit;
Commit complete
3.查看結(jié)果
SQL> select * from test_number;
COL_NUMBER
----------
???? -1.00
????? 0.00
????? 1.00
????? 2.00
???? 11.00
???? 11.11
?? 1234.12
???? -0.10
??? -11.11
? -1234.12
10 rows selected
5. 查看存儲結(jié)構(gòu)
SQL> select col_number, dump(col_number) from test_number;
COL_NUMBER DUMP(COL_NUMBER)
---------- --------------------------------------------------------------------------------
???? -1.00 Typ=2 Len=3: 62,100,102
????? 0.00 Typ=2 Len=1: 128
????? 1.00 Typ=2 Len=2: 193,2
????? 2.00 Typ=2 Len=2: 193,3
???? 11.00 Typ=2 Len=2: 193,12
???? 11.11 Typ=2 Len=3: 193,12,12
?? 1234.12 Typ=2 Len=4: 194,13,35,13
???? -0.10 Typ=2 Len=3: 63,91,102
??? -11.11 Typ=2 Len=4: 62,90,90,102
? -1234.12 Typ=2 Len=5: 61,89,67,89,102
10 rows selected
由此可見:
Number類型的內(nèi)部編碼為:2
根據(jù)每一行的len值可以看出,number是一個變長類型。不同的數(shù)值占用不同的空間。
如果指定了精度,顯示結(jié)果與精度相關(guān)。
就像我插入語句寫為
insert into test_number values(0);
但是顯示結(jié)果為:0.00
如果數(shù)值是負數(shù),在最后一位上填充一個補碼102.即表示該數(shù)值為負數(shù)。
0是一個特殊的值,它在oracle中存儲為128.
第一位為標志位。以128為比較。如果數(shù)值大于128,則它大于0。如果小于128小于0。
-1的內(nèi)部存儲為:
-1.00 Typ=2 Len=3: 62,100,102
最后一位是102,是一個負數(shù)。
第一位小于128,所以小于10.
除了第一位標志位外,其它的都是數(shù)值為了。
如果該值是一個正數(shù)。每一位的存儲值減1為每一位的實際值。
1.0的存儲結(jié)構(gòu)為:
1.00 typ=2 Len=2: 193,2
實值上1.00的存儲結(jié)果與1相同。
第一位193為標志位,大于128,大于0.
第二位為數(shù)值為,因為是正數(shù),實際值為存儲值減1。2-1 = 1。
如是該值是一個負數(shù),每一位的實際值為101 減去存儲的值。
-1.00的存儲結(jié)構(gòu)為:
-1.00 Typ=2 Len=3: 62,100,102
最后一位102為補位。
第一位62為標志位,小于128。實際值小于0.
第二位為數(shù)值為,因為是負數(shù)。實際值為:101 – 100? =1.
§2.2 小數(shù)位在哪里?
從上面的存儲結(jié)果看,對小數(shù)存儲時,它并沒有一個小數(shù)的標志位。但是它實際上是由第一位標志位,和數(shù)值位(第二位)來決定的。
當(dāng)存儲的數(shù)是一個正數(shù),該數(shù)值的前幾位為:第一位 * power(100 , (標志位 - 193));
當(dāng)存儲的數(shù)是一個負數(shù),該數(shù)值的前幾位為:第一位 * power(100,(62 – 標志位));
11.11的存儲結(jié)果為:
11.11 Typ=2 Len=3: 193,12,12
第一位數(shù)值位為:12 實際數(shù)值為11
標志位為:193
12 * power(100, (193- 193);
?? 100的零次方為1.
12 乘1 等于12.
所以這個數(shù)的前幾位為:12。從這后面就是小數(shù)了。
1234.12的存儲結(jié)構(gòu)為:
1234.12 Typ=2 Len=4: 194,13,35,13
第一位數(shù)值位為:13,實際值為12
標志位為:193
13 * power(100,(194-193)) = 1300
所以前四位為整數(shù)位,后面的為小數(shù)位。
-0.10的存儲結(jié)構(gòu)為:
-0.10 Typ=2 Len=3: 63,91,102
標志位為:63
第一位數(shù)值為:91 ,實際值為:10
91 * (100,(62-63)) =-9100.
所以小數(shù)位在91之前。
-1234.12的存儲結(jié)構(gòu)為:
-1234.12 Typ=2 Len=5: 61,89,67,89,102
標志位為:61
第一位數(shù)值為:89
89*(100,(62-61)) =8900
所以小數(shù)位在67之后。
§2.3 number的精度和小數(shù)位
Number類型的精度最多可是38位。小數(shù)位-84--127位。
SQL> create table test_number1(col_number number(39));
create table test_number1(col_number number(39))
ORA-01727: numeric precision specifier is out of range (1 to 38)
指定小數(shù)位時,精度只能是1-38。不能是0
SQL> create table test_number1(col_number number(0,127));
create table test_number1(col_number number(0,127))
ORA-01727: numeric precision specifier is out of range (1 to 38)
SQL> create table test_number1(col_number number(1,128));
create table test_number1(col_number number(1,128))
ORA-01728: numeric scale specifier is out of range (-84 to 127)
精度與小數(shù)位的關(guān)系。精度并不是小數(shù)位加整數(shù)位之和。
我們先看看小數(shù)位為0的情況。
SQL> create table test_number1(col_char varchar2(200), col_num number(10));
Table created
Number(10).只定義了精度,小數(shù)位為0.
看看它可以存放的數(shù)據(jù)。
SQL> insert into test_number1 values('9999999999',9999999999);
1 row inserted
插入了10個9,沒有問題,再插入多一位看看
SQL> insert into test_number1 values('99999999991',99999999991);
insert into test_number1 values('99999999991',99999999991)
ORA-01438: value larger than specified precision allowed for this column
報錯了,精度不夠。
再看看能不能再插入小數(shù)?
SQL> insert into test_number1 values('0.9',0.9);
1 row inserted
SQL> select * from test_number1;
Col_char COL_NUM
-------------------- --------------
9999999999 9999999999
0.9 ???????????? 1
注意插入數(shù)值0.9后,存儲為1.這就是小數(shù)位的作用。在哪里進行舍入。
帶小數(shù)位和精度的情況。
SQL> create table test_number2(col_char varchar(20),col_num number(1,3));
Table created
精度是1,小數(shù)位是3.
可見,精度不是小數(shù)位加整數(shù)位了。但是精度和小數(shù)位倒底什么關(guān)系呢?
SQL> insert into test_number2 values('0.111',0.111);
insert into test_number2 values('0.111',0.111)
ORA-01438: value larger than specified precision allowed for this column
插入3位小數(shù),0.111竟然報錯了,說精度不夠。
SQL> insert into test_number2 values('0.001',0.001);
1 row inserted
插入0.001時,成功了。
SQL> insert into test_number2 values('0.001',0.0015);
1 row inserted
插入0.0015也成功了。
看看插入的值。
SQL> select * from test_number2;
COL_CHAR???????????? COL_NUM
-------------------- -------
0.001????????????????? 0.001
0.0015???????????????? 0.002
需要注意的是0.0015被舍入為0.002
精度大于小數(shù)位
SQL> create table test_number3 (col_char varchar(20), col_number number(5,3));
Table created
SQL> insert into test_number3 values('99.899',99.899);
1 row inserted
SQL> insert into test_number3 values('99.999',99.999);
1 row inserted
SQL> insert into test_number3 values('99.9999',99.9999);
insert into test_number3 values('99.9999',99.9999)
ORA-01438: value larger than specified precision allowed for this column
注意,當(dāng)插入99.9999時,系統(tǒng)報錯。因為小數(shù)位為3位。第四位小數(shù)位是9,于是往前入。最終變成100.000.就已經(jīng)超過了精度。
Number(5,3)可存儲的數(shù)值最大為99.999.
現(xiàn)在終于有點明白小數(shù)位與精度的關(guān)系了。
number(38,127)
可以存儲的最大小數(shù)為:127位小數(shù),最后38為9.
即:0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099999999999999999999999999999999999999
小數(shù)位為負數(shù)。
我們從前面知道,小數(shù)位的取值為-48 ~127
為什么小數(shù)位會為負數(shù)?這有點怪異了。像上面的number(5,3)將值舍入為最接近0.001
Number(5,-3)就是將值舍入為最接近的1000
SQL> create table test_number5 (col_char varchar(20), col_num number(5,-3));
Table created
插入值10999
SQL> insert into test_number5 values('10999',10999);
1 row inserted
查看一下結(jié)果
SQL> select * from test_number5;
COL_CHAR???????????? COL_NUM
-------------------- -------
10999????????????????? 11000
存儲的結(jié)果為:11000
當(dāng)小數(shù)部分為負數(shù)時,是對小數(shù)部分進行舍入。
那么精度在這時起到什么作用呢?與小數(shù)位又有什么關(guān)系?
SQL> insert into test_number5 values('111111111',111111111);
insert into test_number5 values('111111111',111111111)
ORA-01438: value larger than specified precision allowed for this column
插入9個1時,報錯精度不夠。
SQL> insert into test_number5 values('11111111',11111111);
1 row inserted
插入8個1時,正確插入。
我們看看它的結(jié)果,看它是怎么舍入的。
SQL> select * from test_number5;
COL_CHAR???????????? COL_NUM
-------------------- -------
11111111???????????? 11111000
結(jié)果是1111100而不是1111100
無限接近1000,就是從百位開始進行四舍五入,后面的值全部為0。
所以看出number(5,-3)可存儲的最大值為:99999000
SQL> insert into test_number5 values('99999499.999999',99999499.999999);
1 row inserted
SQL> select * from test_number5;
COL_CHAR???????????? COL_NUM
-------------------- -------
99999999???????????? 99999000
99999499.999999????? 99999000
現(xiàn)在應(yīng)該明白了精度和小數(shù)位的關(guān)系了吧。
小數(shù)位告訴系統(tǒng)保留多少位小數(shù),從哪里開始舍入。
精度舍入后,從舍入的位置開始,數(shù)值中允許有多少位。
§2.4? binary_float 和binary_double
這兩種類型是oracle 10g新引進的數(shù)值類型。在oracle 10g之前是沒有這兩種類型的。
Number類型是由oracle軟件支持的類型。而浮點數(shù)用于近似數(shù)值。但是它浮點數(shù)允許由在硬盤上(CPU,芯片)上執(zhí)行運行。而不是在oracel進程中運算。如果希望在一個科學(xué)計算中執(zhí)行實數(shù)處理,依賴于硬件的算術(shù)運算速度要快得多。但是它的精度卻很小。如果希望用來存儲金融數(shù)值,則必須用number.
BINARY_FLOAT是一種IEEE固有的單精度浮點數(shù)。可存儲6位精度,取值范圍在~±1038.25的數(shù)值。
BINARY_DOUBLE是一種IEEE固有的雙精度浮點數(shù)。可存儲12位精度。取值范圍在~±10308.25的數(shù)值
SQL> create table test_floatdouble(col_number number, col_float binary_float, col_double binary_double);
Table created
SQL> insert into test_floatdouble values(9876543210.0123456789,9876543210.0123456789,9876543210.0123456789);
1 row inserted
2 SQL> select to_char(col_number), to_char(col_float), to_char(col_double) from test_floatdouble;
3
4 TO_CHAR(COL_NUMBER)????????????????????? TO_CHAR(COL_FLOAT)?????????????????????? TO_CHAR(COL_DOUBLE)
5 ---------------------------------------- ---------------------------------------- ----------------------------------------
6 9876543210.0123456789??????????????????? 9.87654349E+009????????????????????????? 9.8765432100123463E+009
由此可見,binary_float無法表示這個數(shù)。Binary_float和binary_double無法用于對精度要求高的數(shù)據(jù)。
SQL> select dump(col_float)from test_floatdouble;
DUMP(COL_FLOAT)
--------------------------------------------------------------------------------
Typ=100 Len=4: 208,19,44,6
BINARY_FLOAT 類型編碼為100
Len=4 占用4個字節(jié)。它是采用固定字節(jié)進行存儲的。
SQL> select dump(col_double)from test_floatdouble;
DUMP(COL_DOUBLE)
--------------------------------------------------------------------------------
Typ=101 Len=8: 194,2,101,128,183,80,25,73
BINARY_DOUBLE 類型編碼為101
Leng= 8 占用8個字節(jié)。也是采用固定字節(jié)進行存儲。
注意:number 類型使用的CPU時間是浮點數(shù)類型的50倍。浮點數(shù)是數(shù)值的一個近似值,精度在6-12位之間。從Number類型得到的結(jié)果要比從浮點數(shù)得到的結(jié)果更精確。但在對科學(xué)數(shù)據(jù)進行數(shù)據(jù)挖掘和進行復(fù)雜數(shù)值分析時,精度的損失是可以接受的,還會帶來顯著的性能提升。
這時需要使用內(nèi)置CAST函數(shù),對NUMBER類型執(zhí)行一種實時的轉(zhuǎn)換,在執(zhí)行復(fù)雜數(shù)學(xué)運算之前先將其轉(zhuǎn)換為一種浮點數(shù)類型。CPU使用時間就與固有浮點類型使用的CPU時間非常接近了。
Select ln(cast(number_col as binary_double)) from test_number.
§2.5 Oracle在語法上還支持的數(shù)值數(shù)據(jù)類型
NUMERIC(p,s):完全映射到NUMBER(p,s)。如果p未指定,則默認為38.
DECIMAL(p,s)或DEC(p,s):同NUMERIC(p,s).
INTEGER或int:完全映射至NUMBER(38)
SMALLINT:完全映射至NUMBER(38)
FLOAT(b):映射至NUMBER
DOUBLE PRECISION:映射到NUMBER
REAL:映射到NUMBER.
轉(zhuǎn)載于:https://www.cnblogs.com/linsond/archive/2010/06/30/1767965.html
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的转--Oracle数据类型及存储方式【C】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Alpha通道
- 下一篇: Silverlight4.0(9) 之