楼主: linwz

怎么将字符集为US7ASCII的库中导出的数据导入到字符集为ZHS16GBK的库中?

[复制链接]
论坛徽章:
314
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
31#
发表于 2003-4-11 18:59 | 只看该作者
最初由 linwz 发布
[B]

另外,还是最开始那个问题,我在NT中没有设NLS_LANG变量,其默认值应该是什么?
非常感谢大家!! 也希望大家继续关注!! [/B]


查看一下注册表,看看里面的NLS_LANG的值为多少!

使用道具 举报

回复
论坛徽章:
0
32#
 楼主| 发表于 2003-4-11 20:34 | 只看该作者
to  秦淮夜月, 呵呵,你说的很对!
我设NLS_LANG=AMERICAN_AMERCA.US7ASCII后,进SQLPlus插入中文数据,字段f2中是正常是显示为中文了,但f3中还是乱码。刚才我也想到这点了,不过我改了NLS_LANG后,没有插数据进过,只读出数据看了看,说明还是理解的不大清楚。那你能给你解释一下,为什么我在导出时,系统自动做的从US7ASCII到ZHS16GBK转换却不能导入到字符集为ZHS16GBK的库中去呢?是导出时转换的不对,还是导入时转换的不对?为什么会不对?

to ZALBB,我前面说过了,注册表中没有设NLS_LANG。现在看来,默认值应是SIMPLIFIED CHINESE_CHINA.ZHS16GBK

使用道具 举报

回复
33#
匿名  发表于 2003-4-11 20:37
最初由 linwz 发布
[B]to  秦淮夜月, 呵呵,你说的很对!
我设NLS_LANG=AMERICAN_AMERCA.US7ASCII后,进SQLPlus插入中文数据,字段f2中是正常是显示为中文了,但f3中还是乱码。刚才我也想到这点了,不过我改了NLS_LANG后,没有插数据进过,只读出数据看了看,说明还是理解的不大清楚。那你能给你解释一下,为什么我在导出时,系统自动做的从US7ASCII到ZHS16GBK转换却不能导入到字符集为ZHS16GBK的库中去呢?是导出时转换的不对,还是导入时转换的不对?为什么会不对?

to ZALBB,我前面说过了,注册表中没有设NLS_LANG。现在看来,默认值应是SIMPLIFIED CHINESE_CHINA.ZHS16GBK [/B]


是在你这个特定情况下,导出已经不对了。实际上用US7ASCII数据库字符集存放中文是不好的,不明白为什么你们要这样做,你可以看看我在这个主题下之前的一个帖子,我解释了原因

使用道具

回复
论坛徽章:
0
34#
 楼主| 发表于 2003-4-11 20:53 | 只看该作者
to 秦淮夜月: 呵呵,我看过了,也相信是你说的不错。可能我一直被一个现象给误导了,就是我在UltraEdit中看到导出文件中的中文显示的是正常的,所以我认为导出文件是正常的。

现在,为什么F3字段还是不行?F3是NChar型的,我的NChar字符集是AL16UTF16

只所以用了US7ASCII,是我那时用角本建库时,没写字符集,系统默认了这个字符集,我本来只是用来测试下的,后来一个同事找了个论坛源码,想学习和测试一下,要用我的数据库,我就把这个给他用上了,后来我 想把这个库移出到那个ZHS16GBK库中时,才发现了这个问题。呵呵,在你和大家的帮助下,让我弄清楚了不少东西,倒是不小的收获了,这可是我开始没有想到的!

所以,现在心里感谢你,感谢这里所有热心的人们!!

使用道具 举报

回复
论坛徽章:
0
35#
发表于 2003-4-11 22:30 | 只看该作者
最初由 秦淮夜月 发布
[B]看来还没理解字符集问题的精粹。

