甲骨文中的字节和字符有什么区别呢?

  

甲骨文定义字符串类型VARCHAR2和CHAR指定长度的用法如下:

VARCHAR2 (& lt; SIZE>| & lt;字节CHAR>) & lt; SIZE>是介于1 ~ 4000之间的一个数,表示最多占用4000字节的存储空间。

字符(& lt; SIZE>| & lt;字节CHAR>) & lt; SIZE>是介于1 ~ 2000之间的一个数,表示最多占用2000字节的存储空间。

那其中的字节和字符有什么区别呢

<李>

字节,用字节指定:VARCHAR2(10字节)。这能支持最10字多节的数据,在一个多字节字符集中,这可能只是两个字符。采用多字节字符集时,字节与字符并不相同。

<李>

字符,用字符指定:VARCHAR2 (10 CHAR)。这将支持最多10字符数据,可能是多达40字节的信息。另外,VARCHAR2(4000字符)理论上支持最多4000个字符的数据,不过由于甲骨文中字符串数据类型限制为4000字节,所以可能无法得到全部4000个字符。

使用UTF8之类的多字节字符集时,建议你在VARCHAR2/字符定义中使用CHAR修饰会,也就是说,使用VARCHAR2(30个字符),而不是VARCHAR2(30),因为你的本意很可能是定义一个实际上能存储30字符数据的列。还可以使用会话参数或系统参数NLS_LENGTH_SEMANTICS来修改默认行为,即把默认设置字节改为CHAR。不建议在系统级修改这个设置,而应该使用改变会话修改会话级。还有重要的一点,VARCHAR2中存储的字节数上界是4000。不过,即使你指定了VARCHAR(4000字符),可能并不能在这个字段中放下4000个字符实际上,采用你选择的字符集时,如果所有字符都要用4个字节来表示,那么这个字段中就只能放下1000个字符!

下面使用一个小例子展示字节和字符之间的区别,并显示出上界的作用。

测试环境11.2.0.4,是在多字节字符集数据库上完成的,在此使用了字符集AL32UTF8,这个字符集支持最新版本的Unicode标准,采用一种变长方式对每个字符使用1 ~ 4个字节进行编码

zx@ORCL> col  value  for 故事本来   zx@ORCL> col  parameter  for 故事本来   zx@ORCL> select  *,得到nls_database_parameters  where 参数=& # 39;NLS_CHARACTERSET& # 39;;      参数,,,,,,,的值   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -,- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   nls_characterset,,,,,, AL32UTF8   zx@ORCL> show  parameter  nls_leng      的名字,,,,,类型,,,,,,,的值   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -,- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -女人,- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   nls_length_semantics,,,,,字符串,,,,,,,字节

创建测试表

zx@ORCL> create  table  t  (a  varchar2 (1) b  varchar2 (1, char) c  varchar2 (4000, char));      Table 创建。

现在,这个表中插入一个UTF字符unistr (& # 39; \ 00 d6 # 39;),这个字符长度为2个字节,可以观察到以下结果:

zx@ORCL> select 长度(unistr (& # 39; \ 00 d6 # 39;)), lengthb (unistr (& # 39; \ 00 d6 # 39;)),得到双;      长度(UNISTR (& # 39; \ 00 d6 # 39;)), LENGTHB (UNISTR (& # 39; \ 00 d6 # 39;))   - - - - - - - - - - - - - - - - - - - - - - -女人,- - - - - - - - - - - - - - - - - - - - - - - -   ,,,,,1,,,,,,,2      zx@ORCL> insert  into  t  (a), values  (unistr (& # 39; \ 00 d6 # 39;));   insert  into  t (一),values  (unistr (& # 39; \ 00 d6 # 39;))   ,,,,,,,,,,,,,,,,,,,,,,,,,   ERROR  at  line  1:   ora - 12899: value  too  large  for  column “ZX"干净T"干净A",(实际:2,最大:,1)

这说明:VARCHAR(1)的单位是字节而不是字符。这里确实只有一个Unicode字符,但是它在一个字节中放不下,将应用从单字节定宽字符集移植到一个多字节字符集时,可能会发现原来在字段中能放下的文本现在却无法放下。第二点的原因是:在一个单字节字符集中,包含20个字符的字符串长度就是20字节,完全可以在VARCHAR2(20)中放下。不过在一个多字节字符集中,20个字符的长度可以达到80字节(如果每个字符用4个字节表示),这样一杰,20个Unicode字符很可能无法在20个字节中放下。你可能会考虑将DDL修改为VARCHAR2(20个字符),或在运行DDL创建表时使用前面提到的NLS_LENGTH_SEMENTICS会话参数。

插入包含一个字符的字段时观察到以下结果:

zx@ORCL> insert  into  t  (b), values  (unistr (& # 39; \ 00 d6 # 39;));      1,row 创建。      zx@ORCL> col  dump  for 故事本来   zx@ORCL> select  (b)长度,lengthb (b),转储(b), dump 得到t;      ,长度(B) LENGTHB (B),转储   - - - - - - - - - - -,- - - - - - - - - - -,- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -   ,,1,,2,Typ=1, Len=2:, 195150

甲骨文中的字节和字符有什么区别呢?