oracle字符类型对比认识在oracle9i以上版本里,我们再为字符串选择数据类型时,主要就是三种:CHAR(size),VARCHAR2(size),NVARCHAR2(size)。
VARCHAR2(size):可变长度的字符串,其最大长度为 size 个字节。size 的最大值是 4000,而最小值是 1。您必须指定一个 VARCHAR2 的 size。
CHAR(size):固定字节字符串,最大长度为size个字节,size最大长度为2000
NVARCHAR2(size):可变长度的字符串,它在存储字符时,是根据所选的国家字符集来计算字符占用的字节数,其最大长度为 size 个字符或字节。size 的最大值取决于存储每个字符所需要的字节数,其上限为 4000 个字节。您必须为 NVARCHAR2 指定一个 size。VARCHAR2与NVARCHAR2的不同之处在于它们存放信息占用的空间不同。VARCHAR2存放的英文字符只占一个字节,而NVARCHAR2依据所选的字符集,大多为两个。
既然提到字符集,那就简单了解下字符编码
对于多国语言,在计算机世界里,常用的字符编码有:ASCII,ANSI编码(本地),UNICODE编码(国际化)。这三种编码方法只是概念,如果要在计算机实际环境里实现,就需要不同的算法标准完成。
ASCII:
是通过一种单字节编码实现的,具体有7位编码和8位编码。
ANSI编码(本地化):
是一种多字节编码,是不同的国家根据表示自己的语言的一种编码方式,因为不同ANSI编码采用不同规定标准,如果一个多字节字符串采用非正确的ANSi编码,将会“乱码“。
UNICODE(国际化):
在计算机世界里,为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。虽然UNICODE的一个字符编码是确定的,但是在实际存储或传输中,由于不同系统平台的设计不一定一致,以及出于节省空间的目的,对Unicode编码的实现方式有所不同。Unicode的实现方式称为Unicode转换格式(Unicode Translation Format,简称为UTF)。目前实际应用的Unicode版本对应于UCS-2,使用16位的编码空间。也就是每个字符占用2个字节。
如果对于某些字符可以一个字节表示的,如果要用原Unicode编码,那实在是太浪费了啊,可以使用UTF-8编码,这是一种变长编码,它将基本7位ASCII字符仍用7位编码表示,占用一个字节(首位补0)。而遇到与其他Unicode字符混合的情况,将按一定算法转换,每个字符使用1-3个字节编码,并利用首位为0或1进行识别。这样对以7位ASCII字符为主的西文文档就大大节省了编码长度。类似的,对未来会出现的需要4个字节编码的字符,2字节编码的UTF-16也需要通过一定的算法进行转换。
UTF-8和UTF-16只是UNICODE编码在计算机里的实现。
Unicode的实现方式除了以上的方式外,还包括UTF-7、Punycode、CESU-8、SCSU、UTF-32等,这些实现方式有些仅在一定的国家和地区使用,有些则属于未来的规划方式。目前通用的实现方式是UTF-16小尾序(LE)、UTF-16大尾序(BE)和UTF-8。在微软公司Windows XP操作系统附带的记事本(Notepad)中,“另存为”对话框可以选择的四种编码方式除去非Unicode编码的ANSI(对于英文系统即ASCII编码,中文系统则为GB2312或Big5编码)外,其余三种为“Unicode”(对应UTF-16 LE)、“Unicode big endian”(对应UTF-16 BE)和“UTF-8”。
UTF-8, 8bit编码, ASCII不作变换, 其他字符做变长编码, 每个字符1-3 byte. 通常作为外码. 有以下优点:
1.与CPU字节顺序无关, 可以在不同平台之间交流
2.容错能力高, 任何一个字节损坏后, 最多只会导致一个编码码位损失, 不会联锁错误
(如GB码错一个字节就会整行乱码) 。
UTF-16, 16bit编码, 是变长码, 大致相当于20位编码, 值在0到0x10FFFF之间, 基本上就是unicode编码的实现. 它是变长码, 与CPU字序有关, 但因为最省空间, 常作为网络传输的外码,UTF-16是unicode的preferred encoding。
已经简单了解字符集,那我们在实际使用中如何避免错误使用字符集导致乱码呢?
查看数据库服务器字符集:
select * from nls_database_parameters; ///其来源于props$,是表示数据库的字符集。
查看客户端字符集环境:
select * from nls_instance_parameters; ///其来源于v$parameter,表示客户端的字符集的设置,可能是参数文件,环境变量或者是注册表
查看会话字符集环境:
select * from nls_session_parameters; ///其来源于v$nls_parameters,表示会话自己的设置,可能是会话的环境变量或者是alter session完成,
如果会话没有特殊的设置,将与nls_instance_parameters一致。
客户端的字符集要求与服务器一致或者被包容,才能正确显示数据库的非Ascii字符。如果多个设置存在的时候,alter session>环境变量>参数文件