“我重建字符集为US7ASCII的库后,库中竟然不能保存和显示中文”
库只是保存,显示是前端字符集和OS字符集的问题。你在前端exp出来的dump文件是03 54,那你的缺省前端字符集肯定是ZHS16GBK。你如果要在us7ascii的数据库里放中文,那前端也必须是us7ascii。如果前端是ZHS16GBK,由于它是US7ASCII的superset,所以在前后端字符转换的时候会产生乱码。

[/B]


在导入导出过程中要控制并保持
NLS_LANG(前端字符集NLS_LANG='*******')和
update props$ set values$='*****' where name='NLS_CHARACSET'(数据库字符集); 两者一直。修改.dmp文件时改变前端字符集的一种手段!
那么,导出的数据库内容的存储格式和前端字符集和数据库字符集都是一种什么关系!
可以认为导出的dmp文件的数据部分存储格式是由数据库的字符集控制的吗?而且,其二、三个字节只是标示当前操作系统的前端字符集,和后面的数据部分没有必然的联系。也就是说dmp前面二、三字节的内容是受OS的前端字符集控制的,而后面的数据部分是受数据库字符集控制的。否则怎么可能简单改变dmp文件的二、三字节就可以实现呢?

使用道具 举报

回复
36#
匿名  发表于 2003-4-11 23:59
写得有点乱,没能理解清楚,大概有下面几点:
1)exp的时候如果前端字符集和数据库字符集不同,会产生转换,所以选取前端字符集不同肯定会造成dmp文件内容不同。当前端和后端字符集相同时,不会发生转换,那dmp文件里就采用数据库里的字符集编码方案了
2)改dmp文件第二、三字节的做法只在特定条件下有效,并非可以任意修改
3)“也就是说dmp前面二、三字节的内容是受OS的前端字符集控制的,而后面的数据部分是受数据库字符集控制的。”
这句话有点问题,前端字符集和OS字符集是不同概念,估计混淆了这两个概念了


最初由 ybz3721 发布
[B]

在导入导出过程中要控制并保持
NLS_LANG(前端字符集NLS_LANG='*******')和
update props$ set values$='*****' where name='NLS_CHARACSET'(数据库字符集); 两者一直。修改.dmp文件时改变前端字符集的一种手段!
那么,导出的数据库内容的存储格式和前端字符集和数据库字符集都是一种什么关系!
可以认为导出的dmp文件的数据部分存储格式是由数据库的字符集控制的吗?而且,其二、三个字节只是标示当前操作系统的前端字符集,和后面的数据部分没有必然的联系。也就是说dmp前面二、三字节的内容是受OS的前端字符集控制的,而后面的数据部分是受数据库字符集控制的。否则怎么可能简单改变dmp文件的二、三字节就可以实现呢? [/B]

使用道具

回复
论坛徽章:
0
37#
发表于 2003-4-12 11:48 | 只看该作者
在注册表中找到的NLS_LANG是前段字符集还是前段字符集?
那么另外一种字符集又是什么,怎么看和控制?
在什么情况下修改dmp文件才有效



最初由 秦淮夜月 发布
[B]写得有点乱,没能理解清楚,大概有下面几点:
1)exp的时候如果前端字符集和数据库字符集不同,会产生转换,所以选取前端字符集不同肯定会造成dmp文件内容不同。当前端和后端字符集相同时,不会发生转换,那dmp文件里就采用数据库里的字符集编码方案了
2)改dmp文件第二、三字节的做法只在特定条件下有效,并非可以任意修改
3)“也就是说dmp前面二、三字节的内容是受OS的前端字符集控制的,而后面的数据部分是受数据库字符集控制的。”
这句话有点问题,前端字符集和OS字符集是不同概念,估计混淆了这两个概念了


[/B]

使用道具 举报

回复
38#
匿名  发表于 2003-4-12 13:24
最初由 ybz3721 发布
[B]在注册表中找到的NLS_LANG是前段字符集还是前段字符集?
那么另外一种字符集又是什么,怎么看和控制?
在什么情况下修改dmp文件才有效



