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

来源:互联网 发布:淘宝首页模板 编辑:程序博客网 时间:2024/06/11 22:11
对于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传输模
  用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$内容

  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_SORTBINARY
  NLS_NCHAR_CHARACTERSET  ZHS16GBK
  NLS_RDBMS_VERSION  8.0.5.0.0
  GLOBAL_DB_NAMEORACLE.WORLD
  EXPORT_VIEWS_VERSION7
  已选择15行。
  4.2查看Oracle 8.0.4 for Digital UNIN 的props$内容
  SQL> connect sys/change_on_install
  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_VERSION7
  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。