这是个很麻烦的问题。我曾经成功的把ZHS16GBK字符集的数据库导出/导入到US7ASCII字符集的数据库中,操作还是比较麻烦的。
其实,操作的方法有几种。
我给你几篇看看最常碰到的字符集的问题多是不能正常显示,一般这种问题只要把client端的nls_lang设置和服务器中的值设置成一样就可以。这方面已有很多人都讲过,不用我多说。 
我认为比较麻烦的就是在两台不同字符集的数据库之间exp/imp数据
要想imp以后的数据和imp以前的数据库中原有的数据都能正常显示就需要一些技巧,并考虑几方面的因素,如
exp出来的数据当初写入数据库的时候使用的字符集是否和服务器一致?exp时使用的字符集是什么?
一般分为两大类情况
(一)原始数据写入的时候client字符集和服务器不一致,那么在导入之后必须使用写入时采用的字符集才能正常显示
实验如下:
DB1 (服务器字符集为GBK) 
set nls=BIG5 ,分别写简体中文和繁体中文数据到表test1,
(只有简体中文在该DB1中显示正常)
现要将该表的数据导入导另外一个数据库
DB2 (服务器字符集BIG5)方法A : set nls=BIG5 后exp DB1上的表test1
set nls=BIG5 后imp 表test1到DB2
使用sqlplus或svrmgr30 , set nls=big5 在DB2中查询显示和 set nls=BIG5 在DB1中中显示一致 
方法B : set nls=gbk 后exp DB1上的表test1
set nls=gbk 后imp 表test1到DB2
使用sqlplus或svrmgr30 , set nls=big5 在DB2中查询显示和 set nls=big5 在DB1中中显示一致 
反过来实验结果也是类似:
DB1 (服务器字符集为BIG5) 
set nls=GBK ,分别写简体中文和繁体中文数据到表test2,
(现在只有繁体中文在该DB1中显示正常)现要将该表的数据导入导另外一个数据库
DB2 (服务器字符集GBK)方法A : set nls=gbk 后exp DB1上的表test2
set nls=gbk 后imp 表test2到DB2
使用sqlplus或svrmgr30 , set nls=GBK 在DB2中查询显示和 set nls=gbk 在DB1中中显示一致 方法B : set nls=BIG5 后exp DB1上的表test2
set nls=BIG5 后imp 表test2到DB2
使用sqlplus或svrmgr30 , set nls=GBK 在DB2中查询显示和 set nls=gbk 在DB1中中显示一致 其实从上面的实验可以看出,如果要在两台不同字符集数据库之间exp/imp数据且原始数据写入时和数据库不一致,在exp/imp时必须使用同样的字符集合,并且要使用原始数据写入时采用的字符集才能正常 显示,(使用GBK写入,导入新的数据库也要使用GBK来读才正常)
二)原始数据写入的时候client字符集和服务器一致
在这种情况下就必须使用强制数据字符转换
如要把一个字符集为BIG5数据库的dmp出来的数据导入导GBK或其他字符集的数据库
可按下面的方法来做:
---- 在用imp命令加载数据前,先在客户端用sql*plus登录system DBA用户,执行下列SQL语句进行当前ORACLE数据库字符集修改: SQL > create database character set ZHT16BIG5 
* create database character set US7ASCII 
ERROR at line 1: 
---- 你会发现语句执行过程中,出现错误提示信息,此时不用理会,实际上ORACLE数据库的字符集已被强行修改为US7ASCII,接着用imp命令装载数据。等数据装载完成以后,shutdown 数据库,再startup 数据库,用合法用户登录ORACLE数据库,在sql>命令提示符下,运行select * from V$NLS_PARAMETERS,可以看到ORACLE数据库字符集已复原,这时再查看有汉字字符数据的表时,汉字已能被正确显示。 
这种做法我已在8。0。5上实验过,没问题,8i有人说不行。
另外网上有网友提供的修改props$表的方法,似乎行不通,还有导入前修改nls_lang 可以导入新数据,但无法和旧的数据同时正常显示(例如BIG5的exp文件以BIG5导 入GBK的数据库) 
试试行不行

解决方案 »

  1.   

    这个方法我在805上测试过,ZHS16GBK->US7ASCII
    从ZHS16GBK的数据库中导出数据,假如zhs.dmp,里面含有表test1(中文)
    到US7ASCII的数据库
    1、按正常从ZHS16GBK的数据库导出数据zhs.dmp。2、在US7ASCII的数据库svrmgr30中:
    update props$ set value$='ZHS16GBK' WHERE NAME='NLS_CHARACTERSET';
    COMMIT;
    设置注册表NLS_LANG = …….ZHS16GBK

    NLS_LANG = AMERICAN_AMERICA.ZHS16GBK
    以上设置临时环境为ZHS16GBK
    3、重起数据库
    4、导入zhs.dmp
    5、update props$ set value$='US7ASCII' WHERE NAME='NLS_CHARACTERSET';
    设置注册表NLS_LANG = …….US7ASCII
    重起数据库
    修改环境到US7ASCII
    6、select * from v$nls_parameters;
    NLS_CHARACTERSET = US7ASCII
    7、查询test1,正常。
    -----------------------------
    需要注意的是:
    1、这里通过props$来强行修改字符集是可以的。
    但是修改的同时不要忘了环境变量NLS_LANG 一定要同时修改。
    2、导入的那台数据库的字符集只是临时通过props$改变,如果想导入
    ZHS16GBK字符集数据,可以改成ZHS16GBK,但先前一定要是US7ASCII,导完了再改回来
    3、改字符集后一定要重新启动数据库使之生效
      

  2.   

    我觉得这样考虑是不是可以?
    用一个文本文件作为中介,将源库中的信息以一定的工具,如GOLD LOAD,倒成一个文本文件,或者用UTL_FILE包利用PL/SQL写到文本文件中。
    然后再用同样的方法写入目标库中。
    这种方法可能更具通用性,但没有试过。
      

  3.   

    还有一种,更简单的方法,就是用ORACLE公司提供的家传绝技,改掉某个数据库的字符集...
    一了百了。
      

  4.   

    文本文件是个好办法,但是如果有二进制数据或大字段时,是行不通的。
    但不知chooser说的ORACLE公司提供的家传绝技是什么?
      

  5.   

    不敢在星星版主面前卖弄。
    其实只是ORACLE公司说改数据库字符集很危险,给了一个标准的操作步骤,建议我照做而已。
      

  6.   

    LOB或RAW类型字段,文本文件是不能用的。不过这类字段在一般数据库应用中用得不多,如果没有用到这两大类字段,用文本文件做中介会比较方便。
      

  7.   

    我试过了,直接用exp/imp导就可以了,字符集会自动转换。不过还是要 谢谢各位。