Oracle中的二進制、八進制、十進制、十六進制相互轉換函數

大家經常遇到進制轉換的問題,網上搜到的轉換隻是部分十進制與其它進制的轉換,所以我把自己寫的轉換函數提供給大家,4種進制共12個轉換函數,雖然有的轉換直接使用to_char()就可以實現,但我還是把它們整理到一起,使用和查找都方便。

部分函數需要先創建type_str_agg類型和f_stragg函數才能使用,這兩個對象的代碼也附在之後。

這些函數並非都是我原創,部分是參照別人的代碼整理而來:type_str_agg、f_stragg、f_hex_to_dec、f_oct_to_dec、f_bin_to_dec。



CREATE OR REPLACE PACKAGE pkg_number_trans IS

  FUNCTION f_bin_to_oct(p_str IN VARCHAR2) RETURN VARCHAR2;
 
  FUNCTION f_bin_to_dec(p_str IN VARCHAR2) RETURN VARCHAR2;
 
  FUNCTION f_bin_to_hex(p_str IN VARCHAR2) RETURN VARCHAR2;

  FUNCTION f_oct_to_bin(p_str IN VARCHAR2) RETURN VARCHAR2;
 
  FUNCTION f_oct_to_dec(p_str IN VARCHAR2) RETURN VARCHAR2;

  FUNCTION f_oct_to_hex(p_str IN VARCHAR2) RETURN VARCHAR2;
 
  FUNCTION f_hex_to_bin(p_str IN VARCHAR2) RETURN VARCHAR2;

  FUNCTION f_hex_to_oct(p_str IN VARCHAR2) RETURN VARCHAR2;

  FUNCTION f_hex_to_dec(p_str IN VARCHAR2) RETURN VARCHAR2;
 
  FUNCTION f_dec_to_bin(p_int IN VARCHAR2) RETURN VARCHAR2;

  FUNCTION f_dec_to_oct(p_int IN VARCHAR2) RETURN VARCHAR2;

  FUNCTION f_dec_to_hex(p_int IN VARCHAR2) RETURN VARCHAR2;
 
