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

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

varchar2(<SIZE> <BYTE|CHAR>) <SIZE>是介于1~4000之间的一个数,表示最多占用4000字节的存储空间。
char(<SIZE> <BYTE|CHAR>) <SIZE>是介于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个字节进行编码
[email protected]>col value for a30 
[email protected]>col parameter for a30 
[email protected]>select * from nls_database_parameters where parameter=‘NLS_CHARACTERSET‘; 
  
PARAMETER              VALUE 
------------------------------ ------------------------------ 
NLS_CHARACTERSET          AL32UTF8 
[email protected]>show parameter nls_leng 
  
NAME                    TYPE                VALUE 
------------------------------------ --------------------------------- ------------------------------ 
nls_length_semantics            string                  BYTE

创建测试表

[email protected]>create table t (a varchar2(1),b varchar2(1 char),c varchar2(4000 char)); 
  
Table created.

现在,这个表中插入一个UTF字符unistr(‘\00d6‘),这个字符长度为2个字节,可以观察到以下结果:
[email protected]>select length(unistr(‘\00d6‘)),lengthb(unistr(‘\00d6‘)) from dual; 
  
LENGTH(UNISTR(‘\00D6‘)) LENGTHB(UNISTR(‘\00D6‘)) 
----------------------- ------------------------ 
              1            2 
  
[email protected]>insert into t (a) values (unistr(‘\00d6‘)); 
insert into t (a) values (unistr(‘\00d6‘)) 
                          * 
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会话参数。
插入包含一个字符的字段时观察到以下结果:
[email protected]>insert into t (b) values (unistr(‘\00d6‘)); 
  
1 row created. 
  
[email protected]>col dump for a30 
[email protected]>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个字符
[email protected]>declare
  2  l_date varchar2(4000 char); 
  3  l_ch  varchar2(1 char) := unistr(‘\00d6‘); 
  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个字符:
[email protected]>declare
  2  l_date varchar2(4000 char); 
  3  l_ch  varchar2(1 char) := unistr(‘\00d6‘); 
  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. 
  
[email protected]> 
[email protected]>select length(c),lengthb(c) from t where c is not null; 
  
 LENGTH(C) LENGTHB(C) 
---------- ---------- 
      2000      4000

原文地址:http://www.linuxidc.com/Linux/2017-01/139853.htm

时间: 2024-10-10 02:49:41

Oracle varchar2或char类型的byte和char的区别的相关文章

char类型的数值转换

在视频教程中,你已经认识到了数字类型之间.字符串和其他类型之间的转换.而某些时候,我们还需要将char类型转换为int类型,或者把int类型转换为char类型. 这篇文章,将介绍在代码中虽然不太常用,但也需要了解的知识. char类型的数值转换 char转为int int转为char 字符数据的运算 char转为int 一个字符 '汉' 怎么可能转换为数字呢? 实际上是可以的,在之前的补充资料中已经说到,计算机对字符的存储,是使用某种编码规则对应的数字来存储的. 在C#语言中,使用Unicode

db2的char类型末尾都会以空格填充

查询姓"刘"且全名为2个汉字的学生的姓名: SELECT Sname FROM Student WHERE Sname LIKE '刘__'; 为什么没有结果呀?我把两下横线改为%后有结果出来,难道在DB2里面下横线不代表任意单个字符吗? 经过试验发现 db2的通配符"_" 只能匹配一个字节.db2情况下: char类型, db2的char类型末尾都会以空格填充的. 如果你的sname定义为char(8), 那么'刘xx'在数据库里面实际上保存的是'刘xx    

java对byte,short,char,int,long运算时自动类型转化情况说明

大家都知道,在进行运算时,java会隐式的自动进行类型转化,那么有哪些情况会进行转化呢?总结如下: 一.算术运算符 单目运算符:+(取正)-(取负) ++(自增1) --(自减1) 1.1 +(取正)-(取负) 当操作数是byte,short,char时,会自动转化为int类型:返回结果为int. 当操作数是int,long时,不转化,原来是啥类型,还是啥类型. 1.2 ++(自增1) --(自减1) 不管操作数是啥类型,不转化. 双目运算符:+ - * / %(取余) 1.3 + - * /

Java之byte、char和String类型相互转换

1 package basictype; 2 3 /** 4 * byte.char和String类型相互转换 5 */ 6 public class CHJavaType { 7 public static void main(String[] args) { 8 String string = "abcd"; 9 10 // String转char[] 11 char[] chars = string.toCharArray(); 12 for (char c : chars) {

Oracle Varchar2长度 及 PHP 长度判断

oracle数据库相信大家都比较熟悉,数据库中有一种非常常用的数据类型:字符串型.          对应该类型,在oracle中有三种比较常用的类型:varchar2(byte).varchar2(char).nvarchar2().          那么这三种类型到底有什么区别呢?          首先,我们要时刻记清:无论是varchar2还是nvarchar2,最大字节数都是4000. varchar2(byte):就是默认的表示方式,比如我们写成:varchar2(100),就相当

ORACLE VARCHAR2最大长度问题

VARCHAR2数据类型的最大长度问题,是一个让人迷惑的问题,因为VARCHAR2既分PL/SQL Data Types中的变量类型,也分Oracle Database中的字段类型.简单的说,要看你在什么应用场景下,否则难以回答VARCHAR2数据类型的最大长度问题. ORACLE数据库字段类型 关于Oracle Database中的字段的VARCHAR2类型的最大长度,我们先看下面的例子: SQL> create table test ( name varchar2(4001) ); crea

Oracle varchar2最大支持长度(转)

oerr ora 0650206502, 00000, "PL/SQL: numeric or value error%s"// *Cause: An arithmetic, numeric, string, conversion, or constraint error// occurred. For example, this error occurs if an attempt is made to// assign the value NULL to a variable de

OCCI处理CHAR类型字符串变量的不同

问题背景: 一个旧应用,原先应用是用proc写的,9i的库,现在应用需要改为使用OCCI,其中有一段查询逻辑:select ... where upper(state)=upper(:1). (此处请不要纠结于where条件中state字段使用了upper函数,因为此表数据量很小,且其历史比较悠久,未建索引.) 对应表中定义的state字段类型是char(3),但此处查询条件变量的值可能是两位,例如'NY'. 现象: 1. 使用sqlplus执行select ... where upper(st

ORACLE常用数据库字段类型

ORACLE常用数据库字段类型 常用的数据库字段类型如下: 字段类型 中文说明 限制条件 其它说明 CHAR 固定长度字符串 最大长度2000 bytes VARCHAR2 可变长度的字符串 最大长度4000 bytes  可做索引的最大长度749 NCHAR 根据字符集而定的固定长度字符串 最大长度2000 bytes NVARCHAR2 根据字符集而定的可变长度字符串 最大长度4000 bytes DATE 日期(日-月-年) DD-MM-YY(HH-MI-SS) 经过严格测试,无千虫问题