ORACLE字符集基础知识_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3354 | 回复: 0   主题: ORACLE字符集基础知识        下一篇 
潇湘隐者
注册用户
等级:少校
经验:871
发帖:52
精华:2
注册:2014-3-29
状态:离线
发送短消息息给潇湘隐者 加好友    发送短消息息给潇湘隐者 发消息
发表于: IP:您无权察看 2014-5-27 23:11:47 | [全部帖] [楼主帖] 楼主

    原文地址:http://www.cnblogs.com/kerrycode/p/3749085.html

概念描叙

ORACLE数据库有国家字符集(national character set)与数据库字符集(database character set)之分。两者都是在创建数据库时需要设置的。国家字符集主要是用于NCHAR、NVARCHAR、NCLOB类型的字段数据,而数据库字符集使用很广泛,它用于:CHAR、VARCHAR、CLOB、LONG类型的字段数据;

ORACLE的字符集名字一般由以下部分组成:语言或区域、表示一个字符的比特位数、标准字符集名称(可选项,S或C,表示服务器或客户端)。ORACLE字符集UTF8与UTFE不符合此规定,其它基本都是这种格式。NLS_LANG=<Language>_<Territory>.<Clients

Characterset>
set
nls_lang=AMERICAN_AMERICA.UTF8
set nls_lang=SIMPLIFIED
CHINESE_AMERICA.UTF8


NLS( National Language Support)国家语言支持。NLS是数据库的一个非常强大的特性,它控制着数据的许多方面:比如数据如何存储,一般来说它控制着以下两个方面:

    文本数据持久存储在磁盘上时如何编码

    透明的将数据从一个字符集转换到另外一个字符集。

假设你在数据库中用WE8ISO8859P1 字符集存储8 位的数据,但是你的某些客户使用的是一种7 位字符集,如US7ASCII字符集转换过程通常会修改数据,而你往往会把一个较大的字符集(在此例中就是8 位字符集)映射到一个较小的字符集(此例中的7 位字符集)。这是一种有损转换(lossy conversion),字符就会被修改,这只是因为:较小的字符集不可能表示较大字符集中的每一个字符。但是这种转换必须发生。这也是乱码产生的原因��如果数据库以一种单字节字符集存储数据,但是客户(如一个Java 应用,因为Java 语言使用Unicode)希望数据采用多字节表示,就必须��行转换,只有这样客户应用才能使用这些数据。

ORACLE支持的Unicode字符集有以下几种,下面的列表给出了字符集的名称、对应的数据库版本范围、采用的Unicode的版本。

AL24UTFFSS:是ORACLE第一种支持Unicode的字符集,从7.2版本开始使用,但是它支持的Unicode版本为1.1,因此从9i开始就不支持此字符集了。

UTF8 : 是ORACLE从ORACLE8开始使用的属于UTF-8编码的字符集,从ORACLE8.0到ORACLE8.16,Unicode版本为2.1,而ORACLE817到10g,采用的Unicode标 准为3.0

UTFE :用于EBCDIC码平台上的数据库Unicode字符集。因此它属于专用系统使用的字符集,其它属性与UTF8基本相同。

AL32UTF8 :是从ORACLE9开始使用的属于UTF-8编码的字符集,与UTF8相比,它采用的Unicode版本更新,在10g版本中使用的是Unicode 4.01标准,而UTF8因 为兼容性的考虑,在10g版本中用的是Unicode 3.0标准。

AL16UTF16:是ORACLE第一种采用UTF-16编码方式的字符集,从ORACLE9开始使用,是作为缺省的国家字符集使用,它不能被用作数据库的字符集。这是因为数 据库的字符集决定了SQL与PL/SQL源码的编码方式,对于UTF-16这种使用固定的两个字节来表示英文字母的编码方案来说,确实不适于用作数据库 的字符集,ORACLE目前采用的数据库字符集都是基于ASCII或EBCDID作为子集的编码方案。

对于US7ASCII,表示区域是US,用7个比特位表示一个字符,标准的字符集名称��ASCII。

对于中文字符集ZHS16GBK,表示简体中文(ZHT为繁体��文),一个字符需要16位比特,标准的字符集名称为GBK。而ZHS16CGB231280表示简体中文,一个字符需要16位比特,标准的字符集名称为GB231280,属于我们前面提过的1981年发布的GB2312-80标准。虽然我们说,GBK编码标准是GB2312编码标准的扩展,但是数据库字符集ZHS16GBK与ZHS16CGB231280之间却不是严格的超集与子集的关系,主要是有些汉字的编码在两个字符集中的数值是不同的,因此它们进行字符集转换时会出现问题。

查看字符集参数 

1:查看NLS_CHARACTERSET:字符集,NLS_NCHAR_CHARACTERSET:国家字符集 

    实例字符集环境 

SELECT * FROM
NLS_INSTANCE_PARAMETERS


主要涉及NLS_LANGUAGE、NLS_TERRITORY的值. NLS_INSTANCE_PARAMETERS其来源于v$parameter,注意:网上很多资料都说"NLS_INSTANCE_PARAMETERS 表示客户端的字符集的设置,可以是参数文件,环境变量或者是注册表",而且网上都人人亦云。记住它是表示实例的字符集环境。

    数据库可用字符集参数设置

SELECT * FROM
V$NLS_VALID_VALUES


 数据库服务器字符集

SELECT * FROM
NLS_DATABASE_PARAMETERS


NLS_DATABASE_PARAMETERS其来源于props$,是表示数据库的字符集。 

    客户端字符集环境

SELECT * FROM
V$NLS_PARAMETERS;
SELECT
USERENV('language') FROM
DUAL;


 USERENV、 V$NLS_PARAMETERS表示当前字符集环境。如果你在客户端执行,则表示客户端字符集环境。

    会话字符集环境

SELECT * FROM
NLS_SESSION_PARAMETERS;


 它来源于v$nls_parameters,表示会话自己的设置,可能是会话的环境变量或者是ALTER SESSION完成,如果会话没有特殊的设置,将与 V$NLS_PARAMETERS一致。 

2: 查看客户端字符集(NLS_LANG) 的方法

    如果系统是LINUX或UNIX平台,则也可以通过下面命令查看(前提是必须设置了NLS_LANG,否则查出来的是空值)

[etl@m1 ~]$env | grep NLS_LANG
NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
[etl@m1 ~]$echo $NLS_LANG
AMERICAN_AMERICA.ZHS16GBK


 如果系统是WINDOWS平台,则可以通过下面命令查看:

    1:在运行里面,输入regedit进入注册表,HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraDb11g_home1\里面(最后一项与实例名、数据库版本有关系),找到NLS_LANG选项,双击它,你就可以看到相应的值。

2:echo


%NLS_LANG% 。如果没有设置NLS_LANG,用这个命令看不到相关信息。

3: 设置NLS_LANG的方法

Windows平台:

3.1

set NLS_LANG=SIMPLIFIED
CHINESE_CHINA.ZHS16GBK
set NLS_LANG=SIMPLIFIED
CHINESE_CHINA.ZHS16GBK


3.2 可以通过修改注册表键值永久设置

HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/KEY_XXXX_home1/NLS_LANG
UNIX & LINUX
3.3
export
NLS_LANG=AMERICAN_AMERICA.UTF8


3.4可以编辑 bash_profile 文件进行永久设置

vi .bash_profile
export
NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"


 客户���的字符集要求与服务器一致,才能正确显示数据库的非Ascii字符。如果多个设置存在的时候,优先级关系为:SQL Function >Alter session>环境变量>注册表>参数文件 字符集要求一致,但是语言设置却可以不同,语言设置建议用英文。如字符集是zhs16gbk,则nls_lang可以是American_America.zhs16gbk。 

修改数据库字符集

数据库字符集在创建后原则上不能更改。因此,在前期规划和安装之初考虑使用哪一种字符集十分重要。对数据库服务器而言,错误的修改字符集将会导致很多不可测的后果,可能会严重影响数据库的正常运行,所以在修改之前一定要确认两种字符集是否存在子集和超集的关系。一般来说,除非万不得已,我们不建议修改ORACLE数据库SERVER端的字符集。

有两种方法修改数据库字符集设置

1. 通常需要导出数据库数据,重建数据库,然后再导入数据库数据的方式来转换。

2. 通过ALTER DATABASE CHARACTER SET语句修改字符集,但创建数据库后可以修改的字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如UTF8是US7ASCII的超集,修改数据库字符集可使用ALTER DATABASE CHARACTER SET UTF8。 

特别说明,我们最常用的两种字符集ZHS16GBK和ZHS16CGB231280之间不存在子集和超集关系,因此理论上讲这两种字符集之间的相互转换不受支持修改

关于数据库子集-超级对照表(subset-superset
pairs),可以参考官方文档,例如ORACLE 10g的http://docs.oracle.com/cd/B19306_01/server.102/b14225/applocaledata.htm

SQL>CONN / AS SYSDBA;
SQL>SHUTDOWN IMMEDIATE;
SQL>STARTUP
MOUNT;
SQL>ALTER
SYSTEM ENABLE RESTRICTED SESSION;
SQL>ALTER
SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL>ALTER
SYSTEM SET AQ_TM_PROCESSES=0;
SQL>ALTER
DATABASE OPEN;
--可以从子集到父集
SQL>ALTER
DATABASE CHARACTER SET ZHS16GBK;
--如果是从父集到子集,需要使用INTERNAL_USE参数,跳过超子集检测
SQL>ALTER
DATABASE NATIONAL CHARACTER SET UTF8;
--SQL>ALTER
DATABASE NATIONAL CHARACTER SET
INTERNAL_USE UTF8;
SQL>SHUTDOWN
IMMEDIATE;
SQL>STARTUP;
ALTER DATABASE


NATIONAL CHARACTER SET UTF8;有可能会出现ORA-12717: Cannot ALTER DATABASE
NATIONAL CHARACTER SET when NCLOB data exists 这样的提示信息.这时你用ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE 
UTF8;就可解决上述问题。

参考资料:http://blog.csdn.net/jkl_123/article/details/6157379

http://blog.csdn.net/tianlesoftware/article/details/4915223


该贴被潇湘隐者编辑于2014-5-27 23:18:37
该贴被潇湘隐者编辑于2014-5-27 23:20:05
该贴被潇湘隐者编辑于2014-5-27 23:21:00

该贴由hui.chen转至本版2014-11-5 16:24:18




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论