Oracle中的Char与Varchar的区别和实例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle中的Char与Varchar的区别和实例相关的知识,希望对你有一定的参考价值。

参考技术A

   CHAR的长度是固定的 而VARCHAR 的长度是可以变化的 比如 存储字符串“abc" 对于CHAR ( ) 表示你存储的字符将占 个字节(包括 个空字符) 在数据库中它是以空格占位的 而同样的VARCHAR ( )则只占用 个字节的长度 只是最大值 当你存储的字符小于 时 按实际长度存储

   CHAR的效率比VARCHAR 的效率稍高 看来cscm_number应该设成 char( )

   目前VARCHAR是VARCHAR 的同义词 工业标准的VARCHAR类型可以存储空字符串 但是Oracle不这样做 尽管它保留以后这样做的权利 Oracle自己开发了一个数据类型VARCHAR 这个类型不是一个标准的VARCHAR 它将在数据库中varchar列可以存储空字符串的特性改为存储NULL值 假如你想有向后兼容的能力 Oracle建议使用VARCHAR 而不是VARCHAR

  何时该用CHAR 何时该用varchar ?

  CHAR与VARCHAR 是一对矛盾的统一体 两者是互补的关系 VARCHAR 比CHAR节省空间 在效率上比CHAR会稍微差一些 即要想获得效率 就必须牺牲一定的空间 这也就是我们在数据库设计上常说的‘以空间换效率’ VARCHAR 虽然比CHAR节省空间 但是假如一个VARCHAR 列经常被修改 而且每次被修改的数据的长度不同 这会引起‘行迁移’(Row Migration)现象 而这造成多余的I/O 是数据库设计和调整中要尽力避免的 在这种情况下用CHAR代替VARCHAR 会更好一些

  关于char和varchar 的比较

  char类型与char型或字符常量的比较 在比较时使用补齐空格的方式进行比较

  varchar 类型与varchar 类型 char型和字符常量的比较 在比较时不补充空格 直接比较

  create table tt(A CHAR( ) A VARCHAR ( )) ;

  INSERT INTO TT VALUES( A A ) ;

  insert into tt values( A A ) ;

  MIT ;

   CHAR型与字符常量的比较 字符常量作为char型处理

   与 A 比较 返回 行 也就是在比较时自动将常量 A 右补齐空格后比较

  select * from tt where a = A ;

  A A

  

  A A

  A A

   与 A 比较 返回 行 也就是在比较时自动将常量 A 右补齐空格后比较

  select * from tt where a = A ;

  A A

  

  A A

  A A

   VARCHAR 与常量的比较 字符常量作为varchar 型处理

   与 A 比较 返回 行 也就是在比较时对 A 不做处理 直接比较

  select * from TT WHERE A = A ;

  A A

  

  A A

   与 A 比较 返回 行 也就是在比较时对 A 不做处理 直接比较

  select * from TT WHERE A = A ;

  A A

  

  A A

   当CHAR类型和VARCHAR 类型比较时 比较时对字段值是不作处理 直接比较的

   让A 和A 直接比较 此时是直接比较 有一条记录的A 和A 相同

  select * from tt where a =a ;

  A A

  

  A A

  但是当和decode函数配合使用时 出现不同的情况

  使用A 字段

  select decode(a A AAAA BBBB ) FROM TT ;

  DECODE(A A AAAA BBBB )

  

  BBBB

  BBBB

  虽然A 字段为char( ) 但是比较时并没有将常量 A 补空格再与字段A 做比较 而是直接进行比较 也就是将两个比较字段按照varchar 类型处理的

  因此比较时认为字段A 不等于常量 A 出现两条结果为 BBB 的记录

  进一步验证

  select decode(a A AAAA BBBB ) FROM TT ; 此处是两个空格

  DECODE(A A AAAA BBBB )

  

  BBBB

  BBBB

  还是返回两条 BBB 的记录 说明比较的不是按照char型的比较规则处理的

  使用A 字段

  select decode(a A AAAA BBBB ) FROM TT ;

  DECODE(A A AAAA BBBB )

  

  AAAA

  BBBB

  此时是正常的VARCHAR 类型之间的比较 第一条记录的A 字段等于 A 返回 AAA 第二行记录的A 字段为’A 比较时不等 返回 BBB

  当使用case表达式处理A 字段时 出现了与decode函数不同的处理结果

  使用字段A

  select case a when A then AAA else BBB end from tt ;

  CASEA WHEN A THEN AAA ELSE BBB

  

  AAA

  AAA

  在使用case语句中使用A 字段与常量 A 比较时 两个比较值按照char型的比较规则处理 在右补空格之后进行比较 因此返回两条记录

  进一步验证 如下

  select case a when A then AAA else BBB end from tt ;

  CASEA WHEN A THEN AAA ELSE BBB

  

  AAA

  AAA

  此时将常量改为 A 比较时仍视为char类型之间的比较 将字段A 补齐空格后与常量比较

  使用A 字段

  select case a when A then AAA else BBB end from tt ;

  CASEA WHEN A THEN AAA ELSE BBB

  

  AAA

  BBB

  此时是正常的VARCHAR 类型之间的比较 第一条记录的A 字段等于 A 返回 AAA 第二行记录的A 字段为’A 比较时不等 返回 BBB

  总结

  在使用decode函数对char字段做比较时 需要注意即使比较的两个字段都是char类型 但是decode函数是将其转化varchar 类型 进行处理 不遵循char型的比较规则

  对于char数据 在集合操作中 按照char的实际数据进行比较 而不是按照char型数据的比较规则进行的

  下面是一个简单例子

  create table t (name char( )) ;

  create table t (name char( )) ;

  begin

  for i in loop

  insert into t values(to_char(i)) ;

  insert into t values(to_char(i)) ;

  end loop ;

  mit;

  end ;

  select name from t minus select name from t ;

  NAME

  

  

  

  

  

  

  如果按照char型的比较规则 则不应该有返回值

  select anem from t intersect select name from t ;

  NAME

  

  无返回值 也说明集合操作时比较没有按照char型的比较规则

  ===============================评论 ============================

  对于decode和case对于char类型的差别 原因是由于case是表达式 而decode是函数

  函数中输入参数和返回值一般都定义为varchar 类型

  多谢指点 一时没有想到这里 看了一下decode函数的定义 如你所述 在使用decode的函数对char型数据进行类型转换

  下面是decode的函数的参数定义

  SQL> desc sys standard decode

  Parameter Type Mode Default?

  

  (RESULT) NUMBER

  EXPR NUMBER IN

  PAT NUMBER IN

  RES NUMBER IN

  (RESULT) VARCHAR

  EXPR NUMBER IN

  PAT NUMBER IN

  RES VARCHAR IN

  (RESULT) DATE

  EXPR NUMBER IN

  PAT NUMBER IN

  RES DATE IN

  (RESULT) NUMBER

  EXPR VARCHAR IN

  PAT VARCHAR IN

  RES NUMBER IN

  (RESULT) VARCHAR

  EXPR VARCHAR IN

  PAT VARCHAR IN

  RES VARCHAR IN

  (RESULT) DATE

  EXPR VARCHAR IN

  PAT VARCHAR IN

  RES DATE IN

  (RESULT) NUMBER

  EXPR DATE IN

  PAT DATE IN

  RES NUMBER IN

  (RESULT) VARCHAR

  EXPR DATE IN

  PAT DATE IN

  RES VARCHAR IN

  (RESULT) DATE

  EXPR DATE IN

  PAT DATE IN

  RES DATE IN

  (RESULT) SYS STANDARD

  EXPR SYS STANDARD IN

  PAT SYS STANDARD IN

  RES SYS STANDARD IN

  (RESULT) SYS STANDARD

  EXPR SYS STANDARD IN

  PAT SYS STANDARD IN

lishixinzhi/Article/program/Oracle/201311/19034

oracle之VARCHAR2(50 CHAR) 和VARCHAR2(50) 区别?

 

首先要明白的是:根据字符集不同,varchar2(50)这样在gbk可存25个汉字,utf8可存16个汉字

这里的50相当于50BYTE,是按字节计数,50CHAR是按字符计数。

对于多字节字符(如汉字),varchar2(50)仅能存储25个汉字,而varchar2(50char)能存储50个汉字。

以上是关于Oracle中的Char与Varchar的区别和实例的主要内容,如果未能解决你的问题,请参考以下文章

oracle中char的效率为啥比varchar的高一些了

oracle中 char,varchar,varchar2的区别

mysql中char和varchar有啥区别?

oracle之VARCHAR2(50 CHAR) 和VARCHAR2(50) 区别?

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

关于数据库中char,varchar,varchar的区别