当前位置:  数据库>oracle

Oracle varchar2或char类型的byte和char的区别

    来源: 互联网  发布时间:2017-06-26

    本文导语: Oracle定义字符串类型VARCHAR2和CHAR指定长度的用法如下: varchar2( ) 是介于1~4000之间的一个数,表示最多占用4000字节的存储空间。char( ) 是介于1~2000之间的一个数,表示最多占用2000字节的存储空间。那其中的BYTE和CHAR有什么区别呢BY...

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

varchar2( ) 是介于1~4000之间的一个数,表示最多占用4000字节的存储空间。
char( ) 是介于1~2000之间的一个数,表示最多占用2000字节的存储空间。
那其中的BYTE和CHAR有什么区别呢
BYTE,用字节指定:VARCHAR2(10 BYTE)。这能支持最多10字节的数据,在一个多字节字符集中,这可能只是两个字符。采用多字节字符集时,字节与字符并不相同。

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

使用UTF8之类的多字节字符集时,建议你在VARCHAR2/CHAR定义中使用CHAR修饰会,也就是说,使用VARCHAR2(30 CHAR),而不是VARCHAR2(30),因为你的本意很可能是定义一个实际上能存储30字符数据的列。还可以使用会话参数或系统参数NLS_LENGTH_SEMANTICS来修改默认行为,即把默认设置BYTE改为CHAR。不建议在系统级修改这个设置,而应该使用ALTER SESSION修改会话级。还有重要的一点,VARCHAR2中存储的字节数上界是4000。不过,即使你指定了VARCHAR(4000 CHAR),可能并不能在这个字段中放下4000个字符实际上,采用你选择的字符集时,如果所有字符都要用4个字节来表示,那么这个字段中就只能放下1000个字符!
下面使用一个小例子展示BYTE和CHAR之间的区别,并显示出上界的作用。
测试环境11.2.0.4,是在多字节字符集数据库上完成的,在此使用了字符集AL32UTF8,这个字符集支持最新版本的Unicode标准,采用一种变长方式对每个字符使用1~4个字节进行编码
linuxidc@ORCL>col value for a30
linuxidc@ORCL>col parameter for a30
linuxidc@ORCL>select * from nls_database_parameters where parameter='NLS_CHARACTERSET';
 
PARAMETER              VALUE
------------------------------ ------------------------------
NLS_CHARACTERSET          AL32UTF8
linuxidc@ORCL>show parameter nls_leng
 
NAME                    TYPE                VALUE
------------------------------------ --------------------------------- ------------------------------
nls_length_semantics            string                  BYTE

创建测试表

linuxidc@ORCL>create table t (a varchar2(1),b varchar2(1 char),c varchar2(4000 char));
 
Table created.

现在,这个表中插入一个UTF字符unistr('0d6'),这个字符长度为2个字节,可以观察到以下结果:
linuxidc@ORCL>select length(unistr('0d6')),lengthb(unistr('0d6')) from dual;
 
LENGTH(UNISTR('0D6')) LENGTHB(UNISTR('0D6'))
----------------------- ------------------------
              1            2 
 
linuxidc@ORCL>insert into t (a) values (unistr('0d6'));
insert into t (a) values (unistr('0d6'))
                          *
ERROR at line 1:
ORA-12899: value too large for column "ZX"."T"."A" (actual: 2, maximum: 1)

这说明:VARCHAR(1)的单位是字节而不是字符。这里确实只有一个Unicode字符,但是它在一个字节中放不下;将应用从单字节定宽字符集移植到一个多字节字符集时,可能会发现原来在字段中能放下的文本现在却无法放下。第二点的原因是:在一个单字节字符集中,包含20个字符的字符串长度就是20字节,完全可以在VARCHAR2(20)中放下。不过在一个多字节字符集中,20个字符的长度可以达到80字节(如果每个字符用4个字节表示),这样一杰,20个Unicode字符很可能无法在20个字节中放下。你可能会考虑将DDL修改为VARCHAR2(20 CHAR),或在运行DDL创建表时使用前面提到的NLS_LENGTH_SEMENTICS会话参数。
插入包含一个字符的字段时观察到以下结果:
linuxidc@ORCL>insert into t (b) values (unistr('0d6'));
 
1 row created. 
 