[/B]


NLS_LANG用于指定前端字符集,后端也就是数据库字符集是在建立数据库的时候指定的。后端的字符集只有在特定条件下才可以修改,详细可以看右上角工具条上的“资料库”里的文章,进去后以“字符集”搜索一下就可以。
改dmp文件的一个例子就好象楼主的情况喽,在大多数情况下是不能乱改的,你把当中的原理搞明白就可以理解个中原因。oracle太复杂,强记一些操作学不上手的,一定要理解概念。
顺便说说楼主帖子里的一些问题
1)exp/imp的字符集转换过程
做exp时,系统会比较前后端字符集,如果相同,就直接exp,如果不同,就发生转换,比如从字符集A转到B。
做imp时,首先会比较exp的字符集B和当前前端字符集C是否相同,如果相同就执行imp,如果不同就首先进行转换,但能转换的前提是必须为单字节字符集,如果不是单字节字符集则会提示imp错误
,这个也是为什么US7ASCII的dmp文件,不能在ZHS16GBK前端下imp的原因,因此只能强行修改。imp完成了dmp文件的转换后,就往库里插入,这个时候也要进行前后端字符集转换,如果字符集不同的话
2)字符集怎么转换?例如ZHS16GBK和ZHS16231280,一般是以UTF8作为中介,因为它几乎包含其他一切字符,如果映射不到的就产生“?”号,Oracle在它的文档里也规定了一系列字符集之间的包含关系,通常是US7ASCII和另一种字符集,也有个别例外。详细清单在itpub资料库里也有。ZHS16GBK和ZHS16231280在oracle角度看不存在包含关系。
3)如楼主所说,前后端都用US7ASCII,可以存/取中文,没有问题,为什么把前端改为ZHS16GBK后,反而会乱码呢?这里主要是中文字符高位为1的问题。US7ASCII是个7位字符集,但它在存储的时候是占一个字节的,因此第8个位就有点玄妙了。当前后端都是US7ASCII的时候,输入的中文字符会被OS拆分为两个ASCII字符,当然高位有可能是1的,由于前后端字符集相同,net8不会转换字符,它会把整个字符,包括高位“1”也“忠实地”存放在数据库里,当要输出时,则连续的两个ASCII字符会被OS重新组合为汉字。
但如果前端变成ZHS16GBK,则在输出的时候首先要把US7ASCII转为ZHS16GBK,这个时候高位1会被清除,在输出后将显示乱码。因此存储汉字最好还是用汉字字符集,而不要使用7bits字符集的数据库来存储。

使用道具

回复
论坛徽章:
0
39#
 楼主| 发表于 2003-4-12 15:51 | 只看该作者
感谢秦淮夜月兄不厌其烦的关注,但是我做了一些测试后,现在又有点不明白了。

情况是这样的,我设置NLS_LANG=AMERICAN_AMERICA.US7ASCII后,在SQL PLUS中向TT表中插入中文,保存和显示都没有问题。提交后,我退出SQL Plus,运行EXP导出了这个表。然后,我又设置NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK,然后我又做了一个EXP,这两份分别为不同是导出文件。

然后,我用UltraEdit分别打开两个文件,发现两个字符集是不同,第一个是00 01后面一个是03 54。这一点秦淮夜月兄解释的很清楚了,是因为导出第一个文件前后端字符集是相同的,所以导出时没有做字符集转换,而后面一个前端是ZHS16GBK而后端是US7ASCII,所以做了从US7ASCII到ZHS16GBK的转换。

但是,我发现,这两个文件后面的关于实际的库结构和数据的内容几乎是一模一样的,两个文件中的中文数据显示都是正常的。我分别删除了这两个文件的前129个字节的头后,用FC命令比较,结果如下:
D:\temp>fc /b test_us7ascii_old.DMP test_zhs16gbk_old.DMP
正在比较文件 test_us7ascii_old.DMP 和 TEST_ZHS16GBK_OLD.DMP
00000811: 00 03
00000812: 01 54
00000813: 00 03
00000814: 01 54
000008E0: 33 36
000008E1: 39 31
000008E2: 37 33

