分类: Oracle
2006-07-25 09:30:52
通常在我们的现实环境中,存在3个字符集设置。
第一: 客户端应用字符集(Client Application Character Set)
第二: 客户端NLS_LANG参数设置
第三: 服务器端,数据库字符集(Character Set)设置
在服务器端创建数据库时需要设置两个字符集参数,一个是NLS_CHARACTERSET, 一个是NLS_NCHAR_CHARACTERSET,也可以在sql提示符下用select userenv(‘language’) from dual;来查询。其中前者用于存放char,varchar,varchar2等字符,后者用于存放nchar,nvarchar,nvarchar2等字符,该参数值可以通过v$nls_parameters视图查询。
1.源数据库和目标数据库具有相同字符集设置
这时,只需要设置NLS_LANG等于数据库字符集即可导入(前提是,导出使用的是和源数据库相同字符集,即三者相同)
2.源数据库和目标数据库字符集不同
如果我们导出时候使用的NLS_LANG是和源数据库相同的字符集,那么导入时就可以设置客户端NLS_LANG等于导出时使用的字符集,这
样转换只发生在数据库端,而且只发生一次。
例如:
如果进行从WE8MSWIN1252到UTF8的转换
1)使用NLS_LANG=AMERICAN_AMERICA.WE8MSWIN1252导出数据库。
这时创建的导出文件包含WE8MSWIN1252的数据
2)导入时使用NLS_LANG=AMERICAN_AMERICA.WE8MSWIN1252
这时转换仅发生在insert数据到UTF8的数据库中。
以上假设的转换只在目标数据库字符集是源数据库字符集的超集时才能转换。如果不同,一般就需要进行一些特殊的处理。
我们简单看一下导入的转换过程(以Oracle8i为例):
(1)确定导出数据库字符集环境
通过读取导出文件头,可以获得导出文件的字符集设置
(2)确定导入session的字符集,即导入Session使用的NLS_LANG环境变量
(3)IMP读取导出文件
读取导出文件字符集ID,和导入进程的NLS_LANG进行比较
(4)如果导出文件字符集和导入Session字符集相同,那么在这一步骤内就不需要转换
如果不同,就需要把数据转换为导入Session使用的字符集。
然而这种转换只能在单byte字符集之间进行。
我们看一个测试:
E:\nls2>set NLS_LANG=AMERICAN_AMERICA.US7ASCII
设置导入session NLS_LANG为US7ASCII
E:\nls2>e:\oracle\ora8i\bin\imp eygle/eygle file=Sus7ascii-Cus7ascii-exp817.dmp fromuser=eygle touser=eygle tables=test
这个导出文件是从US7ASCII数据库导出,导出客户端NLS_LANG也是US7ASCII
Import: Release 8.1.7.1.1 - Production on Fri Nov 7 00:59:22 2003
(c) Copyright 2000 Oracle Corporation. All rights reserved.
Connected to: Oracle8i Enterprise Edition Release 8.1.7.1.1 - Production
With the Partitioning option
JServer Release 8.1.7.1.1 - Production
这时导入,在DMP文件和NLS_LANG之间不需要进行字符集转换。
Export file created by EXPORT:V08.01.07 via conventional path
import done in US7ASCII character set and ZHS16GBK NCHAR character set
import server uses ZHS16GBK character set (possible charset conversion)
export server uses UTF8 NCHAR character set (possible ncharset conversion)
. . importing table "TEST" 2 rows imported
Import terminated successfully without warnings.
(5)对于多Byte字符集的导入(如:UTF8)
需要设置导入Session字符集和导出字符集相同
否则就会遇到:IMP-16 "Required character set conversion (type %lu to %lu) not supported" 错误。
:
E:\nls2>set NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
导入Session字符集设置为ZHS16GBK
导入US7ASCII的导出文件
E:\nls2>e:\oracle\ora8i\bin\imp eygle/eygle file=Sus7ascii-Cus7ascii-exp817.dmp fromuser=eygle touser=eygle
Import: Release 8.1.7.1.1 - Production on Fri Nov 7 00:38:55 2003
(c) Copyright 2000 Oracle Corporation. All rights reserved.
Connected to: Oracle8i Enterprise Edition Release 8.1.7.1.1 - Production
With the Partitioning option
JServer Release 8.1.7.1.1 - Production
IMP-00016: required character set conversion (type 1 to 852) not supported
IMP-00000: Import terminated unsuccessfully
在从导出文件US7ASCII到导入 NLS_LANG设置为ZHS16GBK的过程中,不支持单Byte字符集向多Byte转换,报出以上错误。
(6)导入Session字符集应该是导出字符集的超级,否则,专有的字符将难以正确转换。
(7)当数据转换为导入Session字符集设置以后,如果导入Session字符集不同于导入数据库字符集,这时还需要最后一步转换,这要求导入数据库字符
集是导入session字符集的超级,否则某些专有字符将不能正常转换。
我们继续看上面的两个过程,这里有这样两个原则:
1.如果NLS_LANG的设置和数据库相同,那么数据(在传输过程中当然是2进制码)不经过转换就直接插入数据库中。
2.如果NLS_LANG的设置和数据库不同,那么数据需要转换后才能插入数据库中。
我们再回头来看上面的第一个例子:
Export file created by EXPORT:V08.01.07 via conventional path
import done in US7ASCII character set and ZHS16GBK NCHAR character set
import server uses ZHS16GBK character set (possible charset conversion)
export server uses UTF8 NCHAR character set (possible ncharset conversion)
. . importing table "TEST" 2 rows imported
Import terminated successfully without warnings.
这时候经过第一步转换后的数据,US7ASCII到ZHS16GBK丢失首位,原样插入数据库,我们看到这时数据库中存放的就是错误的字符(在后面
部分我们做了详细的转换):
E:\nls2>sqlplus rainny/rainny
SQL*Plus: Release 9.2.0.4.0 - Production on Fri Nov 7 00:35:39 2003
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Connected to:
Oracle8i Enterprise Edition Release 8.1.7.1.1 - Production
With the Partitioning option
JServer Release 8.1.7.1.1 - Production
SQL> select * from test;
NAME
--------------------
2bJT
test
__________________
附:Code Pages Supported by Windows
SBCS (Single Byte Character Set) Codepages
DBCS (Double Byte Character Set) CodepagesIn these graphical representations, leadbytes are indicated by light gray background shading. Each of these leadbytes hyperlinks to a new page showing the 256 character block associated with that leadbyte. Unused leadbytes are identified by a darker gray background.
Windows OEM Code PagesThe list below provides links to graphical representations, and textual listings, of each of the Windows OEM code pages:
Windows ANSI and OEM Code PagesThe following codepages are used as both Windows ANSI and OEM codepages:
|