END pkg_number_trans;
/
CREATE OR REPLACE PACKAGE BODY pkg_number_trans IS


  FUNCTION f_bin_to_oct(p_str IN VARCHAR2) RETURN VARCHAR2 IS
    ----------------------------------------------------------------------------------------------------------------------
    -- 對象名稱: f_bin_to_oct
    -- 對象描述: 二進制轉換八進制
    -- 輸入參數: p_str 二進制字符串
    -- 返回結果: 八進制字符串
    -- 測試用例: SELECT pkg_number_trans.f_bin_to_oct('11110001010') FROM dual;
    -- 備    注: 需要定義f_stragg函數和type_str_agg類型
    ----------------------------------------------------------------------------------------------------------------------
    v_return VARCHAR2(4000);
    v_bin    VARCHAR2(4000);
  BEGIN
    v_bin := substr('00' || p_str, -3 * ceil(length(p_str) / 3));
    SELECT f_stragg(data1) INTO v_return
      FROM (SELECT (CASE upper(substr(v_bin, (rownum - 1) * 3 + 1, 3))
                     WHEN '000' THEN '0'
                     WHEN '001' THEN '1'
                     WHEN '010' THEN '2'
                     WHEN '011' THEN '3'
                     WHEN '100' THEN '4'
                     WHEN '101' THEN '5'
                     WHEN '110' THEN '6'
                     WHEN '111' THEN '7'
                   END) data1
              FROM dual
            CONNECT BY rownum <= length(v_bin) / 3);
    RETURN v_return;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END f_bin_to_oct;

  FUNCTION f_bin_to_dec(p_str IN VARCHAR2) RETURN VARCHAR2 IS
    ----------------------------------------------------------------------------------------------------------------------
    -- 對象名稱: f_bin_to_dec
    -- 對象描述: 二進制轉換十進制
    -- 輸入參數: p_str 二進制字符串
    -- 返回結果: 十進制字符串
    -- 測試用例: SELECT pkg_number_trans.f_bin_to_dec('11110001010') FROM dual;
    ----------------------------------------------------------------------------------------------------------------------
    v_return  VARCHAR2(4000);
  BEGIN
    SELECT SUM(data1) INTO v_return
      FROM (SELECT substr(p_str, rownum, 1) * power(2, length(p_str) - rownum) data1
              FROM dual
            CONNECT BY rownum <= length(p_str));
    RETURN v_return;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END f_bin_to_dec;

  FUNCTION f_bin_to_hex(p_str IN VARCHAR2) RETURN VARCHAR2 IS
    ----------------------------------------------------------------------------------------------------------------------
    -- 對象名稱: f_bin_to_hex
    -- 對象描述: 二進制轉換十六進制
    -- 輸入參數: p_str 二進制字符串
    -- 返回結果: 十六進制字符串
    -- 測試用例: SELECT pkg_number_trans.f_bin_to_oct('11110001010') FROM dual;
    -- 備    注: 需要定義f_stragg函數和type_str_agg類型
    ----------------------------------------------------------------------------------------------------------------------
    v_return VARCHAR2(4000);
    v_bin    VARCHAR2(4000);
  BEGIN
    v_bin := substr('000' || p_str, -4 * ceil(length(p_str) / 4));
    SELECT f_stragg(data1) INTO v_return
      FROM (SELECT (CASE upper(substr(v_bin, (rownum - 1) * 4 + 1, 4))
                     WHEN '0000' THEN '0'
                     WHEN '0001' THEN '1'
                     WHEN '0010' THEN '2'
                     WHEN '0011' THEN '3'
                     WHEN '0100' THEN '4'
                     WHEN '0101' THEN '5'
                     WHEN '0110' THEN '6'
                     WHEN '0111' THEN '7'
                     WHEN '1000' THEN '8'
                     WHEN '1001' THEN '9'
                     WHEN '1010' THEN 'A'
                     WHEN '1011' THEN 'B'
                     WHEN '1100' THEN 'C'
                     WHEN '1101' THEN 'D'
                     WHEN '1110' THEN 'E'
                     WHEN '1111' THEN 'F'
                   END) data1
              FROM dual
            CONNECT BY rownum <= length(v_bin) / 4);
    RETURN v_return;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END f_bin_to_hex;

  FUNCTION f_oct_to_bin(p_str IN VARCHAR2) RETURN VARCHAR2 IS
    ----------------------------------------------------------------------------------------------------------------------
    -- 對象名稱: f_oct_to_bin
    -- 對象描述: 八進制轉換二進制
    -- 輸入參數: p_str 八進制字符串
    -- 返回結果: 二進制字符串
    -- 測試用例: SELECT pkg_number_trans.f_oct_to_bin('3612') FROM dual;
    -- 備    注: 需要定義f_stragg函數和type_str_agg類型
    ----------------------------------------------------------------------------------------------------------------------
    v_return VARCHAR2(4000);
  BEGIN
    SELECT to_char(to_number(f_stragg(data1))) INTO v_return
      FROM (SELECT (CASE upper(substr(p_str, rownum, 1))
                     WHEN '0' THEN '000'
                     WHEN '1' THEN '001'
                     WHEN '2' THEN '010'
                     WHEN '3' THEN '011'
                     WHEN '4' THEN '100'
                     WHEN '5' THEN '101'
                     WHEN '6' THEN '110'
                     WHEN '7' THEN '111'
                   END) data1
              FROM dual
            CONNECT BY rownum <= length(p_str));
    RETURN v_return;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END f_oct_to_bin;

  FUNCTION f_oct_to_dec(p_str IN VARCHAR2) RETURN VARCHAR2 IS
    ----------------------------------------------------------------------------------------------------------------------
    -- 對象名稱: f_oct_to_dec
    -- 對象描述: 八進制轉換十進制
    -- 輸入參數: p_str 八進制字符串
    -- 返回結果: 十進制字符串
    -- 測試用例: SELECT pkg_number_trans.f_oct_to_dec('3612') FROM dual;
    ----------------------------------------------------------------------------------------------------------------------
    v_return  VARCHAR2(4000);
  BEGIN
    SELECT SUM(data1) INTO v_return
      FROM (SELECT substr(p_str, rownum, 1) * power(8, length(p_str) - rownum) data1
              FROM dual
            CONNECT BY rownum <= length(p_str));
    RETURN v_return;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END f_oct_to_dec;
 
  FUNCTION f_oct_to_hex(p_str IN VARCHAR2) RETURN VARCHAR2 IS
    ----------------------------------------------------------------------------------------------------------------------
    -- 對象名稱: f_oct_to_bin
    -- 對象描述: 八進制轉換十六進制
    -- 輸入參數: p_str 八進制字符串
    -- 返回結果: 十六進制字符串
    -- 測試用例: SELECT pkg_number_trans.f_oct_to_hex('3612') FROM dual;
    ----------------------------------------------------------------------------------------------------------------------
    v_return VARCHAR2(4000);
    v_bin    VARCHAR2(4000);
  BEGIN
    SELECT pkg_number_trans.f_oct_to_bin(p_str) INTO v_bin FROM dual;
    SELECT pkg_number_trans.f_bin_to_hex(v_bin) INTO v_return FROM dual;
    RETURN v_return;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END f_oct_to_hex;

  FUNCTION f_dec_to_bin(p_int IN VARCHAR2) RETURN VARCHAR2 IS
    ----------------------------------------------------------------------------------------------------------------------
    -- 對象名稱: f_dec_to_bin
    -- 對象描述: 十進制轉換二進制
    -- 輸入參數: p_str 十進制字符串
    -- 返回結果: 二進制字符串
    -- 測試用例: SELECT pkg_number_trans.f_dec_to_bin('1930') FROM dual;
    ----------------------------------------------------------------------------------------------------------------------
    v_return VARCHAR2(4000);
    v_hex    VARCHAR2(4000);
  BEGIN
    SELECT pkg_number_trans.f_dec_to_hex(p_int) INTO v_hex FROM dual;
    SELECT pkg_number_trans.f_hex_to_bin(v_hex) INTO v_return FROM dual;
    RETURN v_return;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END f_dec_to_bin;
 
  FUNCTION f_dec_to_oct(p_int IN VARCHAR2) RETURN VARCHAR2 IS
    ----------------------------------------------------------------------------------------------------------------------
    -- 對象名稱: f_dec_to_oct
    -- 對象描述: 十進制轉換八進制
    -- 輸入參數: p_str 十進制字符串
    -- 返回結果: 八進制字符串
    -- 測試用例: SELECT pkg_number_trans.f_dec_to_oct('1930') FROM dual;
    ----------------------------------------------------------------------------------------------------------------------
    v_return VARCHAR2(4000);
    v_bin    VARCHAR2(4000);
  BEGIN
    SELECT pkg_number_trans.f_dec_to_bin(p_int) INTO v_bin FROM dual;
    v_bin := substr('00' || v_bin, -3 * ceil(length(v_bin) / 3));
    SELECT f_stragg(data1) INTO v_return
      FROM (SELECT (CASE upper(substr(v_bin, (rownum - 1) * 3 + 1, 3))
                     WHEN '000' THEN '0'
                     WHEN '001' THEN '1'
                     WHEN '010' THEN '2'
                     WHEN '011' THEN '3'
                     WHEN '100' THEN '4'
                     WHEN '101' THEN '5'
                     WHEN '110' THEN '6'
                     WHEN '111' THEN '7'
                   END) data1
              FROM dual
            CONNECT BY rownum <= length(v_bin) / 3);
    RETURN v_return;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END f_dec_to_oct;
 
  FUNCTION f_dec_to_hex(p_int IN VARCHAR2) RETURN VARCHAR2 IS
    ----------------------------------------------------------------------------------------------------------------------
    -- 對象名稱: f_dec_to_oct
    -- 對象描述: 十進制轉換十六進制
    -- 輸入參數: p_str 十進制字符串
    -- 返回結果: 十六進制字符串
    -- 測試用例: SELECT pkg_number_trans.f_dec_to_hex('1930') FROM dual;
    ----------------------------------------------------------------------------------------------------------------------
    v_return VARCHAR2(4000);
  BEGIN
    SELECT upper(TRIM(to_char(p_int, 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'))) INTO v_return FROM dual;
    RETURN v_return;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END f_dec_to_hex;
 
  FUNCTION f_hex_to_bin(p_str IN VARCHAR2) RETURN VARCHAR2 IS
    ----------------------------------------------------------------------------------------------------------------------
    -- 對象名稱: f_dec_to_oct
    -- 對象描述: 十六進制轉換二進制
    -- 輸入參數: p_str 十六進制字符串
    -- 返回結果: 二進制字符串
    -- 測試用例: SELECT pkg_number_trans.f_hex_to_oct('78A') FROM dual;
    ----------------------------------------------------------------------------------------------------------------------
    v_return VARCHAR2(4000);
  BEGIN
    SELECT to_char(to_number(f_stragg(data1))) INTO v_return
      FROM (SELECT (CASE upper(substr(p_str, rownum, 1))
                     WHEN '0' THEN '0000'
                     WHEN '1' THEN '0001'
                     WHEN '2' THEN '0010'
                     WHEN '3' THEN '0011'
                     WHEN '4' THEN '0100'
                     WHEN '5' THEN '0101'
                     WHEN '6' THEN '0110'
                     WHEN '7' THEN '0111'
                     WHEN '8' THEN '1000'
                     WHEN '9' THEN '1001'
                     WHEN 'A' THEN '1010'
                     WHEN 'B' THEN '1011'
                     WHEN 'C' THEN '1100'
                     WHEN 'D' THEN '1101'
                     WHEN 'E' THEN '1110'
                     WHEN 'F' THEN '1111'
                   END) data1
              FROM dual
            CONNECT BY rownum <= length(p_str));
    RETURN v_return;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END f_hex_to_bin;
 
  FUNCTION f_hex_to_oct(p_str IN VARCHAR2) RETURN VARCHAR2 IS
    ----------------------------------------------------------------------------------------------------------------------
    -- 對象名稱: f_dec_to_oct
    -- 對象描述: 十六進制轉換八進制
    -- 輸入參數: p_str 十六進制字符串
    -- 返回結果: 八進制字符串
    -- 測試用例: SELECT pkg_number_trans.f_hex_to_oct('78A') FROM dual;
    ----------------------------------------------------------------------------------------------------------------------
    v_return VARCHAR2(4000);
    v_bin    VARCHAR2(4000);
  BEGIN
    SELECT pkg_number_trans.f_hex_to_bin(p_str) INTO v_bin FROM dual;
    SELECT pkg_number_trans.f_bin_to_oct(v_bin) INTO v_return FROM dual;
    RETURN v_return;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END f_hex_to_oct;
 
  FUNCTION f_hex_to_dec(p_str IN VARCHAR2) RETURN VARCHAR2 IS
    ----------------------------------------------------------------------------------------------------------------------
    -- 對象名稱: f_hex_to_dec
    -- 對象描述: 十六進制轉換十進制
    -- 輸入參數: p_str 十六進制字符串
    -- 返回結果: 十進制字符串
    -- 測試用例: SELECT pkg_number_trans.f_hex_to_dec('78A') FROM dual;
    ----------------------------------------------------------------------------------------------------------------------
    v_return  VARCHAR2(4000);
  BEGIN
    SELECT SUM(data1) INTO v_return
      FROM (SELECT (CASE upper(substr(p_str, rownum, 1))
                     WHEN 'A' THEN '10'
                     WHEN 'B' THEN '11'
                     WHEN 'C' THEN '12'
                     WHEN 'D' THEN '13'
                     WHEN 'E' THEN '14'
                     WHEN 'F' THEN '15'
                     ELSE substr(p_str, rownum, 1)
                   END) * power(16, length(p_str) - rownum) data1
              FROM dual
            CONNECT BY rownum <= length(p_str));
    RETURN v_return;
  EXCEPTION
    WHEN OTHERS THEN
      RETURN NULL;
  END f_hex_to_dec;
 
END pkg_number_trans;
/

CREATE OR REPLACE TYPE type_str_agg AS OBJECT
(
  total VARCHAR2(4000),

  STATIC FUNCTION odciaggregateinitialize(sctx IN OUT type_str_agg)
    RETURN NUMBER,

  MEMBER FUNCTION odciaggregateiterate
  (
    SELF  IN OUT type_str_agg,
    VALUE IN VARCHAR2
  ) RETURN NUMBER,

  MEMBER FUNCTION odciaggregateterminate
  (
    SELF        IN type_str_agg,
    returnvalue OUT VARCHAR2,
    flags       IN NUMBER
  ) RETURN NUMBER,

  MEMBER FUNCTION odciaggregatemerge
  (
    SELF IN OUT type_str_agg,
    ctx2 IN type_str_agg
  ) RETURN NUMBER
)
/
CREATE OR REPLACE TYPE BODY type_str_agg IS

  STATIC FUNCTION odciaggregateinitialize(sctx IN OUT type_str_agg)
    RETURN NUMBER IS
  BEGIN
    sctx := type_str_agg(NULL);
    RETURN odciconst.success;
  END;

  MEMBER FUNCTION odciaggregateiterate
  (
    SELF  IN OUT type_str_agg,
    VALUE IN VARCHAR2
  ) RETURN NUMBER IS
  BEGIN
    SELF.total := SELF.total || VALUE;
    RETURN odciconst.success;
  END;

  MEMBER FUNCTION odciaggregateterminate
  (
    SELF        IN type_str_agg,
    returnvalue OUT VARCHAR2,
    flags       IN NUMBER
  ) RETURN NUMBER IS
  BEGIN
    returnvalue := SELF.total;
    RETURN odciconst.success;
  END;

  MEMBER FUNCTION odciaggregatemerge
  (
    SELF IN OUT type_str_agg,
    ctx2 IN type_str_agg
  ) RETURN NUMBER IS
  BEGIN
    SELF.total := SELF.total || ctx2.total;
    RETURN odciconst.success;
  END;

END;
/




CREATE OR REPLACE FUNCTION f_stragg(p_input VARCHAR2) RETURN VARCHAR2
  PARALLEL_ENABLE
  AGGREGATE USING type_str_agg;
/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章