Oracle 提供內建函數支援 2/10/16 進制互轉,核心為 TO_NUMBER (字串→數值)、TO_CHAR (數值→字串)、BIN_TO_NUM (二進位位元→數值)。本文彙整標準語法、格式模型、常見陷阱與實用範例,適用 9i 至 23c 所有版本。
TO_NUMBER(hex_string, 'XXXX...') -- X 代表十六進位數字位數,需與字串長度對應
-- 範例
SELECT TO_NUMBER('19F', 'XXX') FROM DUAL; -- 415
SELECT TO_NUMBER('F', 'XX') FROM DUAL; -- 15
SELECT TO_NUMBER('FF', 'XX') FROM DUAL; -- 255
X 大小寫不敏感,但輸入字串必須為有效十六進位字元 (0-9, A-F)。ORA-01722: invalid number。TO_NUMBER('00FF', 'XXXX') = 255。TO_CHAR(number, 'XXXX...') -- 回傳大寫十六進位字串,無前導零
-- 範例
SELECT TO_CHAR(123, 'XX') FROM DUAL; -- 7B
SELECT TO_CHAR(4567, 'XXXX') FROM DUAL; -- 11D7
SELECT TO_CHAR(255, 'XXXXXXXX') FROM DUAL; -- 000000FF (12c+ 支援 FM 修飾符抑制前導空格)
-- FM 移除前導空格,固定寬度需自行 LPAD
SELECT LPAD(TO_CHAR(255, 'FMXXXX'), 8, '0') FROM DUAL; -- 000000FF
專為位元旗標轉換設計,參數為 0/1 位元序列 (最高位在前)。
BIN_TO_NUM(bit1, bit2, ..., bitN) -- 回傳 NUMBER
-- 範例
SELECT BIN_TO_NUM(1,1,0,1) FROM DUAL; -- 13 (1101₂)
SELECT BIN_TO_NUM(1,0) FROM DUAL; -- 2 (10₂)
SELECT BIN_TO_NUM(1,1,1,0,1) FROM DUAL; -- 29 (11101₂)
-- 實務:將多個布林旗標打包成單一整數儲存
-- FLAGS = (IS_ACTIVE, IS_ADMIN, IS_LOCKED, IS_DELETED)
SELECT BIN_TO_NUM(1, 0, 0, 1) AS packed_flags FROM DUAL; -- 9
Oracle 無直接八進制格式模型,可透過兩步轉換:
-- 八進制字串 → 十進制
SELECT TO_NUMBER('173', 'XXXX') FROM DUAL; -- 錯誤!X 僅支援 16 進位
-- 正確:手寫函數或 PL/SQL 迴圈解析
-- 十進制 → 八進制字串
-- 同樣需自行實作 (除 8 取餘法)
建議:八進制需求極少見,若必要請封裝 PL/SQL 函數 OCT_TO_NUM / NUM_TO_OCT。
-- HTML 顏色 #RRGGBB 解析
SELECT
TO_NUMBER(SUBSTR('#FF8000', 2, 2), 'XX') AS R, -- 255
TO_NUMBER(SUBSTR('#FF8000', 4, 2), 'XX') AS G, -- 128
TO_NUMBER(SUBSTR('#FF8000', 6, 2), 'XX') AS B -- 0
FROM DUAL;
-- IPv4 字串轉數值 (利用 256 進位)
-- 192.168.1.10 → 3232235786
SELECT TO_NUMBER('C0', 'XX') * 16777216 +
TO_NUMBER('A8', 'XX') * 65536 +
TO_NUMBER('01', 'XX') * 256 +
TO_NUMBER('0A', 'XX') AS ip_num
FROM DUAL;
| 錯誤現象 | 原因 | 修正 |
|---|---|---|
| ORA-01722 | 格式模型長度 < 輸入字串長度,或含非法字元 | 對齊模型長度,輸入大寫 A-F |
| 結果為 NULL | 輸入字串為 NULL | 加 NVL 或 CASE 處理 |
| 負數轉十六進制異常 | TO_CHAR(-1, 'XX') 回傳 'FFFFFFFF' (補碼) | 若需邏輯無符號,先 + 4294967296 |
| BIN_TO_NUM 參數非 0/1 | 傳入 2、NULL 等 | 嚴格驗證參數來源 |
| 轉換方向 | 函數 | 格式模型 | 版本 |
|---|---|---|---|
| 16進位字串 → 數值 | TO_NUMBER | 'XXXX' | 所有版本 |
| 數值 → 16進位字串 | TO_CHAR | 'XXXX' / 'FMXXXX' | 所有版本 / 12c+ |
| 二進位位元 → 數值 | BIN_TO_NUM | 無 (位元參數列) | 9i+ |
| 八進位 | 自行實作 | — | — |
掌握這三大函數與格式模型,即可輕鬆應對 Oracle 中所有進制轉換需求,從位元旗標處理到網路地址運算,一致、高效、無相容性疑慮。