注意,关键的不同是00000811-00000814处是四个字节分别为两个不同字符集的代码即,第一个文件是00 01 00 01第二个文件是03 54 03 54。后面三个字节的不是个inst_scn号

是不是由此可见,实际上,两种前端字符集下导出的文件其实主要部分是没有什么区别的,导出程序只是在导出文件中记录下了两种前端字符集,但数据还是原库中的字符原样没有作转换。
或者,还是因为US7ASCII是ZHS16GBK的子集,所以才没有看出转换效果?

如果确实是这样的,说明导出文件时并没有出错,错误的转换可能发生在导入时。

我跟前面一样分别设置两种NLS_LANG后分别导入了两个导出文件(即我作了四次导入),但是发现导入后始终是乱码。

秦淮夜月兄说:“做imp时,首先会比较exp的字符集B和当前前端字符集C是否相同,如果相同就执行imp,如果不同就首先进行转换,但能转换的前提是必须为单字节字符集,如果不是单字节字符集则会提示imp错误 ,这个也是为什么US7ASCII的dmp文件,不能在ZHS16GBK前端下imp的原因,因此只能强行修改。imp完成了dmp文件的转换后,就往库里插入,这个时候也要进行前后端字符集转换,如果字符集不同的话 ”

但是从我测试的这个结果看来,是不是只要导出库是US7ASCII的,而导入库是ZHS16GBK的,无论导入时前端是那种字符集,都不能正常导入??

看来直接导入时不行了,于是,我试图按照coolyl的方法,来做,
1。确定你A机上的oracle用户的.profile文件中的NLS_LANG是US7ASCII,正常的导出所有数据。
2。然后传到B机上,bin模式,然后在B机上设定好oracle用户的设定环境变量NLS_LANG=AMERICAN_AMERICA.US7ASCII
以sys用户执行update props$ set values$='US7ASCII'
where name='NLS_CHARACSET';
3。正常的导入数据至ZHS16GBK的数据库中去,重新启动数据库,此时查看原来导入的数据应该已经中文了。

我是Windows2000环境,我做了前面两步,第三步完成导入后,我作了Shutdown,然后,我再作Startup,这时问题就出来了:
SQL> startup
ORA-01031: insufficient privileges
SQL>
数据库启不来了,在导入之前,即update props$之前,是一点问题都没有的。我重启ORACLE的服务后,还是不能Startup。

不知道我描述清楚了没有,希望大家仔细的看一看,然后再帮助分析一下我这次测试,能不能再做做总结。

另个,关于前面提到的Nchar型中中文不正常的现象,也请大家关注。

使用道具 举报

回复
论坛徽章:
314
行业板块每日发贴之星
日期:2012-07-12 18:47:29双黄蛋
日期:2011-08-12 17:31:04咸鸭蛋
日期:2011-08-18 15:13:51迷宫蛋
日期:2011-08-18 16:58:25紫蛋头
日期:2011-08-31 10:57:28ITPUB十周年纪念徽章
日期:2011-09-27 16:30:47蜘蛛蛋
日期:2011-10-20 15:51:25迷宫蛋
日期:2011-10-29 11:12:59ITPUB十周年纪念徽章
日期:2011-11-01 16:19:41鲜花蛋
日期:2011-11-09 20:33:30
40#
发表于 2003-4-12 17:34 | 只看该作者
想问一点,你在导入前:
我跟前面一样分别设置两种NLS_LANG后分别导入了两个导出文件(即我作了四次导入),但是发现导入后始终是乱码。

有没有把第一个导出文件的第二第三个字节改为0354?

说清楚,或者把这个文件上传上来。我试试。[B]第一个导出文件[/B]

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表