Oracle中的進制轉(zhuǎn)換
?
?
?
Oracle里二進制、八進制、十進制、十六進制之間的互相轉(zhuǎn)換
--各進制之間轉(zhuǎn)換
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;
/
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
-- 對象描述: 二進制轉(zhuǎn)換八進制
-- 輸入?yún)?shù): p_str 二進制字符串
-- 返回結(jié)果: 八進制字符串
-- 測試用例: SELECT pkg_number_trans.f_bin_to_oct('11110001010') FROM dual;
-- 備 注: 需要定義f_stragg函數(shù)和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
-- 對象描述: 二進制轉(zhuǎn)換十進制
-- 輸入?yún)?shù): p_str 二進制字符串
-- 返回結(jié)果: 十進制字符串
-- 測試用例: 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
-- 對象描述: 二進制轉(zhuǎn)換十六進制
-- 輸入?yún)?shù): p_str 二進制字符串
-- 返回結(jié)果: 十六進制字符串
-- 測試用例: SELECT pkg_number_trans.f_bin_to_oct('11110001010') FROM dual;
-- 備 注: 需要定義f_stragg函數(shù)和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
-- 對象描述: 八進制轉(zhuǎn)換二進制
-- 輸入?yún)?shù): p_str 八進制字符串
-- 返回結(jié)果: 二進制字符串
-- 測試用例: SELECT pkg_number_trans.f_oct_to_bin('3612') FROM dual;
-- 備 注: 需要定義f_stragg函數(shù)和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
-- 對象描述: 八進制轉(zhuǎn)換十進制
-- 輸入?yún)?shù): p_str 八進制字符串
-- 返回結(jié)果: 十進制字符串
-- 測試用例: 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
-- 對象描述: 八進制轉(zhuǎn)換十六進制
-- 輸入?yún)?shù): p_str 八進制字符串
-- 返回結(jié)果: 十六進制字符串
-- 測試用例: 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
-- 對象描述: 十進制轉(zhuǎn)換二進制
-- 輸入?yún)?shù): p_str 十進制字符串
-- 返回結(jié)果: 二進制字符串
-- 測試用例: 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
-- 對象描述: 十進制轉(zhuǎn)換八進制
-- 輸入?yún)?shù): p_str 十進制字符串
-- 返回結(jié)果: 八進制字符串
-- 測試用例: 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
-- 對象描述: 十進制轉(zhuǎn)換十六進制
-- 輸入?yún)?shù): p_str 十進制字符串
-- 返回結(jié)果: 十六進制字符串
-- 測試用例: 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
-- 對象描述: 十六進制轉(zhuǎn)換二進制
-- 輸入?yún)?shù): p_str 十六進制字符串
-- 返回結(jié)果: 二進制字符串
-- 測試用例: 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
-- 對象描述: 十六進制轉(zhuǎn)換八進制
-- 輸入?yún)?shù): p_str 十六進制字符串
-- 返回結(jié)果: 八進制字符串
-- 測試用例: 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
-- 對象描述: 十六進制轉(zhuǎn)換十進制
-- 輸入?yún)?shù): p_str 十六進制字符串
-- 返回結(jié)果: 十進制字符串
-- 測試用例: 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;
/
?
?
?
?
?
?
另外再轉(zhuǎn)一篇比較簡單的做法:
---------------------------------------------------------------------------------
?
?
進制轉(zhuǎn)換是開發(fā)中經(jīng)常需要用到的,本文簡單介紹幾種常用的進制轉(zhuǎn)化方法.
一 16進制轉(zhuǎn)換為10進制
可以通過to_number函數(shù)實現(xiàn)
SQL> select to_number(’19f’,’xxx’) from dual;
TO_NUMBER(’19F’,’XXX’)
----------------------
415
SQL> select to_number(’f’,’xx’) from dual;
TO_NUMBER(’F’,’XX’)
-------------------
15
二 10進制轉(zhuǎn)換為16進制
可以通過to_char函數(shù)轉(zhuǎn)換
SQL> select to_char(123,’xxx’) from dual;
TO_C
----
7b
SQL> select to_char(4567,’xxxx’) from dual;
TO_CH
-----
11d7
三 2進制轉(zhuǎn)換為10進制
從Oracle9i開始,提供函數(shù)bin_to_num進行2進制到10進制的轉(zhuǎn)換
SQL> select bin_to_num(1,1,0,1) a,bin_to_num(1,0) b from dual;
A ??? B
----- ----------
13 ?? 2
SQL> select bin_to_num(1,1,1,0,1) from dual;
BIN_TO_NUM(1,1,1,0,1)
---------------------
29
四 通過自定義函數(shù)實現(xiàn)進制轉(zhuǎn)換
以下函數(shù)來自AskTom網(wǎng)站,是Tom給出的例子,供參考:
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;
/
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
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;
/
?