如何在oracle 中保存外国字符?(300分)

A

aaab

Unregistered / Unconfirmed
GUEST, unregistred user!
我在oracle(8.1.7)库中有一张表,其中一个字段(nvarchar类型)需要同时存储中文(简)、中文(繁)
日文和朝鲜文,请问要如何配置数据库、如何编程才能够实现?
 
是不是用UNICODE字符集就可以呢?

 
用varchar2不行吗?
 
请参考Oracle的在线文档:
Choosing a Character Set
http://download-west.oracle.com/docs/cd/A87860_01/doc/server.817/a76966/ch3.htm
 
到WWW.ITPUB.NET(中国最大的ORACLE技术论坛)上看看,好象是和字符集有关的问题
解决方法
一:通过编程动态更改客户端字符集
对如中文(繁)的客户端更改相映字符集,可对相关字符集的数据进行编辑存储
二:注意字符集的包含关系(据说ZHSGBK好象是最大的字符集)
三:是否可以对不同的字符集数据建立不同的数据库,未经过测试不敢说可行你可以试试
四:如果想同时在一个客户端看见这样多的不同字符集数据,可能较困难,也许别人有更好的方法
五:你说的问题好象不是用几百分就能够有一个非常好的解决方案。
六:ORACLE公司是不建议你在建立数据库后修改字符集的,他们说是最好是重新安装数据库,但实际情况确是可以修改的。
七:下面是我在网上收集的和ORACKE字符集相关的资料也许对你有用 慢慢看吧

>> ChinaUnix.net > Oracle



转载:Oracle数据库移植时字符集问题的解决


作者:slackerqxl 发表时间:2002/06/20 03:42pm

对于Oracle数据库之间的移植采用Oracle的导入导出工具(Import/Export)是一个比较好的策略。虽也可以利用第三方软件如Sybase 的Power designer中的Reverse Engineering 进行数据库结构重建,然后在进行较复杂的数据导入过程,但对于作业队列、快照等则不得不用手工来创建。而Export能将整个数据库、指定用户、指定表和相关的数据字典进行输出,Export输出的输出转存二进制文件包括了完全重建所有被选对象所需的命令。

本人在为某电厂MIS(Oracle数据库)数据采用Oracle的导入导出工具从Windows NT平台移植到Digital Unix平台时遇到的关于字符集的问题和总结出的经验与大家来分享。

1. 移植环境
原操作系统平台: Windows NT
数据库: Oracle 8.0.5 for Windows NT
服务器:HP NetServer LH3
目标操作系统平台:Digital Unix alpha V4.0
数据库:Oracle 8.0.4 for Digital Unix
服务器:ALPHASERVER ES40 小型机

2. 数据导出
在NT服务器上用Oracle导出工具进行数据导出,Oracle导出工具有命令行和图形界面两种方式。
本人直接用命令行方式进行数据导出:
c:> exp80 gxmisdba/manager file=c:expdat.dmp log=c:export.log
即将导出指定的用户...
. 正在导出用户GXMISDBA的外部函数程序库名称
. 正在导出用户GXMISDBA的对象类型定义
即将导出GXMISDBA的对象 ...
. 正在导出数据库链接
. 正在导出序号
. 正在导出群集定义
. 即将导出GXMISDBA的表通过常规路径 ...
. . 正在导出表     AAAAA          0 行被导出
. . 正在导出表  EVT_CARRIER_CONFIGURATION   0 行被导出
. . 正在导出表    TBL_AJ_AGKS       331 行被导出
  .
  .
  .
. 正在导出同义词
. 正在导出视图
. 正在导出存储的过程
. 正在导出参考资料一致性约束条件
. 正在导出触发器
. 正在导出后期表活动
. 正在导出快照
. 正在导出快照日志
. 正在导出作业队列
. 正在导出刷新组和子组
在没有警告的情况下成功终止导出。

3.数据导入
在NT服务器上通过ftp命令将导出的输出转存二进制文件expdat.dmp(使用binary传输模式)传输至Digital Unix服务器上。
用Oracle for Digital Unix 数据导入工具命令行方式进行数据导入
$imp gxmisdba/manager file=/expdat.dmp full=y log=u01import.log
Connected to: Oracle8 Enterprise Edition Release 8.0.4.0.0 - Production
PL/SQL Release 8.0.4.0.0 - Production
Export file created by EXPORT:V08.00.05 via conventional path
. importing GXMISDBAs objects into GXMISDBA
. . importing table   "AAAAA"            0 rows imported
. . importing table  "EVT_CARRIER_CONFIGURATION"   0 rows imported
. . importing table   "TBL_AJ_STK"         331 rows imported
IMP-00017: following statement failed with ORACLE error 2437:
"ALTER TABLE "TBL_KJ_JLRY" ADD CONSTRAINT "PK_TBL_KJ_JLRY" PRIMARY KEY ("FLD_KJ_JLRY_BH","FLD_KJ_JLRY_XM") USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (INITIAL 10240 NEXT 10240 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 50 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)"
"      ENABLE NOVALIDATE"
IMP-00003: ORACLE error 2437 encountered
ORA-02437: cannot enable (GXMISDBA.PK_TBL_KJ_JLRY) - primary key violated
.
.
.
Import terminated successfully with warnings.
数据导入出现20多个以上类似错误,后分析其中报错的"TBL_AJ_STK"表,发现"FLD_KJ_JLRY_XM"字段值(关键字组成之一)为中文字符而在Digital Unix服务器Oracle数据库中"FLD_KJ_JLRY_XM"字段值显示的为"????"(在客户端用Oracle Sql Plus查看),从而造成关键字冲突。
在客户端Oracle Sql Plus对某行显示"????"的字段值进行修改,如改成中文值”测试”,提交后,用SQL语句查看,刚修改的行中显示"????"的字段值变成了”测试”,这说明了Digital UNIN服务器上的Oracle数据集可以存储中文字符,但Oracle 8.0.4 for Digital UNIN的导入工具imp未能将Oracle 8.0.5 for Windows NT imp80导出的中文数据进行转换。

