zoukankan      html  css  js  c++  java
  • 转Oracle 数据类型及存储方式 【B】

    §1.5  NCHAR和NVARCHAR2
    如果系统需要集中管理和存储多种字符集,就需要使用这两种字符类型。在使用NCAHR和NVARCHAR2时,文本内容采用国家字符集来存储和管理。而不是默认字符集。
    这两种类型的长度指的是字符数,而不是字节数。
    NLS国家语言支持(National Language Support)
    在oracle 9i及以后的版本,数据库的国家字符集可以是:utf-8和AL16UTF-16两种。
    Oracle 9i是utf -8, Oralce 10g是AL16UTF-16.

    1.新建一个表,有两列,类型分别为:nchar和nvarchar2.长度都为10
    SQL> create table test_nvarchar(col_nchar nchar(10),col_nvarchar2 nvarchar2(10));
    Table created

    2.插入一些数据
    SQL> insert into test_nvarchar values('袁','袁光东');
    1 row inserted
    SQL> insert into test_nvarchar values(N'袁',N'袁光东');
    1 row inserted
    (在9i之前的版本,插入时加上N时,在处理时跟普通方式有不同的方式。但是在10g的时候已经有了改变,加不加N都是一样,这里只是为了测试)
    SQL> insert into test_nvarchar values('a','b');

    1 row inserted
    插入一行英文字母

    3. 查看每行的col_nchar列的存储方式。
    SQL> select col_nchar, dump(col_nchar) from test_nvarchar;

    COL_NCHAR            DUMP(COL_NCHAR)
    -------------------- --------------------------------------------------------------------------------
    袁                   Typ=96 Len=20: 136,129,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32
    a                    Typ=96 Len=20: 0,97,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32
    袁                   Typ=96 Len=20: 136,129,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32,0,32

    Typ=96 与char的类型编码一样。
    Len=20 每一行的长度都是20字节。这一点跟char一样。都是定长的,会以空格填充。
    需要注意的是:统统以两位来表示一个字符。
    136,129 表示’袁’
    0,97 表示’a’
    0,32 表示空格。

    4. nvarchar2的储存
    SQL> select col_nvarchar2, dump(col_nvarchar2) from test_nvarchar;

    COL_NVARCHAR2        DUMP(COL_NVARCHAR2)
    -------------------- --------------------------------------------------------------------------------
    袁光东               Typ=1 Len=6: 136,129,81,73,78,28
    b                    Typ=1 Len=2: 0,98
    袁光东               Typ=1 Len=6: 136,129,81,73,78,28

    Typ=1 与varchar2一样。
    每一行的len值都不样同。不会使用空格进行填充。
    每一个字符都占有两个字节两进行存储。
    b 存储为: 0, 98
    袁 存储为: 136,129

    5.nchar和nvarchar2的数据定义。
    SQL> desc test_nvarchar;
    Name          Type          Nullable Default Comments
    ------------- ------------- -------- ------- --------
    COL_NCHAR     NCHAR(20)     Y                        
    COL_NVARCHAR2 NVARCHAR2(20) Y   

    虽然在定义nchar和nvarchar2时,指定的长度是指字符数。但是表结构的定义中,仍然是存储着它的字节数。
    在定义时nchar(10)表示可以最大存储10个字符。
    在查看数据表结构时,显示该列最大占用的字节数。


    需要注意的是:在char和nchar中对汉字的实际存储值是不一样的。因为采用了不同的字符集,就有了不同的字符编码。

    SQL> insert into test_varchar values('袁');

    1 row inserted
    SQL> select col, dump(col) from test_varchar where col='袁';

    COL        DUMP(COL)
    ---------- --------------------------------------------------------------------------------
    袁         Typ=1 Len=2: 212,172
    这时采用的字符集系统默认字符集ZHS16GBK。
    这里很容易的把它转换成ascii码。
    高位 * 256(2的8次方) + 低位.
    212 * 256 + 172 = 54444

    SQL> select chr(54444) from dual;

    CHR(54444)
    ----------


    而在Nchar 和Nvarchar中,采用的是UTF-8或UTF-16的字符集。

    SQL> insert into test_nvarchar values('袁','袁');

    1 row inserted

    SQL> select col_nvarchar2, dump(col_nvarchar2) from test_nvarchar where col_nvarchar2='袁';

    COL_NVARCHAR2        DUMP(COL_NVARCHAR2)
    -------------------- --------------------------------------------------------------------------------
    袁                   Typ=1 Len=2: 136,129

    ‘袁’存储的值为:136,129
    Oracle 10以上对nchar和nvarchar都采用utf-16字符集了。它的好处就是对字符采用固定长度的字节存储(2字节),支持多国字符,在操作效率上会更高。但是它却无法兼容于ascii码。
    §1.6  RAW
    RAW与CHAR和VARCHAR2相比。RAW属于二进制数据,更可以把它称为二进制串。在对CHAR和VARCHAR2类型进行存储时,会进行字符集转换。而对二进制数据进行存储则不会进行字符集转换。
    SQL> create table test_raw (col_chr varchar2(10), col_raw raw(10));

    Table created
    SQL> insert into test_raw values('aa','aa');

    1 row inserted

    SQL> commit;

    Commit complete

    SQL> select * from test_raw;

    COL_CHR    COL_RAW
    ---------- --------------------
    aa         AA

    SQL> select col_chr,dump(col_chr) from test_raw;

    COL_CHR    DUMP(COL_CHR)
    ---------- --------------------------------------------------------------------------------
    aa         Typ=1 Len=2: 97,97
    SQL> select col_raw,dump(col_raw) from test_raw;

    COL_RAW              DUMP(COL_RAW)
    -------------------- --------------------------------------------------------------------------------
    AA                   Typ=23 Len=1: 170

    通过上面的分析,虽然我们通过select查询得到的结果,raw列显示为插入的字符。但是我们通过dump函数得知到raw并不是以字符的方式存储。它是把插入的字符认为是16进制的值。
    比如本例,我们向raw列插入aa,但是它占用的空间为1个字节。值为170.
    170转为16进制正好是aa
    向raw列插入数据时会发生一个隐式转换HEXTORAW
    从raw列读取数据时会发生一个隐式转换RAWTOHEX

    如果向raw列插入值不是有效的十六进制值时,会报错的。
    SQL> insert into test_raw values('h','h');

    insert into test_raw values('h','h')

    ORA-01465: invalid hex number
  • 相关阅读:
    I can do more…
    在希望的田野上
    卓越管理培训笔记
    Python 学习小计
    谈谈“直抒己见”
    [更新]关于博客园不支持RSS全文输出的解决方案
    效率生活二三事
    个人阅读解决方案
    Oracle函数sys_connect_by_path 详解
    基础班-模板配置
  • 原文地址:https://www.cnblogs.com/linsond/p/1767964.html
Copyright © 2011-2022 走看看