Chinaunix首页 | 论坛 | 博客
  • 博客访问: 383391
  • 博文数量: 85
  • 博客积分: 1504
  • 博客等级: 上尉
  • 技术积分: 928
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-04 12:20
文章分类

全部博文(85)

文章存档

2011年(66)

2010年(19)

分类: Oracle

2011-03-10 21:47:42

http://www.cublog.cn/u2/61329/showart_1421691.html

 

1)当前数据库字符集

SQL> select   name,value$   from   props$   where   name='NLS_CHARACTERSET';

2)当前客户端NLS_LANG

env |grep NLS

 

通常在我们的现实环境中,存在3个字符集设置。

第一: 客户端应用字符集(Client Application Character Set)

第二: 客户端NLS_LANG参数设置

第三: 服务器端,数据库字符集(Character Set)设置

我们说,一个字符在客户端应用(比如SQLPLUS,CMD,NOTEPAD等)中以怎样的字符显示取决于客户端操作系统,客户端能够显示怎样的字符,
我们就可以在应用中录入这些字符,至于这些字符能否在数据库中正常存储,就和另外的两个字符集设置紧密相关了。

在传输过程中,客户端NLS_LANG主要用于进行转换判断

如果NLS_LANG等于数据库字符集,则不进行任何转换直接把字符插入数据库

如果不同则进行转换,转换主要有两个任务

  • 如果存在对应关系,则把相应二进制编码经过映射后(这一步映射以后,所代表的字符可能发生转换)传递给数据库
  • 如果不存在对应关系,则传递一个替换字符(很多平台就是?)

数据库字符集,在和客户端NLS_LANG不同时,会把经过NLS_LANG转换的字符进行进一步处理

  • 对于?(即不存在对应关系的字符)直接以?形式存放入数据库
  • 对于其他字符,在NLS_LANG和数据库字符集之间进行转换后存入。

以下我们来看一下最为常见的字符集及乱码的产生:

1.当NLS_LANG字符集与数据库字符集不同,同时NLS_LANG不同于Server端字符集设置

在这种情况下,存在两种可能:

  • 客户端输入的字符在NLS_LANG中没有对应的字符,这时无法转换,NLS_LANG使用替换字符替代这些无法映射的字符(这一步转换在TTS中
    完成),在很多字符集中这个替代字符就是”?”
  • 当客户端的字符在NLS_LANG中对应了不同的字符时,传递给数据库以后发生转换,存储的是字符,但是已经丢失了元数据,数据库中
    的字符不再代表客户端的输入。而且这个过程不可逆,这也就是为什么很多时候在客户端输入的是正常的编码,查询之后会得到未知字符的原因。

2. NLS_LANG和数据库字符集相同时
在这种情况下,数据库端对客户端传递过来的编码不进行任何转换(这样可以提高性能),直接存储进入数据库,那么这时候就存在和上面同样的问题,
如果客户端传递过来的字符集在数据库中有正确的对应就可以正确存储,如果没有,就会被替换字符置换成?,乱码就这样产生了。

 

* 转换数据库字符集(必须在restrict模式下进行)

SQL> startup mount
ORACLE instance started

SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;

System altered.

SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;

System altered.

SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;

System altered.

SQL> ALTER DATABASE OPEN;

SQL> alter database character set INTERNAL_USE ZHS16GBK;(使用INTERNAL_USE 可跳过超集检查)

Database altered.

以上内容摘自eagle的blog:

阅读(1212) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2011-03-27 18:28:21

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com