4.查看字符集参数
4.1查看Oracle 8.0.5 for Windows NT props$内容
SQL> connect sys/change_on_install
SQL> col value$ format a40
SQL> select name,value$ from props$;
NAME              VALUE$
---------------------------------------
DICT.BASE            2
NLS_LANGUAGE           AMERICAN
NLS_TERRITORY          AMERICA
NLS_CURRENCY           $
NLS_ISO_CURRENCY         AMERICA
NLS_NUMERIC_CHARACTERS     .,
NLS_CALENDAR           GREGORIAN
NLS_DATE_FORMAT         DD-MON-YY
NLS_DATE_LANGUAGE        AMERICAN
NLS_CHARACTERSET         ZHS16GBK
NLS_SORT            BINARY
NLS_NCHAR_CHARACTERSET     ZHS16GBK
NLS_RDBMS_VERSION        8.0.5.0.0
GLOBAL_DB_NAME         ORACLE.WORLD
EXPORT_VIEWS_VERSION      7
已选择15行。

4.2查看Oracle 8.0.4 for Digital UNIN 的props$内容
SQL> connect sys/change_on_install
SQL> col value$ format a40
SQL> select name,value$ from props$;
NAME              VALUE$
---------------------------------------
DICT.BASE            2
NLS_LANGUAGE           AMERICAN
NLS_TERRITORY          AMERICA
NLS_CURRENCY           $
NLS_ISO_CURRENCY         AMERICA
NLS_NUMERIC_CHARACTERS      .,
NLS_CALENDAR           GREGORIAN
NLS_DATE_FORMAT         DD-MON-YY
NLS_DATE_LANGUAGE        AMERICAN
NLS_CHARACTERSET         ZHS16CGB231280
NLS_SORT             BINARY
NLS_NCHAR_CHARACTERSET      ZHS16CGB231280
NLS_RDBMS_VERSION        8.0.4.0.0
GLOBAL_DB_NAME          ORCL.WORLD
EXPORT_VIEWS_VERSION      7
15 rows selected.
发现Oracle 8.0.4 for Digital UNIN 采用了Oracle在Digital Unix环境下建议的中文字符集ZHS16CGB231280,两者的字符集不同,于是本人就在Digital UNIN服务器上重新安装Oracle,选择了与NT上同样的字符集ZHS16GBK(中国简体汉字16位国标库)。安装完成后,通过查看props$的内容,确认了Oracle 8.0.4 for Digital UNIN和Oracle 8.0.5 for Windows NT的字符集一致。于是用Oracle 8.0.4 for Digital UNIN的导入工具imp重新进行数据导入,但还是报同样的错误,问题还未得到解决。

5.问题解决办法
后来本人发现在Oracle 8.0.5 for Windows NT的服务器(或装有Oracle 8.0.5 for windows 95/98的工作站)上直接用Oracle 8.0.5 for Windows NT的导入工具imp80远程对Oracle 8.0.4 for Digital UNIN数据库进行数据导入,问题竟得到解决。
5.1在NT的服务器上,修改tnsnames.ora(或通过Oracle Net8 Easy config)设置数据库连接字符串gxmis(可自行设定)指向Oracle 8.0.4 for Digital UNIN服务器。

5.2在NT的服务器上进行数据远程导入
c:>imp80 gxmisdba/manager@gxmis file=c:expdat.dmpfull=y log=c:import.log

已连接到:Oracle8 Enterprise Edition Release 8.0.4.0.0 - Production
PL/SQL Release 8.0.4.0.0 - Production
经由常规路径导出由EXPORT:V08.00.05创建的文件
. 正在将GXMISDBA的对象导入到 GXMISDBA
. . 正在导入表 "AAAAA" 0行被导入
. . 正在导入表 "EVT_CARRIER_CONFIGURATION" 0行被导入
. . 正在导入表 "TBL_AJ_AGKS" 331行被导入
.
.
.
准备启用约束条件...
成功终止导入

5.3把Oracle 8.0.4 for Digital UNIN字符集重新又改成ZHS16CGB231280,进行数据远程导入测试,数据也同样地导入成功。说明ZHS16CGB231280字符集可以兼容ZHS16GBK字符集。

6.经验总结
6.1在Oracle 8.0.4 for Digital UNIN服务器上(字符集ZHS16GBK)用8.0.4 for Digital UNIN的导出工具exp将已正常(即可存储和显示中文)的数据库导出。
$ exp gxmisdba/manager file=/u01/expdat.dmp log=/u01/export.log
显示成功导出。
在用Oracle 8.0.4 for Digital UNIN的导入工具imp进行导入
$imp gxmisdba/manager file=/u01/expdat.dmp full=y log=u01import.log
错误又重现。

6.2在NT服务器上通过ftp命令将在Oracle 8.0.4 for Digital UNIN服务器上刚导出的输出转存二进制文件expdat.dmp下载至NT服务器上,用imp80进行远程导入。
c:>imp80 gxmisdba/manager@gxmis file=c:expdat.dmp full=y log=c:import.log
已连接到:Oracle8 Enterprise Edition Release 8.0.4.0.0 – Production
PL/SQL Release 8.0.4.0.0 – Production
IMP-00016: 不支持要求的字符集转换(从类型1到852)
IMP-00000: 未成功终止导入

