Oracle raw類型


RAW(size):長度為size字節的原始二進制數據,size的最大值為2000字節;
  RAW類型好處:在網絡中的計算機之間傳輸 RAW 數據時,或者使用 Oracle 實用程序將 RAW 數據從一個數據庫移到另一個數據庫時,Oracle 服務器不執行字符集轉換。
  RAW,類似於CHAR,聲明方式RAW(L),L為長度,以字節為單位,作為數據庫列最大2000,作為變量最大32767字節。
  LONG RAW,類似於LONG,作為數據庫列最大存儲2G字節的數據,作為變量最大32760字節;

操作:  
create table raw_test (id number, raw_date raw(10)); 

insert into raw_test values (1, hextoraw('ff'));  
insert into raw_test values (2,UTL_RAW.cast_to_raw('abc'));  
insert into raw_test values (3,UTL_RAW.cast_to_raw('你好你你的'));

SELECT r.*,DUMP(r.raw_date),RAWTOHEX(r.raw_date),UTL_RAW.CAST_TO_VARCHAR2(r.raw_date) FROM raw_test r;
-----------------------------------------------------------------------------

ID    RAW_DATE    DUMP(R.RAW_DATE)        RAWTOHEX(R.RAW_DATE)    UTL_RAW.CAST_TO_VARCHAR2(R.RAW
1      FF        Typ=23 Len=1: 255        FF                  
2      616263      Typ=23 Len=3: 97,98,99     616263               abc
3    C4E3BAC3C4E3C4E3B5C4    Typ=23 Len=10: 196,227,186,195,196,227,196,227,181,196    C4E3BAC3C4E3C4E3B5C4    你好你你的

這里用到了幾個函數:

  1. UTL_RAW.CAST_TO_RAW:該函數按照缺省字符集(一般為GB2312),將VARCHAR2字符串轉換為RAW,直接把字符串中每個字符的ASCII碼存放到RAW類型的字段中。

  2.UTL_RAW.CAST_TO_VARCHAR2:該函數按照缺省字符集合(一般為GB2312),將RAW轉換為VARCHAR2。

  3.HEXTORAW(string):當使用HEXTORAW時,會把字符串中數據當作16進制數,String中的每兩個字符表示了結果RAW中的一個字節。

  4.RAWTOHEX(rawvalue):將RAW類數值rawvalue轉換為一個相應的十六進制表示的字符串. rawvalue中的每個字節都被轉換為一個雙字節的字符串. RAWTOHEX和HEXTORAW是兩個相反的函數.

  當使用HEXTORAW時,會把字符串中數據當作16進制數。
  而使用UTL_RAW.CAST_TO_RAW時,直接把字符串中每個字符的ASCII碼存放到RAW類型的字段中.

 

其實RAW和VARCHAR是類似的,只是存儲在RAW里的是二進制值,在任何時候不會做自動的字符集轉換,這是RAW和VARCHAR的不同,RAW只是一種外部類型,其內部存儲是VARRAW;

  VARCHAR的Oracle內部定義是:struct { ub2 len; char arr[n] }

  VARRAWORACLE內部定義是: struct { ub2 len; unsigned char arr[n] }

補充:

hextoraw():十六進制字符串轉換為raw;16進制不能超過F

sys@XXX> select hextoraw('abcdef') from dual;

HEXTOR
------
ABCDEF

錯誤結果:

sys@XXX> select hextoraw('G') from dual;
select hextoraw('G') from dual
                     *
ERROR at line 1:
ORA-01465: invalid hex number --把字符串“A”當作16進制,就是0x0A,這就算轉成raw了;
為了顯示出來給你看,所以又轉化成16進制,就是字符串“0A” SYS
@xxx> SELECT hextoraw('A') FROM dual; HE -- 0A

 

rawtohex():將raw串轉換為十六進制;

sys@ORCL> select rawtohex('aa') from dual;

RAWT
----
6161

--ASCII碼值轉換字符
SYS@XXX> SELECT CHR('97') FROM DUAL;

C
-
a

--字符轉換ASCII碼值
SYS@XXX> SELECT ASCII('a') FROM DUAL;

ASCII('A')
----------
        97

--十轉換16進制
SYS@XXX> select to_char('97','XXX') from dual;

TO_C
----
  61

--16進制轉換成十進制
SYS@XXX> SELECT to_number('61','XX') FROM dual;

TO_NUMBER('61','XX')
--------------------
                  97

結果之所以是6161是因為a的ASCII為97,65轉換為十六進制就是41。
 
        
SQL> select rawtohex(sysdate) from dual;
07D70B100A003100
SQL> select dump(sysdate,16) from dual;
Typ=13 Len=8: 7,d7,b,10,a,1,2,0
SQL> select rawtohex(12) from dual;
C10D
SQL> select dump(12,16) from dual;
Typ=2 Len=2: c1,d
SQL> select rawtohex('12') from dual;
3132
SQL> select dump('12',16) from dual;
Typ=96 Len=2: 31,32
可以看出rawtohex()函數參數可為date,number,char等類型,並自動轉化為相應16進制數據.
 
        

 


特殊情況:

sys@XXX>

declare a varchar2(100); begin select rawtohex('aa') into a from dual; dbms_output.put_line(a); end; / 6161 PL/SQL procedure successfully completed. sys@XXX>
declare a varchar2(100); begin a:=rawtohex('aa'); dbms_output.put_line(a); end; / AA PL/SQL procedure successfully completed.
 
        

原因在於:SELECT方法用的是SQL 引擎,而:=是用PL/SQL 引擎;

本例兩個調用中給的參數都是CHAR類型,這時ORACLE要進行缺省的類型轉換,把'aa'由CHAR轉到RAW。
但是SQL引擎和PL/SQL引擎的這個類型轉換卻不一樣,SQL引擎使用了utl_raw.cast_to_raw,所以最后結果是'6161',PL/SQL使用了HEXTORAW
因此在用到rawtohex()函數時,不應該給它自動類型轉換的機會,因為這是最容易出錯的。
如果你期待的結果是'6161'就該這樣寫:rawtohex(utl_raw.cast_to_raw('aa'))
如果你期待的結果是'AA'就該這樣寫:rawtohex(hextoraw('aa'))

不管哪個引擎都不會錯了。

 
ASCII 碼 字符   ASCII 碼 字符   ASCII 碼 字符   ASCII 碼 字符
十進位 十六進位   十進位 十六進位   十進位 十六進位   十進位 十六進位
032 20     056 38 8   080 50 P   104 68 h
033 21 !   057 39 9   081 51 Q   105 69 i
034 22 "   058 3A :   082 52 R   106 6A j
035 23 #   059 3B ;   083 53 S   107 6B k
036 24 $   060 3C <   084 54 T   108 6C l
037 25 %   061 3D =   085 55 U   109 6D m
038 26 &   062 3E >   086 56 V   110 6E n
039 27 '   063 3F ?   087 57 W   111 6F o
040 28 (   064 40 @   088 58 X   112 70 p
041 29 )   065 41 A   089 59 Y   113 71 q
042 2A *   066 42 B   090 5A Z   114 72 r
043 2B +   067 43 C   091 5B [   115 73 s
044 2C ,   068 44 D   092 5C \   116 74 t
045 2D -   069 45 E   093 5D ]   117 75 u
046 2E .   070 46 F   094 5E ^   118 76 v
047 2F /   071 47 G   095 5F _   119 77 w
048 30 0   072 48 H   096 60 `   120 78 x
049 31 1   073 49 I   097 61 a   121 79 y
050 32 2   074 4A J   098 62 b   122 7A z
051 33 3   075 4B K   099 63 c   123 7B {
052 34 4   076 4C L   100 64 d   124 7C |
053 35 5   077 4D M   101 65 e   125 7D }
054 36 6   078 4E N   102 66 f   126 7E ~
055 37 7   079 4F O   103 67 g   127 7F  
 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM