此处主要是关于NLS_LANG这个环境变量的说明,客户端依据其最先找到的NLS_LANG作为参考字符集,顺序为:用户级环境变量,系统级环
一 字符集与导出导入问题总结
首先是必须保证Oracle的数据库服务端与客户端字符集一致,这样就能保证数据编码的一致性。
当数据库服务端选用ZHS16GBK时,当导出导入新的数据过程中,数据库服务端会对导入的二进制数据库作ZHS16GBK编码检查,当数据长度为奇数值时,出现数据的最后一个字节对应十进制为:129到254时,会丢失此字节,具体解释见第二节内容。
当数据库服务端选用WE8ISO8859P1时,当导出导入新的数据过程中,数据库服务端会对导入的二进制数据库作WE8ISO8859P1编码检查,逐个字节内容进行,不会有数据丢情况发生,具体解释见第二节内容;
针对在不同的字符集下将密文表数据进行导出导入后会有数据丢失的情况,下面作详细描述。
二 ZHS160GBK与WE8ISO8859P1字符集说明
对于上面提到的两种字符集,ZHS16GBK是Windows系统安装Oracle时,默认的数据库字符集,WE8ISO8859P1是Linux系统的默认安装的数据库字符集。且两种字符集都支持中文,至于国家字符集的选择,这里我们都是选择AF16UTF16。数据库安装完成后,可以用 select userenv('language') from dual 语句进行查看。对于ZHS16GBK字符集,数据库按双字节进行处理,且当字节对应的十进制数从129到254时,Oracle会按双字节处理,从而查找下一个字节内容,两个字节组成一个整体进行处理;但对WE8ISO8859P1,数据库完全是按单字节进行处理,所以不会有什么字节检查。
三当数据库为ZHS16GBK的情况描述
1 数据库端配置
在Windows下我们使用默认的Oracle安装,当要DBCoffer正常工作时,需对listener.ora进行修改,其参考配置如下:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = ljb)
(ORACLE_HOME = E:\oracle\product\10.2.0\db_1)
)
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = E:\oracle\product\10.2.0\db_1)
(ENVS = EXTPROC_DLLS=ANY)
(PROGRAM = extproc)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = extproc))
(ADDRESS = (PROTOCOL = TCP)(HOST = Jiabo)(PORT = 1521))
)
)
表1
关于此种情况下的Oracle客户端环境变量的设置,可以在注册表查找到:
NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
2 加密解密情况描述
正常安装DBCoffer完成后,便可以正常加密解密数据
3 导出导入情况描述
当加密一个表后,我们知道加密后的密文长度都是一个奇数值,当将密文表用exp命令导出数据库后,然后将原密文表重命名,而后将导出的数据导入数据库,此时会出现的情况是密文字段部分数据的最后一个字节内容丢失,当再次将此时导入的密文表再次导出去,并且与原导出的表的二进制文件进行比较时,明显数据对不上,且丢失的字节大小范围都在对应的十进制的129到254,那么这样一来,就可以确定是数据库字符集处理产生的问题,因为密文长度是一个奇数值,假如当密文的数据的最后一个字节内容为129到254时,会出现如前面所描述的情况发生,Oracle服务端会将最后一个字节作双字节处理,如果找不到下一
个字节,则将此字节丢失。
关于以上情况:我们可以用lengthb(密文字段)去查看,原密文表的密文长度都是一个固定的奇数值,而再次导入表密文表的密文字段有部分是比该奇数值小1的,所以针对密文表的查询会报-10004,加密数据不完整。
四当数据库为WE8ISO8859P1的情况描述
1 新建一个Oracle数据库实例iso8859
此步可以利用DBCA工具进行,当进行至第十步时,按下图所示设置数据库字符集。
图 1
2 修改Oracle的listener.ora和tnames.ora的配置
关于listener.ora的配置参考如下:
# listener.ora Network Configuration File: E:\oracle\product\10.2.0\db_1\network\admin\listener.ora
# Generated by Oracle configuration tools.
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = ljb)
(ORACLE_HOME = E:\oracle\product\10.2.0\db_1)
)
(SID_DESC =
(SID_NAME = iso8859)
(ORACLE_HOME = E:\oracle\product\10.2.0\db_1)
)
(SID_DESC =
(SID_NAME = orcl)
(ORACLE_HOME = E:\oracle\product\10.2.0\db_1)
)
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = E:\oracle\product\10.2.0\db_1)
(ENVS = "EXTPROC_DLLS=ANY,ODC_SECURE_SERVICE_API_CONFIG_FILE=C:\DBCoffer\DBCSecureServiceAPI\secureServiceAPI.conf,NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1")
(PROGRAM = extproc)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = extproc))
(ADDRESS = (PROTOCOL = TCP)(HOST = Jiabo)(PORT = 1521))
)
)
表2
其中请一定注意红色部分的内容,如果用Net Manager修改相关配置后,也请以此文件为参考,否则有可能我们的DBCoffer可能不能正常工作,而在tnames.ora的配置就相对较简单,添加如下内容即可: