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 码字符
十进位十六进位 十进位十六进位 十进位十六进位 十进位十六进位
03220  056388 08050P 10468h
03321! 057399 08151Q 10569i
03422" 0583A: 08252R 1066Aj
03523# 0593B; 08353S 1076Bk
03624$ 0603C< 08454T 1086Cl
03725% 0613D= 08555U 1096Dm
03826& 0623E> 08656V 1106En
03927' 0633F? 08757W 1116Fo
04028( 06440@ 08858X 11270p
04129) 06541A 08959Y 11371q
0422A* 06642B 0905AZ 11472r
0432B+ 06743C 0915B[ 11573s
0442C, 06844D 0925C\ 11674t
0452D- 06945E 0935D] 11775u
0462E. 07046F 0945E^ 11876v
0472F/ 07147G 0955F_ 11977w
048300 07248H 09660` 12078x
049311 07349I 09761a 12179y
050322 0744AJ 09862b 1227Az
051333 0754BK 09963c 1237B{
052344 0764CL 10064d 1247C|
053355 0774DM 10165e 1257D}
054366 0784EN 10266f 1267E~
055377 0794FO 10367g 1277F 
 
   
posted on 2016-08-29 17:04 田灬禾 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/willspring/p/5818720.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值