金額/比率欄位需 **固定顯示兩位小數** (如 `1234.50`、`0.00`),且 **整數部分無前導空格/零**,直接用 `ROUND(val,2)` 輸出格式不穩 (科學計數法、省略尾零)。
| 方案 | 核心代碼 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|---|
| 1. TO_CHAR + FM | `TO_CHAR(ROUND(val,2), 'FM99999999999999.00')` | 標準 SQL、可直接用於視圖/報表 | 値為 0 顯示 `.00` 需 `DECODE` 修正;左側 9 不夠顯示 `####` | 靜態報表、視圖定義 |
| 2. CASE WHEN 分支 | `CASE WHEN INSTR(TO_CHAR(val),'.')<1 THEN val||'.00' WHEN INSTR(TO_CHAR(val),'.')+1=LENGTH(TO_CHAR(val)) THEN val||'0' ELSE TO_CHAR(ROUND(val,2)) END` | 純邏輯控制、無格式串長度限制 | 代碼冗長、效能稍差 (多次轉換) | 動態精度需求、舊版本相容 |
| 3. COLUMN FORMAT (SQL*Plus/客戶端) | `COLUMN val FORMAT L9999999999.99` | 零代碼侵入、客戶端自動渲染 | Session 級生效、連接池複用易失效、左側 9 長度固定 | 互動式查詢、臨時調試 |
| 4. TRIM + TO_CHAR (推薦) | `TRIM(TO_CHAR(val, '99999999999999.99'))` | 自動去除前導空格、格式串通用、可配合 `LTRIM(..., '0')` 去前導零 | 值為 0 顯示 `.99` 需 `DECODE` 修正 | **通用最佳**:應用層、報表、視圖、ETL |
-- 單值測試
SELECT DECODE(val, 0, '0.00', TRIM(TO_CHAR(val, '99999999999999.99'))) fmt_val
FROM (SELECT 0 val FROM dual UNION ALL SELECT 1234.5 FROM dual UNION ALL SELECT 1234.567 FROM dual);
-- 結果:
-- 0.00
-- 1234.50
-- 1234.57
-- 視圖/報表通用寫法
CREATE OR REPLACE VIEW v_fmt_amount AS
SELECT
id,
DECODE(amount, 0, '0.00', TRIM(TO_CHAR(amount, '99999999999999.99'))) AS amount_fmt
FROM transactions;
-- 方案 1: TO_CHAR+FM ~1.2 秒
-- 方案 2: CASE WHEN ~2.8 秒
-- 方案 4: TRIM+TO_CHAR ~1.1 秒 (最快)
-- 原因:TRIM 為內部 C 函數極快,CASE 多次函數調用開銷大
**`DECODE(val,0,'0.00', TRIM(TO_CHAR(val,'99999999999999.99')))` 是 Oracle 小數格式化的「黃金公式」**:標準 SQL、零客戶端依賴、效能最優、邊界情況全覆蓋。將其封裝為 **公共函數 `PKG_UTIL.FMT_AMOUNT(val)`**,全專案統一調用,徹底消除格式不一致 Bug。