这是个很麻烦的问题。我曾经成功的把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的数据库)
试试行不行
其实,操作的方法有几种。
我给你几篇看看最常碰到的字符集的问题多是不能正常显示,一般这种问题只要把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的数据库)
试试行不行
解决方案 »
- 添加数据,批量
- oracle中怎么实现数据反转
- ORACLE 记录类型
- oracle存储过程能输出空值参数吗?
- 请推荐一本好的Oracle教材
- 求救!为什么老是提示“无法解析连接描述符中指定的SID“啊?在线等!谢谢先!
- sql server 中基础概念 如何和oracle中的对应起来,和谁对应?up 有分
- 请教:如何获取对象的属性信息?比如有个dba_role_privs,我想知道它的类型(是表吗?我怎么没有找到?)、所属的方案、所在的表空间,等等
- 在VB开发环境下运行正常,但编译成exe可执行文件后运行提示:"运行时错误-2147467259(80004005) ORA-06413:连接未打开" 该如何解决?
- sql 中如何选择出带有''号的字符串
- Connection reset by peer: JVM_recv in socket input stream read
- 如何动态改边查询语句中的表名或字段名?
从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、改字符集后一定要重新启动数据库使之生效
用一个文本文件作为中介,将源库中的信息以一定的工具,如GOLD LOAD,倒成一个文本文件,或者用UTL_FILE包利用PL/SQL写到文本文件中。
然后再用同样的方法写入目标库中。
这种方法可能更具通用性,但没有试过。
一了百了。
但不知chooser说的ORACLE公司提供的家传绝技是什么?
其实只是ORACLE公司说改数据库字符集很危险,给了一个标准的操作步骤,建议我照做而已。