一、SQL-92 數值類型分類與核心概念
數值類型分為精確數值 (Exact Numeric) 與近似數值 (Approximate Numeric) 兩大類。核心屬性:
- 精度:有效數字總位數 (如 1234.56 精度為 6)
- 刻度:小數點右側位數 (如 1234.56 刻度為 2)
- 標準語法:`TYPE(precision[, scale])`
二、精確數值類型詳細規格
| 類型 | 語法 | 儲存方式 | 刻度 | 長度計算 | 關鍵規則 |
| NUMERIC | `NUMERIC(p,s)` | 十進制 BCD | 固定 = s | p (s>0 時 +1 小數點) | 四捨五入符合刻度;標準精確型別 |
| DECIMAL / DEC | `DECIMAL(p,s)` | 十進制 BCD | ≥ s (上限由廠商定) | p (s>0 時 +1) | 允許保留更多小數位;功能相當 NUMERIC |
| INTEGER / INT | `INTEGER[(p)]` | 二進制/十進制 | 固定 0 | 視實作位元數 | 廠商定義最大/最小精度;可有預設精度 |
| SMALLINT | `SMALLINT[(p)]` | 同 INTEGER | 固定 0 | ≤ INTEGER 最大精度 | 短整數,節省空間 |
三、近似數值類型 (浮點數)
| 類型 | 語法 | 表示形式 | 精度基礎 | 廠商控制 |
| FLOAT | `FLOAT(p)` | 科學記號 `1.23e-45` | 二進制精度 (位元數) | 最大精度由廠商設定 |
| REAL | `REAL` | 單精度浮點數 | 二進制 | 最大精度 < DOUBLE PRECISION |
| DOUBLE PRECISION | `DOUBLE PRECISION` | 雙精度浮點數 | 二進制 | 最大精度 > REAL |
關鍵差異:精確型別適合財務/會計;近似型別適合科學計算、圖形、統計,但不可用於等值比較或貨幣運算。
四、SQL Server 具體實作對照表
| 標準類型 | SQL Server 2005/2008+ | 儲存位元組 | 精度範圍 | 刻度範圍 | 備註 |
| NUMERIC(p,s) | `NUMERIC(p,s)` / `DECIMAL(p,s)` | 5-17 (視 p) | 1-38 | 0-p | 功能完全相同 |
| INTEGER | `INT` | 4 | 10 位數 (-2^31~2^31-1) | 0 | 最常用整數 |
| SMALLINT | `SMALLINT` | 2 | 5 位數 (-32768~32767) | 0 | |
| - | `TINYINT` | 1 | 0-255 | 0 | SQL Server 擴充 |
| - | `BIGINT` | 8 | 19 位數 (-2^63~2^63-1) | 0 | SQL Server 擴充 |
| FLOAT(p) | `FLOAT[(n)]` | 4 (n≤24) / 8 (n>24) | 7 / 15 位數 | - | n 為位元精度,預設 53 (雙精度) |
| REAL | `REAL` | 4 | 7 位數 | - | 單精度 = FLOAT(24) |
| DOUBLE PRECISION | `FLOAT` / `FLOAT(53)` | 8 | 15 位數 | - | 雙精度 |
| - | `MONEY` | 8 | 19 位數 | 固定 4 | 貨幣專用,四捨五入行為特殊 |
| - | `SMALLMONEY` | 4 | 10 位數 | 固定 4 | |
五、跨平台遷移核心風險:Oracle vs SQL Server
| 場景 | Oracle NUMBER | SQL Server NUMERIC/DECIMAL | 風險 |
| 未指定精度/刻度 | `NUMBER` (最大 38 位,刻度 -84~127) | **必須指定** `NUMERIC(38,10)` 等 | Oracle 隱式精度極大,SQL Server 截斷/溢位 |
| 負刻度 | 支援 `NUMBER(*, -3)` (千位精度) | **不支援** 負刻度 | 遷移需重新設計刻度策略 |
| 浮點數字面值 | `1.23f` / `1.23d` | 無後綴區分,靠 `FLOAT`/`REAL` 型別 | 隱式轉換精度損失 |
六、運算規則與隱式轉換優先序
- 運算結果保留最大精度 (精確型別) 或最高精度浮點格式
- 精確 + 近似 → 近似 (隱式轉換為 FLOAT)
- 不同精確型別運算 → 結果精度/刻度依廠商規則 (SQL Server 有詳細公式)
- 避免混用:財務系統全程 `DECIMAL(19,4)`,科學計算全程 `FLOAT(53)`
七、MONEY 型別特殊行為警示
- 除法運算會截斷而非四捨五入:`SELECT 10.0 / 3.0` → `3.3333` (MONEY) vs `3.333333...` (DECIMAL)
- 匯率/單價計算建議用 `DECIMAL(19,6)` 以上,最後顯示才 `CAST AS MONEY`
- 國際化場景:`MONEY` 無貨幣單位資訊,需額外欄位存 `CurrencyCode`
八、最佳實踐檢查清單
- [ ] 所有貨幣/會計欄位使用 `DECIMAL(p,s)`,明確指定 p,s
- [ ] 科學/統計欄位使用 `FLOAT(53)`,文件註明精度需求
- [ ] 整數鍵值:`BIGINT` (身分識別)、`INT` (外鍵)、`SMALLINT`/`TINYINT` (代碼/狀態)
- [ ] 避免 `FLOAT`/`REAL` 參與 `WHERE col = value` 等值比較
- [ ] 跨資料庫遷移時,以 `bcp`/`SSIS` 匯出 CSV,指定 `DECIMAL` 格式,驗證資料完整性
- [ ] 統計資訊包含數值直方圖,定期 `UPDATE STATISTICS` 維護基數估計
下一篇將講解字串資料類型:`CHAR`、`VARCHAR`、`NCHAR`、`NVARCHAR`、`TEXT`/`NTEXT`、`VARCHAR(MAX)` 儲存機制、排序規則、Unicode 處理與遷移策略。