首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle NUMBER 型別精度與小數位完整解析:p、s 參數行為與工具差異

     編輯:Oracle 資料庫相關知識

NUMBER(p, s) 參數定義

  • p (Precision, 精度):有效數字總位數,**1 ~ 38**
  • s (Scale, 小數位):小數點右邊位數,**-84 ~ 127**
  • 整數位上限 = p - s**

Scale (s) 正負號行為差異

s 值行為範例 NUMBER(5,2)範例 NUMBER(5,-2)
s > 0小數點**右邊**保留 s 位,四捨五入123.456 → 123.46—
s = 0四捨五入至**整數**123.456 → 123123.456 → 123
s < 0小數點**左邊**第 |s| 位四捨五入 (十位、百位...)—123.456 → 100 (百位)
p < s (s>0)純小數,**小數點後前 (s-p) 位必為 0**,保留 s 位小數NUMBER(2,5) 存 0.00123 → 0.00123—

實測案例:NUMBER(5,2) vs NUMBER(5,-2) vs NUMBER(2,5)


CREATE TABLE hjm_num_test (
  a NUMBER,           -- 無限制
  b NUMBER(5,2),      -- 2 位小數
  c NUMBER(5,-2),     -- 百位四捨五入
  d NUMBER(5,0),      -- 整數
  e NUMBER(5),        -- 等同 NUMBER(5,0)
  f NUMBER(2,5)       -- 純小數,小數點後前 3 位必為 0
);

INSERT INTO hjm_num_test (a,b,c,d,e,f) VALUES (123.3333, 123.3333, 123.3333, 123.3333, 123.3333, -0.0003);
INSERT INTO hjm_num_test (a,b,c,d,e,f) VALUES (197.9333, 197.9333, 197.9333, 197.9333, 197.9333, 0.00012567);
COMMIT;

SELECT * FROM hjm_num_test;

查詢結果對照

欄位定義第 1 列輸入第 1 列儲存第 2 列輸入第 2 列儲存
ANUMBER123.3333123.3333197.9333197.9333
BNUMBER(5,2)123.3333123.33197.9333197.93
CNUMBER(5,-2)123.3333100197.9333200
DNUMBER(5,0)123.3333123197.9333198
ENUMBER(5)123.3333123197.9333198
FNUMBER(2,5)-0.0003-0.000300.000125670.00013

工具顯示差異:PL/SQL Developer vs iSQL*Plus / SQL*Plus

欄位PL/SQL DeveloperiSQL*Plus / SQL*Plus原因
F (第 1 列)-0.00030-.0003SQL*Plus 預設抑制前導/尾隨零
F (第 2 列)0.00013.00013同上

解決顯示差異


-- SQL*Plus / iSQL*Plus 設定
SET NUMFORMAT "0.99999"        -- 固定格式
SET NUMWIDTH 20                -- 寬度
COLUMN f FORMAT "0.00000"      -- 特定欄位格式

-- 或使用 TO_CHAR 明確格式化
SELECT TO_CHAR(f, 'FM0.00000') FROM hjm_num_test;

NUMBER 子類型對照

子類型等價定義用途
INTEGER / INTNUMBER(38,0)整數
SMALLINTNUMBER(38,0) 但邏輯限制較小相容 ANSI
DEC / DECIMAL(p,s)NUMBER(p,s)固定小數位
NUMERIC(p,s)NUMBER(p,s)相容 ANSI
FLOAT(p)二進制精度 p 位 (1~126)近似數值
REALFLOAT(63)單精度
DOUBLE PRECISIONFLOAT(126)雙精度

效能與儲存考量

  • 儲存大小:可變長度,約 (p/2)+1 bytes,最大 21 bytes
  • 運算效能:PLS_INTEGER / SIMPLE_INTEGER (PL/SQL 區域) 效能遠優於 NUMBER
  • 索引大小:NUMBER 索引較 CHAR/VARCHAR2 大
  • 避免過度精度:金額用 NUMBER(18,4) 或 NUMBER(15,2) 足矣,勿用 NUMBER(38,*)

最佳實踐建議

  1. 金額/價格:NUMBER(18,4) (支援萬億、4 位小數)
  2. 數量/計數:NUMBER(10,0) 或 INTEGER
  3. 比率/百分比:NUMBER(5,4) (0.0001 ~ 9.9999)
  4. 科學計算:BINARY_DOUBLE / BINARY_FLOAT
  5. PL/SQL 區域變數:迴圈計數器用 PLS_INTEGER、SIMPLE_INTEGER
  6. 明確指定 p,s:避免隱含 NUMBER(38,*) 浪費空間

常見轉換陷阱


-- 隱含轉換導致精度遺失
INSERT INTO t(num_col) VALUES (1.234567890123456789); -- NUMBER(38,*) 可能截斷

-- 正確:明確精度
INSERT INTO t(num_col) VALUES (1.234567890123456789); -- 目標欄位 NUMBER(20,10) 完整保留

-- 科學記號
INSERT INTO t VALUES (1.23E-5); -- 等同 0.0000123
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved