ORACLE使用函式對二進位制、十進位制、十六進位制數互相轉換

還不算暈發表於2013-11-03

文中涉及:

十進位制與十六進位制的互相轉換

二進位制與十進位制的互相轉換

二進位制與十六進位制的互相轉換

1.將十進位制的數轉換為十六進位制的數請使用to_char函式。

資料庫中16進位制的表達是按照字串來描述的,所以將十進位制的數轉換為十六進位制的數使用to_char函式
BYS@bys1>select to_char(10,'xxx'), to_char(42,'xxx') from dual;
TO_C TO_C
---- ----
   a   2a
   

2.將十六進位制的數轉換為十進位制的數請使用to_number函式。

如下,16進位制A是10.2A是2*16+A=42.注意xxx,如果轉換的數比較大,要多寫幾個,避免位數不足而報錯。
BYS@bys1>select to_number('a','xxx'), to_number('2a','xxx') from dual;
TO_NUMBER('A','XXX') TO_NUMBER('2A','XXX')
-------------------- ---------------------
                  10                    42
####################################################
ORACLE未提供二進位制與十進位制互轉的函式,可以自己建立。以下十進位制與二進位制轉換指令碼引自惜紛飛部落格,感謝!

3.十進位制轉換二進位制--使用自定義函式

CREATE OR REPLACE FUNCTION NUMBER_TO_BIT(V_NUM NUMBER)
RETURN VARCHAR IS V_RTN VARCHAR(8);--注意返回列長度
  V_N1  NUMBER;
  V_N2  NUMBER;
BEGIN
V_N1 := V_NUM;
    LOOP
      V_N2  := MOD(V_N1, 2);
      V_N1  := ABS(TRUNC(V_N1 / 2));
      V_RTN := TO_CHAR(V_N2) || V_RTN;
      EXIT WHEN V_N1 = 0;
    END LOOP;
--返回二進位制長度
 SELECT lpad(V_RTN,8,0)
    INTO   V_RTN
    FROM dual;
return V_RTN;
end;

BYS@bys1>col a255 for a20
BYS@bys1>col a1 for a20
BYS@bys1>select number_to_bit(255) as a255,number_to_bit(1) as a1 from dual;
A255                 A1
-------------------- --------------------
11111111             00000001

4.二進位制轉換十進位制--使用自定義函式

CREATE OR REPLACE FUNCTION BIT_TO_NUMBER(P_BIN IN VARCHAR2) RETURN NUMBER AS
  V_SQL    VARCHAR2(30000) := 'SELECT BIN_TO_NUM(';
  V_RETURN NUMBER;
BEGIN
  IF LENGTH(P_BIN) >= 256 THEN
    RAISE_APPLICATION_ERROR(-20001, 'INPUT BIN TOO LONG!');
  END IF;
  IF LTRIM(P_BIN, '01') IS NOT NULL THEN
    RAISE_APPLICATION_ERROR(-20002, 'INPUT STR IS NOT VALID BIN VALUE!');
  END IF;
  FOR I IN 1 .. LENGTH(P_BIN) LOOP
    V_SQL := V_SQL || SUBSTR(P_BIN, I, 1) || ',';
  END LOOP;
  V_SQL := RTRIM(V_SQL, ',') || ') FROM DUAL';
  EXECUTE IMMEDIATE V_SQL
    INTO V_RETURN;
  RETURN V_RETURN;
END;
 
BYS@bys1>select bit_to_number('11111111') from dual;
BIT_TO_NUMBER('11111111')
-------------------------

                      255

5.關於建立公有同義詞解決其它使用者引用當前使用者的定義函式的問題:

當前BYS使用者為DBA使用者,其它使用者預設無法使用當前使用者的自定義函式。關於同義詞,更詳細:http://blog.csdn.net/q947817003/article/details/14104519

可以將自定義函式的執行許可權授予PUBLIC使用者,並建立公有同義詞。這樣其它使用者就可以通過引用公有同義詞來使用新建的自定義函式了。
BYS@bys1>select * from user_objects where object_type='FUNCTION';
OBJECT_NAME          SUBOBJECT_NAME                  OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE
-------------------- ------------------------------ ---------- -------------- -------------------
CREATED             LAST_DDL_TIME       TIMESTAMP           STATUS  T G S  NAMESPACE
------------------- ------------------- ------------------- ------- - - - ----------
EDITION_NAME
------------------------------
NUMBER_TO_BIT                                            76930                FUNCTION
2013/11/03 11:57:30 2013/11/03 11:57:30 2013-11-03:11:57:30 VALID   N N N          1