6.3在NT服务器上对Digital UNIN服务器上的数据进行远程导出(备份)
c:>exp80 gxmisdba/manager@gxmis file=c:expdat.dmp log=c:export.log
显示成功导出。再进行远程导入
c:>imp80 gxmisdba/manager@gxmis file=c:expdat.dmp full=y log=c:import.log
显示成功导入。通过客户端Oracle Sql Plus查看中文显示正常。
从而说明在Oracle 8.0.4 for Digital UNIN服务器上对含有中文的数据库的数据移植、备份、数据恢复不要用Oracle 8.0.4 for Digital UNIN本身自带的导入导出工具imp,exp,应使用能进行中文导入导出的工具,如imp80,exp80。

江西思创数码科技有限公司 江恭和







--------------------------------------------------------------------------------
此文章相关评论:

该文章有1个相关评论如下:(点这儿可以发表评论)

anubis 发表于: 2002/09/24 02:33pm







--------------------------------------------------------------------------------
Copyright ? ChinaUnix.net * 转载请注明出处及作者

Oracle在数据转储时的字符集问题 (看到很多人在问,顺便转了过来了)
作为一个Oracle数据库的用户,对于Export和Import两个命令绝对不会感到陌生,因为这二者正是我们经常用于数据备份和恢复的工具。但在使用这两个命令过程中所发生的Oracle字符集问题,常给一些Oracle使用者带来不必要的麻烦和不必要的数据损失。本文将就Export和Import过程中Oracle字符集的转换规律及使用这两个命令的注意事项做一总结。



字符集转换的原因
Export、Import过程如下图所示,从这个示意图中可以看到有四处关系到字符集,而这四处字符集的不一致恰恰是导致Oracle进行字符集转换的原因。

源数据库字符集;
Export过程中用户会话字符集;
Import过程中用户会话字符集;
目标数据库字符集。
在Export和Import过程中,如果存在影响字符集转换的四因素不一致,则可能发生Oracle字符集转换,即:

在Export过程中,如果源数据库字符集与Export用户会话字符集不一致,会发生字符集转换,并在导出的二进制格式Dmp文件的头部几个字节中存储Export用户会话字符集的ID号。在这个转换过程中可能发生数据的丢失。
例1: 如果源数据库使用ZHS16GBK,而Export用户会话字符集使用US7ASCII,由于ZHS16GBK是8位字符集,而US7ASCII是7位字符集,这个转换过程中,中文字符在US7ASCII中不能够找到对等的字符,所以所有中文字符都会丢失而变成“?? ”形式,即这种转换后生成的Dmp文件已经发生了数据丢失。
例2: 如果源数据库使用ZHS16GBK,而Export用户会话字符集使用ZHS16CGB231280,但由于ZHS16GBK字符集是ZHS16CGB231280字符集的超集,这个过程中绝大部分字符都能够正确转换,只有一些超出ZHS16CGB231280字符集的字符变为“?? ”形式。如果源数据库使用ZHS16CGB231280字符集,而Export用户会话使用ZHS16GBK字符集,则转换过程能够完全转换成功。
在Import向目标数据库转换过程中,其字符集发生转换的情况正好与Export过程相反,这里不再详述。
在Export导出的Dmp文件中,含有Export用户会话字符集。在Import过程中,首先发生的是Dmp文件字符集(即Export用户会话字符集)向Import用户会话字符集的转换。如果这个转换过程不能正确完成,Import向目标数据库的导入过程也就不能完成。

进行字符集的正确转换
通常情况下,我们在使用Oracle的Export和Import过程中,并不希望发生字符的转换,但有时这种转换却是必要的。如我们在安装Oracle数据库时,选择ZHS16CGB231280字符集,由于这种字符集是一种中文小字符集,对于一些汉字不能够正确表示,这需要通过使用ZHS16GBK字符集得到解决,此时就要进行字符集的转换。

为了确保Export、Import过程中,Oracle字符集不发生转换或正确转换,建议最好在进行这个过程前,检查一下源数据库字符集与Export用户会话字符集是否一致,源数据库字符集与目标数据库字符集是否一致,目标数据库字符与Import用户会话字符集是否一致。如果能够保证这四个字符集是一致的,则在Export、Import过程中,Oracle字符集就不用发生转换。

可用以下办法检查数据库字符集:

通过InitXXXX.ora文件进行查看;
借助SQL语句查看: SELECT NAME,VALUE$ FROM SYS.PROPS$ WHERE NAME=‘NLS_CHARACTERSET’。
对于Export、Import用户会话字符集,在Windows系统中也可以通过注册表中的NLS_LANG进行查看或修改,对于Unix系统则可通过设置用户的环境变量NLS_LANG来查看或修改。

特别要注意的是,Oracle数据库字符集通常是在创建时确定,一旦存储用户数据后就不要再修改了,因为其数据都是使用该字符集进行存储的,改换其他字符集之后,原有数据就不能够正确表示了。但如果确实想进行字符集改变,则可通过以下几步来实现:

备份数据库后删除原数据(可物理备份,如使用Export,请注意确保字符集不发生转换或数据无损失);
使用Internal用户更新sys.props$表中的字符集:
Update sys.props$ set name=‘Dest.CharSet’ Where name=‘NLS_CHARACTERSET’; COMMIT;
重启数据库;
恢复数据。
下面字符集之间的转换是可行的:

字符集子集向字符集父集转换是可行的,如ZHS16CGB231280向ZHS16GBK转换;而字符集父类向字符集子集进行转换时,会损失部分数据。
只包含英文字符数据的双字节字符集也可向单字节字符集转换,如ZHS16GBK(English Only)可以向US7ASCII正确转换。
编码范围相同的单字节字符集之间通常可以进行相互转换。
请注意,这里所说的没有数据损失,是指一种字符集A转换成另一种字符集B之后,可以再从字符集B正确转换成字符集A或字符集B能够正确表示字符集A中转换过来的数据。