linuxidc@ORCL>col dump for a30
linuxidc@ORCL>select length(b),lengthb(b),dump(b) dump from t;
 
 LENGTH(B) LENGTHB(B) DUMP
---------- ---------- ------------------------------
    1    2 Typ=1 Len=2: 195,150

这个INSERT成功了,而且可以看到,所有插入数据的长度(LENGTH)就是一个字符,所有字符串函数都以字符为单位工作。LENGTHB函数(字节长度)显示出这个字段占用了2字节的存储空间,另外DUMP函数显示了这些字节到底是什么。这个例子展示了VARCHAR2(N)并不一定存储N个字符,而只是存储N个字节。
下面测试VARCHAR2(4000)可能存储不了4000个字符
linuxidc@ORCL>declare
  2  l_date varchar2(4000 char);
  3  l_ch  varchar2(1 char) := unistr('0d6');
  4  begin
  5  l_date:=rpad(l_ch,4000,l_ch);
  6  insert into t(c) values(l_date);
  7  end;
  8  /
declare
*
ERROR at line 1:
ORA-01461: can bind a LONG value only for insert into a LONG column
ORA-06512: at line 6

在此显示出,一个4000字符的实际上长度为8000字节,这样一个字符串无法永久地存储在一个VARCHAR(4000 char)字段中,这个字符串能放在PL/SQL变量中,因为在PL/SQL中VARCHAR2最大可以达到32K。不过,存储在表中,VARCHAR2则被硬性限制为最多只能存放4000字节。我们可以成功地存储其中2000个字符:
linuxidc@ORCL>declare
  2  l_date varchar2(4000 char);
  3  l_ch  varchar2(1 char) := unistr('0d6');
  4  begin
  5  l_date:=rpad(l_ch,2000,l_ch);
  6  insert into t(c) values(l_date);
  7  end;
  8  /
 
PL/SQL procedure successfully completed. 
 
linuxidc@ORCL>
zx@ORCL>select length(c),lengthb(c) from t where c is not null;
 
 LENGTH(C) LENGTHB(C)
---------- ----------
      2000      4000


    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • ORACLE数据库常用字段数据类型介绍
  • oracle中的空类型与c语言的空类型相匹配吗?
  • 关于Oracle BLOB类型,一个String字符怎么写入BLOB字段?
  • Oracle中查看某列数据类型
  • 测试添加Oracle中Blob数据类型对象
  • jsp文件上传smartupload到oracle数据库中没有longblob的数据类型如何处理的?
  • 请问保存文章内容的字段应用什么类型的(oracle),急!!!
  • oracle中怎么没有boolean类型的字段?应该用什么代替?
  • 如何向oracle库中字段类型是date的添加数据
  • 请问:ORACLE中的数据取出来后,需不需要进行一定的转换才能变为C语言的数据类型啊?
  • jsp中在oracle中查询日期类型时sql语句该怎么写啊?
  • 怎样将当前时间写到Oracle中date类型的字段中!!!!!!!!!!!!
  • 急!急!oracle 中 long 类型在 tomcat 中的问题
  • Oracle里long类型
  • Oracle中的Raw类型解释
  • 我要向oracle中插入大文本,用的是lang类型的字段,但是只能插3000字,再多就抱错,说我字符串过长。谁遇到过此问题?
  • Oracle返回表类型的自定义函数
  • 在Oracle的函数中,返回表类型的语句
  • 高分求救:谁用过JSP处理ORACLE数据库中的LONG RAW类型字段
  • 急死了! oracle中long数据类型问题! 重酬!!!
  • 讲解Oracle中的Clob与String类型转换
  • Oracle 12c发布简单介绍及官方下载地址
  • 在linux下安装oracle,如何设置让oracle自动启动!也就是让oracle那个服务自动启动,不是手动的
  • oracle 11g最新版官方下载地址
  • 请问su oracle 和su - oracle有什么不同?
  • Oracle 数据库(oracle Database)Select 多表关联查询方式
  • 虚拟机装Oracle R12与Oracle10g
  • Oracle数据库(Oracle Database)体系结构及基本组成介绍
  • Oracle 数据库开发工具 Oracle SQL Developer
  • 如何设置让Oracle SQL Developer显示的时间包含时分秒
  • Oracle EBS R12 支持 Oracle Database 11g


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3