BIT_TO_NUMBER                                            76931                FUNCTION
2013/11/03 12:00:16 2013/11/03 12:00:16 2013-11-03:12:00:16 VALID   N N N          1
建立公有同義詞--先不將函式執行許可權授予PUBLIC,此時從其它使用者使用函式報錯。
BYS@bys1>create public synonym number_to_bit for number_to_bit;
Synonym created.
BYS@bys1>conn test/test
Connected.
TEST@bys1>select number_to_bit(255) from dual;
select number_to_bit(255) from dual
       *
ERROR at line 1:
ORA-00904: : invalid identifier
將函式執行許可權授予PUBLIC,此時從其它使用者可以正常使用函式。
TEST@bys1>conn bys/bys
Connected.
BYS@bys1>grant execute on number_to_bit to public;
Grant succeeded.
BYS@bys1>conn test/test
Connected.
TEST@bys1>select number_to_bit(255) from dual;
NUMBER_TO_BIT(255)
----------------------------------------------------------------------------------------------------
11111111
#########################

對於bit_to_number函式,先將函式執行許可權授予PUBLIC,但是並未建立同義詞。此時使用其它使用者執行函式報錯

BYS@bys1>grant execute on bit_to_number to public;
Grant succeeded.

TEST1@bys1>select bit_to_number(11111111) from dual;
select bit_to_number(11111111) from dual
       *
ERROR at line 1:
ORA-00904: "BIT_TO_NUMBER": invalid identifier

TEST1@bys1>conn bys/bys
Connected.

此時對函式建立公有同義詞,使用其它使用者可以正常執行函式。
B
YS@bys1>create public synonym bit_to_number for bit_to_number;
Synonym created.
BYS@bys1>conn test1/test1
Connected.
TEST1@bys1>select bit_to_number(11111111) from dual;
BIT_TO_NUMBER(11111111)
-----------------------
                    255

###################################################################

6.二進位制與十六進位制的轉換

因為沒有直接的函式,但是結合以上的十進位制轉二進位制與十進位制轉十六進位制函式,可以通過函式巢狀來實現二進位制與十六進位制的轉換。

即先使用二進位制與十進位制的轉換,再將轉換成的十進位制做為引數轉換為十六進位制。

BYS@bys1>select number_to_bit(17) as a255 from dual;
A255
--------------------
00010001
下面語句得出16進位制數11,換算成十進位制是17,轉換正確完成。
BYS@bys1>select to_char(bit_to_number('00010001'),'xxx') from dual;
TO_C
----
  11

7.十六進位制與二進位制的轉換

BYS@bys1> select to_number('11','xxx') from dual;
TO_NUMBER('11','XXX')
---------------------
                   17
下面語句可以將16進位制轉成二進位制,與上面語句對比,轉換結果正確。
BYS@bys1> select number_to_bit(to_number('11','xxx')) from dual;
NUMBER_TO_BIT(TO_NUMBER('11','XXX'))
----------------------------------------------------------------------------------------------------
00010001

##############################################################################

8.其它轉換函式:

HEXTORAW

語法: HEXTORAW(string)
功能: 將由string表示的二進位制數值轉換為一個RAW數值. String應該包含一個十六進位制的數值. String中的每兩個字元表示了結果RAW中的一個位元組..HEXTORAW和RAWTOHEX為相反的兩個函式.
使用位置: 過程性語言和SQL語句。

BYS@bys1>select hextoraw('abcdef') from dual;
HEXTOR
------
ABCDEF

RAWTOHEX
語法: RAWTOHEX(rawvalue)
功能: 將RAW類數值rawvalue轉換為一個相應的十六進位制表示的字串. rawvalue中的每個位元組都被轉換為一個雙位元組的字串. RAWTOHEX和HEXTORAW是兩個相反的函式.
使用位置: 過程性語言和SQL語句。
BYS@bys1>SELECT RAWTOHEX('11') FROM DUAL;
RAWT
----
3131
BYS@bys1>SELECT RAWTOHEX('1') FROM DUAL;
RA
--
31
BYS@bys1>SELECT RAWTOHEX('2') FROM DUAL;
RA
--
32

RAWTONHEX
語法: RAWTONHEX(rawvalue)
功能: 將RAW型別值rawvalue轉換為一個十六進位制表示的字串。rawvalue中的每個位元組轉換為一個雙字元的字串。RAWTONHEX返回值是NVARCHAR2型別而不是VARCHAR2型別。
使用位置: 過程性語言和SQL語句。

相關文章