字符集对程序的影响
根据一个字符需要多少位字节来表示,可以把字符集分为单字节字符集和多字节字符集。其中,单字节字符集又分为7位字符集和8位字符集。单字节7位编码字符集有US7ASCⅡ,单字节8位编码字符集有符合ISO 8859-1标准规定的WE8ISO8859P1等。多字节编码又分为固定长度(长度大于或等于2)编码模式和不固定长度编码模式。多字节编码字符集中的ZHS16GBK、ZHS16CGB231280、JA16SJIS等是采用两个字节表示一个字符的字符集,又叫双字节字符集。

一个英文字母是一个字符,一个中文汉字是几个字符呢?我们知道,一个中文汉字是双字节字符,但它有几个字符与其数据库字符集有关。如果数据库字符集使用单字节US7ASCII,则一个中文汉字是二个字符;如果数据库字符集使用双字节字符集ZHS16GBK,则一个中文汉字是一个字符。有关这一点可以使用Oracle的函数Substr得到证明。
使用US7ASCⅡ字符集时:
Select substr(‘东北大学’,1,2) from dual;
语句执行结果返回‘东’。


使用ZHS16GBK字符集时:
Select substr(‘东北大学’,1,2) from dual;
语句执行结果返回‘东北’。

选择合适的数据库字符集
选择数据库字符集时应考虑以下事项:


1.数据库需要支持什么语言
在为数据库选择字符集时,常会发现几种字符集都适合你当前语言需求,如简体中文就有ZHS16GBK和ZHSCGB231280等字符集可供选择,应选择哪种?在选择字符集时,应考虑到数据库将来的系统需求。如果知道将来数据库要扩展支持不同的语言,选择一个范围较广的字符集会是一个更好的主意。


2.系统资源与应用之间的互作用性
选择的数据库字符集应保证操作系统与应用之间的无缝连接。如果选择的字符集不是操作系统有效的字符集,则系统就需要在这两者之间做字符转换。在这种字符转换过程中,就有可能发生一些字符丢失现象。从一种字符集A向另一种字符集B转换过程中,A中的字符必须在B中可以找到等价的字符,否则就会以“?”来代替。从这个意义上说,如果两种字符集编码范围是相同的,则可以相互转换。

字符集转换过程中会影响系统性能,因此,应保证客户端和服务器端有相同的字符集以避免字符集转换,也可以提高一定的系统性能。


3.系统的性能要求
不同的数据库字符集对于数据库的性能是有一定影响的。为了得到最好的数据库性能,选择的数据库字符集应避免字符转换,并且要选择对于期望的语言有最高效的编码效率。通常,单字节字符集比多字节字符集有更优的性能表现,在空间需求方面也更小些。


4.其他一些限制
在为数据库选择一个合适的字符集时,应参考Oracle对应版本的相关文档,检查Oracle对于一些字符集的限制。如Oracle 8.1.5版本中,以下字符集是不能使用的: JA16EUCFIXED、ZHS16GBKFIXED、JA16DBCSFIXED、KO16DBCSFIXED、ZHS16DBCSFIXED、JA16SJISFIXED、ZHT32TRISFIXED。

综上所述,正确理解Oracle字符集的转换过程,可以使我们避免不必要的麻烦和数据损失。合理利用Oracle字符集的转换过程,也可以帮助我们正确地从一种字符集转换到另一种字符集,以满足我们各种不同的应用需求。







02-08-26 00:34



ripe
初级会员

注册日期: 2002 Sep
来自:
发帖数量: 3

good archive!!!





02-09-26 20:36



phonee
初级会员

注册日期: 2002 Sep
来自:
发帖数量: 12

ORACLE是不建议修改数据库字符集的
特别要注意的是,Oracle数据库字符集通常是在创建时确定,一旦存储用户数据后就不要再修改了,因为其数据都是使用该字符集进行存储的,改换其他字符集之后,原有数据就不能够正确表示了。但如果确实想进行字符集改变,则可通过以下几步来实现:

备份数据库后删除原数据(可物理备份,如使用Export,请注意确保字符集不发生转换或数据无损失);
使用Internal用户更新sys.props$表中的字符集:
Update sys.props$ set name=‘Dest.CharSet’ Where name=‘NLS_CHARACTERSET’; COMMIT;
重启数据库;
恢复数据。
--------------------------------------------------------------------

ORACLE提供了以上修改字符集的方法,
但强烈建议在建库以后不要再修改字符集!





02-09-26 21:15



supershawn
中级会员

注册日期: 2002 Mar
来自: 山城+火炉 ---〉重庆
发帖数量: 224

不错阿,很好,


__________________
终于回家了,感觉不摆了,︿_︿




02-09-26 23:58



zl99
一般会员

注册日期: 2002 Jul
来自: hn
发帖数量: 66

ZT:

Character Set Conversion

The following sections describe character conversion for CHAR and NCHAR data.

CHAR Data

Up to three character set conversions may be required for character data during
an export/import operation:

1. Export writes export files using the character set specified in the NLS_LANG
environment variable for the user session. A character set conversion is
performed if the value of NLS_LANG differs from the database character set.

2. If the character set in the export file is different than the Import user
session character set, Import performs a character set conversion to its user
session character set. Import can perform this conversion only if the ratio of
the width of the widest character in its user session character set to the width
of the smallest character in the export file character set is 1.


3. A final character set conversion may be performed if the target database?s
character set is different from Import?s user session character set.





02-09-27 04:12



rejoice999
版主

注册日期: 2002 Jun
来自:
发帖数量: 1055

Re: ORACLE是不建议修改数据库字符集的
你建议不要改字符集是好的,但是你给的改法是不对的,会害死人的哟!



quote:
--------------------------------------------------------------------------------
最初由 phonee 发布
特别要注意的是,Oracle数据库字符集通常是在创建时确定,一旦存储用户数据后就不要再修改了,因为其数据都是使用该字符集进行存储的,改换其他字符集之后,原有数据就不能够正确表示了。但如果确实想进行字符集改变,则可通过以下几步来实现:

备份数据库后删除原数据(可物理备份,如使用Export,请注意确保字符集不发生转换或数据无损失);
使用Internal用户更新sys.props$表中的字符集:
Update sys.props$ set name=‘Dest.CharSet’ Where name=‘NLS_CHARACTERSET’; COMMIT;
重启数据库;
恢复数据。
--------------------------------------------------------------------

ORACLE提供了以上修改字符集的方法,
但强烈建议在建库以后不要再修改字符集!
--------------------------------------------------------------------------------






02-09-27 05:57



zl99
一般会员

注册日期: 2002 Jul
来自: hn
发帖数量: 66

看手册上的正确改法应该是:
SQL> SHUTDOWN IMMEDIATE; -- or NORMAL
<do a full backup>
SQL> STARTUP MOUNT;
SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL> ALTER DATABASE OPEN;
SQL> ALTER DATABASE CHARACTER SET <new_character_set_name>;
SQL> SHUTDOWN IMMEDIATE; -- or NORMAL
SQL> STARTUP;

改后的字符集必须是改前字符集的严格超集,昨天在metalink问了一下,他们回答说
ZHS16GBK不是ZHS16CGB231280的superset,所以建议用exp/imp的方式改。





02-09-27 16:43



ggf0626
老会员

注册日期: 2002 May
来自: 杭州
发帖数量: 310


quote:
--------------------------------------------------------------------------------
最初由 zl99 发布
看手册上的正确改法应该是:
SQL> SHUTDOWN IMMEDIATE; -- or NORMAL
<do a full backup>
SQL> STARTUP MOUNT;
SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL> ALTER DATABASE OPEN;
SQL> ALTER DATABASE CHARACTER SET <new_character_set_name>;
SQL> SHUTDOWN IMMEDIATE; -- or NORMAL
SQL> STARTUP;

改后的字符集必须是改前字符集的严格超集,昨天在metalink问了一下,他们回答说
ZHS16GBK不是ZHS16CGB231280的superset,所以建议用exp/imp的方式改。
--------------------------------------------------------------------------------


这个超级不只是说一个汉字在两个字符集都有,而是BINARY SUPERSET,即编码必须一致。


__________________
一直在努力




影响ORACLE汉字显示的字符集问题
中原油田研究院
康子明 等4人
---- 在国内外大中型数据库管理系统中,把ORACLE作为数据库管理平台的用户比较多。ORACLE 不论是数据库管理能力还是安全性都是无可非议的,但是,它在汉字信息的显示方面着实给中国用户带来不少麻烦,笔者多年从事ORACLE数据库管理,经常收到周围用户和外地用户反映有关ORACLE数据库汉字显示问题的求援信,主要现象是把汉字显示为不可识别的乱码,造成原来大量信息无法使用。本文将就这一问题产生的原因和解决办法进行一些探讨,供存在这方面问题的用户朋友参考。

---- 1、原因分析

---- 通过对用户反映情况的分析,发现字符集的设置不当是影响ORACLE数据库汉字显示的关键问题。那么字符集是怎么一会事呢?字符集是ORACLE 为适应不同语言文字显示而设定的。用于汉字显示的字符集主要有ZHS16CGB231280,US7ASCII,WE8ISO8859P1等。字符集不仅需在服务器端存在,而且客户端也必须有字符集注册。服务器端,字符集是在安装ORACLE时指定的,字符集登记信息存储在ORACLE数据库字典的V$NLS_PARAMETERS表中;客户端,字符集分两种情况,一种情况是sql*net 2.0以下版本,字符集是在windows的系统目录下的oracle.ini文件中登记的;另一种情况是sql*net 2.0以上(即32位)版本,字符集是在windows的系统注册表中登记的。要在客户端正确显示ORACLE 数据库汉字信息,首先必须使服务器端的字符集与客户端的字符集一致;其次是加载到ORACLE数据库的数据字符集必须与服务器指定字符集一致。因此,把用户存在的问题归纳分类,产生汉字显示异常的原因大致有以下几种:

---- 1. 1服务器指定字符集与客户字符集不同,而与加载数据字符集一致。

---- 这种情况是最常见的,只要把客户端的字符集设置正确即可,解决办法见2.1。

---- 1. 2服务器指定字符集与客户字符集相同,与加载数据字符集不一致。

---- 这类问题一般发生在ORACLE版本升级或重新安装系统时选择了与原来服务器端不同的字符集,而恢复加载的备份数据仍是按原字符集卸出的场合,以及加载从其它使用不同字符集的ORACLE数据库卸出的数据的情况。这两种情况中,不管服务器端和客户端字符集是否一致都无法显示汉字。解决办法见2.2。

---- 1.3服务器指定字符集与客户字符集不同,与输入数据字符集不一致。

---- 这种情况是在客户端与服务器端字符集不一致时,从客户端输入了汉字信息。输入的这些信息即便是把客户端字符集更改正确,也无法显示汉字。解决办法见2.3。

---- 2.解决办法

---- 下面将分别对上述三种情况给出解决办法。为了叙述方便,假设客户端使用WINDOWS95/98环境,并已成功地配置了TCP/IP协议,安装了ORACLE的sql*net,sql*pluse产品。

---- 2.1 设置客户端字符集与服务器端字符集一致

---- 假设当前服务器端使用US7ASCII字符集。

---- (1)查看服务器端字符集

---- 通过客户端或服务器端的sql*plus登录ORACLE的一个合法用户,执行下列SQL语句:

SQL > select * from V$NLS_PARAMETERS
parameter value
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
…. ….
NLS_CHARACTERSET US7ASCII
NLS_SORT BINARY
NLS_NCHAR_CHARACTERSET US7ASCII

---- 从上述列表信息中可看出服务器端ORACLE数据库的字符集为'US7ASCII'。

---- (2)按照服务器端字符集对客户端进行配置

---- 配置方法有两种:

安装ORACLE的客户端软件时指定
---- 在安装ORACLE的客户端产品软件时,选择与ORACLE服务端一致的字符集(本例为US7ASCII)即可。

修改注册信息的方法
---- 根据ORACLE 客户端所选sql*net 的版本分为下列两种情况:

---- a. 客户端为 sql*net 2.0 以下版本

---- 进入Windows的系统目录,编辑oracle.ini文件,用US7ASCII替换原字符集,重新启动计算机,设置生效。

---- b. 客户端为 sql*net 2.0 以上版本

---- 在WIN98 下 运 行REGEDIT,第一步选HKEY_LOCAL_MACHINE,第二步选择SOFTWARE, 第三步选择 ORACLE, 第四步选择 NLS_LANG, 键 入 与服 务 器 端 相 同 的 字 符 集(本例为:AMERICAN_AMERICAN.US7ASCII)。

---- 2.2 强制加载数据字符集与服务器端字符集一致

---- 假设要加载数据从原ORACLE数据库卸出时的字符集为US7ASCII,当前ORACLE服务器字符集为WE8ISO8859P1。

---- 下面提供三种解决方法:

---- (1) 服务器端重新安装ORACLE

---- 在重新安装ORACLE 时选择与原卸出数据一致的字符集(本例为US7ASCII)。

---- 加载原卸出的数据。

---- 这种情况仅仅使用于空库和具有同一种字符集的数据。

---- (2)强行修改服务器端ORACLE当前字符集

---- 在用imp命令加载数据前,先在客户端用sql*plus登录system DBA用户,执行下列SQL语句进行当前ORACLE数据库字符集修改:

SQL > create database character set US7ASCII
* create database character set US7ASCII
ERROR at line 1:
ORA-01031: insufficient privileges

---- 你会发现语句执行过程中,出现上述错误提示信息,此时不用理会,实际上ORACLE数据库的字符集已被强行修改为US7ASCII,接着用imp命令装载数据。等数据装载完成以后,shutdown 数据库,再startup 数据库,用合法用户登录ORACLE数据库,在sql>命令提示符下,运行select * from V$NLS_PARAMETERS,可以看到ORACLE数据库字符集已复原,这时再查看有汉字字符数据的表时,汉字已能被正确显示。

---- (3)利用数据格式转储,避开字符集限制

---- 这种方法主要用于加载外来ORACLE数据库的不同字符集数据。其方法如下:

---- 先将数据加载到具有相同字符集的服务器上,然后用转换工具卸出为foxbase 格式或access格式数据库,再用转换工具转入到不同字符集的ORACLE数据库中,这样就避免了ORACLE字符集的困扰。目前数据库格式转换的工具很多,象power builder5.0以上版本提供的pipeline,Microsoft Access数据库提供的数据导入/导出功能等。转换方法参见有关资料说明。.

---- 2.3匹配字符集替换汉字

---- 对于1.3提到的情况,没有很好的办法,只能先把客户端与服务器端字符集匹配一致后,根据原输入汉字的特征码替换汉字字符部分。




Free Advertising from Click2Paid.com 首页 | 请您留言
[数据库技术]->[Oracle] 技术文摘 | 程序下载 | 书籍与资料 | 网络资源 | 讨论区




巧妙转换ORACLE数据库字符集
张嘉瑜

在大型数据库管理系统中,ORACLE数据库不论在数据库管理能力还是在安全性方面都是无可非议的。国内企业使用ORACLE数据库的也较多,但是由于ORACLE不同版本的字符集,给数据显示、数据备份、数据转换等实际工作带来了不少麻烦。
一、字符集参数
一旦数据库创建后,数据库的字符集是不能改变的。因此,考虑使用哪一种字符集是十分重要的。数据库字符集应该是操作系统本地字符集的一个超集。存取数据库的客户使用的字符集将决定选择哪一个超集,即数据库字符集应该是所有客户字符集的超集。
下面介绍一些与字符集有关的NLS_LANG参数:
NLS_LANG格式:NLS_LANG=language_territory.charset
有三个组成部分(语言、地域和字符集),每个组成成分控制了NLS子集的特性。三个成分可以任意组合,例如:
AMERICAN_AMERICA.US7SCII
JPANESE_JAPAN.JA16EUC
其中:language 指定服务器消息的语言。
territory 指定服务器的日期和数字格式。
Charset 指定字符集
还有一些子集可以更明确定义NLS_LANG参数:
NLS_DATE_FORMAT 缺省的日期格式
NLS_DATE_LANGUAGE 缺省的日期语言
NLS_NUMBERIC_CHARACTERS 小数字符和组分隔开
NLS_CURRENCY 本地货币字符
NLS_ISO_CURRENCY ISO货币字符
NLS_SORT 字符排序序列
二、字符集转换
1、NLS_LANG参数的修改方法:
1)用SYS用户名登陆ORACLE。
2)查看字符集内容
SQL>SELECT * FROM PROPS$;
3)修改相应的字符子集
SQL>UPDATE PROPS$ SET VALUE$=’SIMPLIFIED CHINESE ‘
WHERE NAME=’NLS_LANGUAGE’;
4) 递交COMMIT;
2、NLS_LANG参数的具体应用:
1)采用服务器端/客户端方式,两端字符集不同
修改客户端字符集:
WIN95/WIN98:修改注册表
HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/NLS_LANG
UNIX:按照1方法,直接进入ORACLE 修改。
2)不同字符集使用EXP/IMP命令
按照1方法,修改IMP端的字符集设置,如果是WIN98/WIN95系统,还必须修改注册表。注意:NLS_LANG三个子集的参数必须一致。另外,如果字符集单双字节设置不同,则不能通过修改字符集进行转换。可以使用其他方式,不修改字符集,进行ORACLE数据库搬移,如数据量比较小,可以使用SQLLOAD命令,通过文本文件转换;使用其他数据库软件(ACCESS,FOXPRO等)转换。


首页 - 关于泡吧 - 加盟机会 - 广告服务 - 版权声明 - 您请留言


【如何查看数据库的字符集?】

软件环境:
1、Windows NT4.0+ORACLE 8.0.4
2、ORACLE安装路径为:C:/ORANT

实现方法:
SQL> conn sys/change_on_install
SQL> desc props$
SQL> set arraysize 1
SQL> col value$ format a40 --格式化value$的输出为40个字符宽
SQL> select name,value$ from props$ where name='NLS_CHARACTERSET';

SQL> conn system/manager
SQL> select * from nls_database_parameters;
SQL> select * from V$NLS_PARAMETERS;

SQL> select * from nls_database_parameters;

PARAMETER VALUE
---------------------------------------- -------------------
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-YY
NLS_DATE_LANGUAGE AMERICAN
NLS_CHARACTERSET ZHS16GBK
NLS_SORT BINARY
NLS_NCHAR_CHARACTERSET ZHS16GBK
NLS_RDBMS_VERSION 8.0.4.0.0

查询到12记录.

SQL> select * from V$NLS_PARAMETERS;

PARAMETER VALUE
---------------------------------------- -------------------
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_CURRENCY RMB
NLS_ISO_CURRENCY CHINA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-YY
NLS_DATE_LANGUAGE SIMPLIFIED CHINESE
NLS_CHARACTERSET ZHS16GBK
NLS_SORT BINARY
NLS_NCHAR_CHARACTERSET ZHS16GBK

查询到11记录.




摘自:ORACLE技术网   时间:2002年5月26日



2002年12月21日 星期六  


 

  当前位置:网站首页>>编程语言>>SQL>>数据库技巧 双击自动滚屏

数据库乱码的原因与解决


--------------------------------------------------------------------------------

发表日期:2002年11月4日 已经有77位读者读过此文

数据库乱码的原因与解决


--------------------------------------------------------------------------------



“在SQL*Plus中用insert插进的都是中文的,为什么一存入服务器后,再select出的就是???”

“有的时候,服务器数据先导出,重装服务器,再导入数据,结果,发生数据查询成???”

……

这些问题,一般是因为字符集设置不对造成的。

很久以来,字符集一直是困扰着众多Oracle爱好者的问题,笔者从事Oracle数据库管理和应用已经几年了,经常接到客户的类似上面提到的有关数据库字符集的“告急”和“求救”,在此我们就这个问题做一些分析和探讨。

首先,我们要明确什么是字符集?字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包括关系,如us7ascii就是zhs16gbk的子集,从us7ascii到zhs16gbk不会有数据解释上的问题,不会有数据丢失,Oracle对这种问题也要求从子集到超集的导出受支持,反之不行。在所有的字符集中utf8应该是最大,因为它基于unicode,双字节保存字符(也因此在存储空间上占用更多)。

其次,一旦数据库创建后,数据库的字符集是不能改变的。因此,在设计和安装之初考虑使用哪一种字符集是十分重要的。数据库字符集应该是操作系统本地字符集的一个超集。存取数据库的客户使用的字符集将决定选择哪一个超集,即数据库字符集应该是所有客户字符集的超集。

在实际应用中,和字符集问题关系最大的恐怕就是exp/imp了。在做exp/imp时,如果Client 和Server的nls_lang设置是一样的,一般就没有问题的。但是,要在两个不同字符集的系统之间导数据就经常会有这样或那样的问题,如,导出时数据库的显示正常,是中文,当导入到其他系统时,就成了乱码,这也是一类常见问题。

现在,介绍一些与字符集有关的NLS_LANG参数,

NLS_LANG格式:

NLS_LANG = language_territory.charset

有三个组成部分(语言、地域和字符集),每个成分控制了NLS子集的特性。其中:language 指定服务器消息的语言。

territory 指定服务器的日期和数字格式。

charset 指定字符集

例如:

AMERICAN_AMERICA.US7SCII

AMERICAN _ AMERICA. ZHS16GBK



还有一些子集可以更明确定义NLS_LANG参数:

DICT.BASE 数据字典基本 表版本

DBTIMEZONE 数据库时区

NLS_LANGUAGE 语言

NLS_TERRITORY 地域

NLS_CURRENCY 本地货币字符

NLS_ISO_CURRENCY ISO货币字符

NLS_NUMERIC_CHARACTERS 小数字符和组 分隔开

NLS_CHARACTERSET 字符集

NLS_CALENDAR 日历系统

NLS_DATE_FORMAT 缺省的日期格式

NLS_DATE_LANGUAGE 缺省的日期语言

NLS_SORT 字符排序序列

NLS_TIME_FORMAT 时间格式

NLS_TIMESTAMP_FORMAT 时间戳格式

…… 通过props$动态性能视图,我们可以查看数据库的字符集信息:

$> sqlplus internal

SQL> desc props$

Name Type Nullable Default Comments



NAME VARCHAR2(30)

VALUE$ VARCHAR2(4000) Y

COMMENT$ VARCHAR2(4000) Y



SQL> set arraysize 1

SQL> col value$ format a40

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

NAME VALUE$



NLS_CHARACTERSET ZHS16GBK

SQL> select * from sys.props$;



NAME VALUE$

DICT.BASE 2

DBTIMEZONE 0:00

NLS_LANGUAGE AMERICAN

NLS_TERRITORY AMERICA

NLS_CURRENCY $

