天天看點

pg資料庫numeric對應oracle,Oracle類型number與PG類型numeric對比和轉換政策

Oracle 11g

number 任意精度數字類型

存儲資料的範圍

正數:1 x 10-130 to 9.99...9 x 10125 ,資料精度為38個有效數字

負數:-1 x 10-130 to 9.99...99 x 10125,資料精度為38個有效數字

零:0

無窮大:僅僅隻可以從oracle 5中導入

描述

标度scale代表小數部分的數字位數,scale∈[-84,127],s預設為0;

精度precision代表所有數字的位數,precision∈[1,38],p預設為最大限度内的任意值。

一般的精度可以大于等于标度,oracle中精度也可以小于标度,如numeri(3,6),該字段隻能插入小于0.001的值,即0.0009,0.0008等等,小數點後尾數超出标度的位數将會四舍五入省去。

幾個常見形式

Number 或者Number(*), (user_tab_column查詢結果中data_precision=null,data_scale=null),此時可以存儲極限内任意Precision和scale的值。

Number(*,scale), (user_tab_column查詢結果中data_precision=null,data_scale=scale)此時可以存儲極限内任意precision的值;

Number(precision), 此時scale預設為0,等價于number(precision,0);

Number(precision,scale), precision∈[1,38],scale∈[-84,127]。

例子

Input Data

Specified As

Stored As

7,456,123.89

NUMBER

7456123.89

7,456,123.89

NUMBER(*,1)

7,456,123.89

NUMBER(9)

7456124

7,456,123.89

NUMBER(9,2)

7456123.89

7,456,123.89

NUMBER(9,1)

7,456,123.89

NUMBER(6)

(not accepted, exceeds precision)

7,456,123.89

NUMBER(7,-2)

7456100

我的個人測試例子(oracle Release 10.2.0.1.0)如下,得出小結論:number最多能存儲126位整數(超出126位後會溢出報錯),能準确存儲最高40位的整數(大于40切小于等于126的整數,超出40位的部分四舍五入後補為0),當有整數和小數時,整數部分最多能準确存儲38位。

SQL> create table test0(id int,num number);

表已建立。

SQL> insert into test0 values(1,123456789123456789123456789123456789123456789123

456789123456789123456789123456789123456789123456789123456789123456789123456789);--126

已建立 1 行。

送出完成。

SQL> insert into test0 values(2,123456789123456789123456789123456789123456789123

4567891234567891234567891234567891234567891234567891234567891234567891234567891)

;--127

insert into test0 values(2,12345678912345678912345678912345678912345678912345678

91234567891234567891234567891234567891234567891234567891234567891234567891)

*

第 1 行出現錯誤:

ORA-01426: 數字溢出

SQL> insert into test0 values(3,1234567891234567891234567891234567891234);--40

已建立 1 行。

送出完成。

SQL> insert into test0 values(4,12345678912345678912345678912345678912345);--41

已建立 1 行。

送出完成。

SQL> insert into test0 values(6,1234567891234567891234567891234567891234.567);--【40,3】

已建立 1 行。

送出完成。

SQL> insert into test0 values(7,123456789123456789123456789123456789123.4567);--【39,4】

已建立 1 行。

送出完成。

SQL> insert into test0 values(8,12345678912345678912345678912345678912.34567);--【38,5】

已建立 1 行。

送出完成。

SQL> select * from test0;

ID NUM

---------- ----------

1 1.235E+125

3 1.2346E+39

4 1.2346E+40

6 1.2346E+39

7 1.2346E+38

8 1.2346E+37

通過JDBC擷取到的資料是:

System.out.println(rs.getInt(1)+","+rs.getBigDecimal(2)+","+rs.getBigDecimal(2) .toString().length());

print

-----------------------------------------

1,123456789123456789123456789123456789123500000000000000000000000000000000000000000000000000000000000000000000000000000000000000,126

3,1234567891234567891234567891234567891234,40

4,12345678912345678912345678912345678912300,41

6,1234567891234567891234567891234567891235,40

7,123456789123456789123456789123456789123,39

8,12345678912345678912345678912345678912.35,41

Postgresql 9.3

Numeric任意精度數字類型

存儲空間:變長

描述:使用者聲明精度,位數精确。

範圍:小數點以前最多131072位,小數點以後最多16383位。

标度(scale):是小數部分的位數,scale>=0

精度(precision):是全部資料位的數目,也就是小數點兩邊的位數總和。

僅支援精度>=标度。

例子:數字23.5141的精度為6而标度為4。可以認為整數的标度scale為零。

常見形式:

numeric字段的最大精度和最大标度都是可以配置的。要聲明一個字段的類型為numeric,可以用下面的文法:

NUMERIC(precision, scale),其中precision>0,scale>=0。

NUMERIC(precision),此時即scale預設為0,即等價于NUMERIC(pre3cision,0)。

NUMERIC不帶任何精度與标度的聲明,則建立一個可以存儲一個直到實作精度上限的任意精度和标度的數值,一個這樣類型的字段将不會把輸入數值轉化成任何特定的标度,而帶有标度聲明的 numeric字段将把輸入值轉化為該标度。

我的個人測試例子(postgresql9.3.4)如下,得出小結論:numeric不同于oracle的number,numeric能準确存儲126位,甚至更高位的數字。

jnggzy=> create table ttt1(id int, num numeric);

CREATE TABLE

jnggzy=> insert into ttt1 values(1,123456789123456789123456789123456789123456789

12345678912345678912345678912345678912345678912345678912345678912345678912345678

9);---126

INSERT 0 1

jnggzy=> insert into ttt1 values(1,123456789123456789123456789123456789123456789

12345678912345678912345678912345678912345678912345678912345678912345678912345678

9123456789);---135

INSERT 0 1

jnggzy=> insert into ttt1 values(3,123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789.123456789);--【135,9】

INSERT 0 1

jnggzy=> select * from ttt1;

id | num

----+---------------------------------------------------------------------------

1 | 123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789

1 | 123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789

3 | 123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789.123456789

(3 行記錄)