最近碰到Oracle乱码问题,刚开始甚是头疼,以前在合肥出差的时候,这种问题也碰到过,当时直接抛给了“乌压压一片”(一个搞数据的同事儿),这次没办法躲过,只好硬着头皮上。虽然我这次碰到的是Oracle乱码问题中的一个,但是我决定将这个乱码问题整理清楚(不整清楚,就觉得身边有个定时炸弹,怕下次整数据库的时候会突然又爆炸)。
解决这个问题的关键在于理解字符集的概念,所以在正文开始之前,有必要先提一下字符集的相关知识!(这部分知识,对于解决j2ee中文参数传递过程中出现的乱码,也非常具有参考意义)
一、字符、字节和编码(熟悉的人或者急于解决问题的人,直接跳过这一节。备注:此节内容非原创,查看原创请连接: http://www.regexlab.com/zh/encoding.htm)
1.1 字符与编码的发展
从计算机对多国语言的支持角度看,大致可以分为三个阶段:
系统内码 | 说明 | 系统 | |
阶段一 | ASCII | 计算机刚开始只支持英语,其它语言不能够在计算机上存储和显示。 | 英文 DOS |
阶段二 | ANSI编码 (本地化) |
为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。 不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。 不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。 |
中文 DOS,中文 Windows 95/98,日文 Windows 95/98 |
阶段三 | UNICODE (国际化) |
为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。 | Windows NT/2000/XP,Linux,Java |
字符串在内存中的存放方法:
在 ASCII 阶段,单字节字符串使用一个字节存放一个字符(SBCS)。比如,"Bob123" 在内存中为:
42 | 6F | 62 | 31 | 32 | 33 | 00 |
B | o | b | 1 | 2 | 3 |