NLS_ISO_CURRENCY AMERICA

NLS_NUMERIC_CHARACTERS .,

NLS_CHARACTERSET ZHS16GBK

NLS_CALENDAR GREGORIAN

NLS_DATE_FORMAT DD-MON-RR

NLS_DATE_LANGUAGE AMERICAN

NLS_SORT BINARY

NLS_TIME_FORMAT HH.MI. SSXFF AM

NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM

NLS_TIME_TZ_FORMAT HH.MI.

SSXFF AM TZH:TZM

NLS_TIMESTAMP_TZ_FORMAT DD-MON- RR HH.MI. SSXFF AM TZH:TZM

NLS_DUAL_CURRENCY $

NLS_COMP BINARY

NLS_NCHAR_CHARACTERSET ZHS16GBK

NLS_RDBMS_VERSION 8.1.6.0.0



NAME VALUE$

GLOBAL_DB_NAME SCPDB1

EXPORT_VIEWS_VERSION 8



22 rows selected



SQL>从结果可以看出:

NLS_LANG = AMERICAN _ AMERICA. ZHS16GBK

虽然,数据库的字符集是在create database的时候指定的,以后不允许改变,但在一个已经建立好的数据库上,我们可以通过修改SYS.PROPS$来修改主要是对应客户端的显示,与存储无关。

如:

SQL> conn / as sysdba

Connected.

SQL> SQL> select * from sys.props$

2 WHERE NAME=‘NLS_LANGUAGE’;



NAME VALUE$



NLS_LANGUAGE AMERICAN

SQL>

SQL> UPDATE sys.PROPS$ SET VALUE$=‘SIMPLIFIED CHINESE’

2 WHERE NAME=‘NLS_LANGUAGE’;

1 row updated

SQL>

SQL> select * from sys.props$

2 WHERE NAME=‘NLS_LANGUAGE’;

NAME VALUE$



NLS_LANGUAGE SIMPLIFIED CHINESE

SQL>

通常出现问题的原因,可分为三种:

1. 服务器指定字符集与客户字符集不同,而与加载数据字符集一致。

解决方法:对于这种情况,只需要设置客户端字符集与服务器端字符集一致就可以了,具体操作如下:

* 查看当前字符集:

SQL> select * from sys.props$

2 WHERE NAME=‘NLS_CHARACTERSET’;

NAME VALUE$



NLS_CHARACTERSET ZHS16GBK

SQL>

可以看出,现在服务器端Oracle数据库的字符集为‘ZHS16GBK’

* 根据服务器的字符集在客户端作相应的配置或者安装Oracle的客户端软件时指定:

如果还没安装客户端,那么在安装客户端时,指定与服务器相吻合的字符集即可;如果已经安装好了客户端,并且客户端为 sql*net 2.0 以下版本,进入Windows的系统目录,编辑oracle.ini文件,用US7ASCII替换原字符集,重新启动计算机,设置生效;否则,如果,客户端为 sql*net 2.0 以上版本,在Win98 下 运 行REGEDIT,第一步选HKEY_LOCAL_MACHINE,第二步选择SOFTWARE, 第三步选择 Oracle, 第四步选择 NLS_LANG, 键 入 与服 务 器 端 相 同 的 字 符 集

(本例为:HKEY_LOCAL_MACHINE/

SOFTWARE/ORACLE/NLS_LANG :AMERICAN _ AMERICA. ZHS16GBK)。

如果是UNIX客户端,则:

SQL> conn / as sysdba

Connected.

SQL> SQL> UPDATE sys.PROPS$ SET VALUE$=‘SIMPLIFIED CHINESE’

2 WHERE NAME=‘NLS_LANGUAGE’;

1 row updated

SQL> COMMIT;

Commit complete

SQL> 2. 服务器指定字符集与客户字符集相同,与加载数据字符集不一致。

解决方法:强制加载数据字符集与服务器端字符集一致。要做到这一点,可以通过重新创建数据库,并选择与原卸出数据一致的字符集,然后IMP数据,这种情况仅仅适用于空库和具有同一种字符集的数据。

解决这类问题,也可以先将数据加载到具有相同字符集的服务器上,然后用转换工具卸出为foxbase 格式或access格式数据库,再用转换工具转入到不同字符集的Oracle数据库中,这样就避免了Oracle字符集的困扰。目前数据库格式转换的工具很多,像power builder5.0以上版本提供的pipeline及Microsoft Access数据库提供的数据导入/导出功能等。

3. 服务器指定字符集与客户字符集不同,与输入数据字符集不一致。

对于这种情况,目前为止都还没有太好的解决方法。

通过上面的了解,我们知道,导致在后期使用数据库时出现种种关于字符集的问题,多半是由于在数据库设计、安装之初没有很好地考虑到以后的需要,所以,我们完全可以通过在服务器上和客户端使用相同的字符集来避免由此类问题引出的麻烦。





--------------------------------------------------------------------------------


相关专题:

--------------------------------------------------------------------------------


相关信息:

没有相关信息

--------------------------------------------------------------------------------


相关评论:

没有相关评论




  发表、查看更多关于该信息的评论 将本信息发给好友 打印本页



设为首页 | 加入收藏 | 联系我们 | 管理入口
版权所有 Copyright ? 2001-2002 索酷搜索 All Rights Reserved 保留所有权利
索酷搜索综合管理系统 V3.0 build 20020931 制作、技术支持:杨正炎
 
就是修改一下字符集,unicode ,只要原来的字符集和现在的是兼容的,那么里边的数据不会变成
乱码。
不过你的客户端的字符集也要改成unicode 有些外国字符不是双字节的,可能是3,4 字节的,
就要用nvarchar2

一点经验
 
楼上的兄弟不他的问题不会有你说的那么简单吧?
 
接受答案了.
 
顶部