首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

Oracle 進制轉換完全指南:內建函數與自訂函數實作

     編輯:關於SqlServer

前言

資料庫開發中常需處理不同進制間的轉換(十六進制 ↔ 十進制、二進制 ↔ 十進制、八進制等)。Oracle 提供豐富的內建函數,並支援自訂函數擴展任意進制轉換。本文系統整理各種轉換方法與效能考量。

一、內建函數轉換(Oracle 9i+)

1. 十六進制 → 十進制:TO_NUMBER

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 代表一位十六進制數字,大小寫不敏感。位數需足夠容納輸入值,否則回傳 ORA-01722。

2. 十進制 → 十六進制:TO_CHAR

SELECT TO_CHAR(123, 'XXX') FROM dual;   -- 7B
SELECT TO_CHAR(4567, 'XXXX') FROM dual; -- 11D7
SELECT TO_CHAR(255, 'FMXX') FROM dual;  -- FF (FM 移除前導空白)

注意:TO_CHAR 預設回傳大寫,若需小寫可用 LOWER() 包裹。

3. 二進制 → 十進制:BIN_TO_NUM (9i+)

SELECT BIN_TO_NUM(1,1,0,1) FROM dual;      -- 13 (1101₂)
SELECT BIN_TO_NUM(1,1,1,0,1) FROM dual;    -- 29 (11101₂)
SELECT BIN_TO_NUM(1,0) FROM dual;          -- 2 (10₂)

參數:每個位元為獨立參數(0 或 1),最多 255 位元(對應 NUMBER 精度)。高位在前,低位在後。

二、任意進制轉換自訂函數(參考 AskTom 經典實作)

1. 核心函數:TO_BASE (十進制 → 任意進制 2~16)

CREATE OR REPLACE FUNCTION to_base (
    p_dec    IN NUMBER,
    p_base   IN NUMBER
) RETURN VARCHAR2 IS
    l_str   VARCHAR2(255) DEFAULT NULL;
    l_num   NUMBER        DEFAULT p_dec;
    l_hex   VARCHAR2(16)  DEFAULT '0123456789ABCDEF';
BEGIN
    IF TRUNC(p_dec) != p_dec OR p_dec < 0 THEN
        RAISE PROGRAM_ERROR;  -- 僅支援非負整數
    END IF;
    LOOP
        l_str := SUBSTR(l_hex, MOD(l_num, p_base) + 1, 1) || l_str;
        l_num := TRUNC(l_num / p_base);
        EXIT WHEN l_num = 0;
    END LOOP;
    RETURN l_str;
END to_base;
/
SHOW ERRORS

2. 反向函數:TO_DEC (任意進制 2~16 → 十進制)

CREATE OR REPLACE FUNCTION to_dec (
    p_str        IN VARCHAR2,
    p_from_base  IN NUMBER DEFAULT 16
) RETURN NUMBER IS
    l_num  NUMBER       DEFAULT 0;
    l_hex  VARCHAR2(16) DEFAULT '0123456789ABCDEF';
BEGIN
    FOR i IN 1 .. LENGTH(p_str) LOOP
        l_num := l_num * p_from_base + 
                 INSTR(l_hex, UPPER(SUBSTR(p_str, i, 1))) - 1;
    END LOOP;
    RETURN l_num;
END to_dec;
/
SHOW ERRORS

3. 便利包裝函數

CREATE OR REPLACE FUNCTION to_hex (p_dec IN NUMBER) RETURN VARCHAR2 IS
BEGIN RETURN to_base(p_dec, 16); END to_hex;
/

CREATE OR REPLACE FUNCTION to_bin (p_dec IN NUMBER) RETURN VARCHAR2 IS
BEGIN RETURN to_base(p_dec, 2); END to_bin;
/

CREATE OR REPLACE FUNCTION to_oct (p_dec IN NUMBER) RETURN VARCHAR2 IS
BEGIN RETURN to_base(p_dec, 8); END to_oct;
/

三、使用範例與驗證

-- 十進制 255 轉各進制
SELECT to_hex(255) AS hex, to_bin(255) AS bin, to_oct(255) AS oct FROM dual;
-- HEX: FF, BIN: 11111111, OCT: 377

-- 反向驗證
SELECT to_dec('FF', 16) AS dec16, 
       to_dec('11111111', 2) AS dec2, 
       to_dec('377', 8) AS dec8 FROM dual;
-- 全部回傳 255

-- 內建函數交叉驗證
SELECT TO_NUMBER(to_hex(4095), 'XXXX') AS check_hex,
       BIN_TO_NUM(1,1,1,1,1,1,1,1,1,1,1,1) AS check_bin
FROM dual;  -- 4095, 4095

四、效能與限制說明

方法適用範圍效能限制
TO_NUMBER/TO_CHAR16↔10 進制極高(原生 C 實作)僅 16 進制
BIN_TO_NUM2→10 進制高(原生)參數列表長度受限,不適合長二進制字串
自訂 PL/SQL 函數2~16 任意進制雙向中(PL/SQL 迴圈)僅支援非負整數;大數值需注意 VARCHAR2 長度

五、進階擴展:支援負數、小數、大進制 (Base32/Base64)

若需支援:

  • 負數:在 TO_BASE 開頭判斷正負號,轉換絕對值後加回符號;
  • 小數:整數部與小數部分別轉換,小數部採「乘基數取整」法迴圈;
  • Base32/Base64:擴展 l_hex 字元集至 32/64 字元(RFC 4648 標準字母表),邏輯不變。

六、結語

Oracle 內建 TO_NUMBER/TO_CHAR 處理 16 進制、BIN_TO_NUM 處理二進制,已滿足 90% 場景。自訂 TO_BASE/TO_DEC 函數組合則提供 2~16 進制通用解決方案,程式碼精簡、易維護。實務建議:將這組函數封裝為 PKG_BASE_CONV 套件部署於共用 Schema,供全系統呼叫,避免重複造輪子。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved