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] }
VARRAW的ORACLE內部定義是: 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 |