zoukankan      html  css  js  c++  java
  • 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  
    
    
  • 相关阅读:
    have you declared this activity in your AndroidManifest.xml?
    Android收回输入法的实现
    Android手机Home键重写
    Android屏幕点击事件重写
    拖动ListView列表时背景变黑
    AFNetworking vs ASIHTTPRequest vs MKNetworkKit
    libgif.so
    android.support.v4.widget.DrawerLayout
    Titanium vs PhoneGap
    Non-constant Fields in Case Labels
  • 原文地址:https://www.cnblogs.com/willspring/p/5818720.html
Copyright © 2011-2022 走看看