- 循序渐进Oracle:数据库管理、优化与备份恢复
- 盖国强
- 1100字
- 2020-06-26 12:09:27
3.3 字符集文件及字符支持
Oracle的全球支持是通过Oracle NLS Runtime Library(NLSRTL)来实施的,NLS运行库通过独立的函数来完成运行时和语言相关的转换及控制。字符集相关的文件在数据库服务器上是单独存储的,这些文件的位置受环境变量参数 ORA_NLS*参数的控制,在不同版本中,这个环境变量的参数并不相同,在Oracle 7.2中,这个环境变量是ORA_NLS;在Oracle 7.3中,这个环境变量值变更为ORA_NLS32;在Oracle8/Oracle8i/Oracle 9i的各个版本中,该环境变量为ORA_NLS33;在Oracle 10g中,该环境变量参数又变更为ORA_NLS10。通常缺省地,可以不设置这个变量。
在Oracle 9i中,这个参数指向的字符文件缺省位置为$ORACLE_HOME/ocommon/nls/ admin/data。在Oracle 10g/11g中,这个参数指向的字符文件缺省位置为$ORACLE_HOME/ nls/data。
该目录下存放3类文件分别用来定义语言(NLS_LANGUAGE)、区域(NLS_TERRITORY)和字符集(NLS_CHARACTERSET),其中中文语言的文件为lx00023.nlb,如图3-2所示。
用Oracle提供的Locale Builder工具打开该文件,就可以看到在中文语言环境下的相关设置,如月份、星期等,如图3-3所示。
当然最终要得文件是字符集文件,用 Locale Builder 工具打开相关的字符集文件(ZHS16GBK字符集文件为lx20354.nlb),如图3-4所示,就可以看到和字符集相关的设置信息。
图3-2 选择语言文件
图 3-3 月份和星期格式
通过字符集文件,Oracle 将所有汉字编码存放在数据库之中,这样当存放和转换汉字时才有了依据,我们看一下字符编码,如图3-5所示。
图3-4 打开字符集文件
图3-5 字符编码
在上图中可以看到,汉字“盖”的编码为0xb8c7,这也就是Oracle在数据库中存放汉字时的编码,有了这个编码方案,Oracle才能知道在一个字符集中,字符0xb8c7真正代表什么:
SQL> select dump('盖') from dual;
DUMP('盖')
---------------------
Typ=96 Len=2: 184,199
SQL> select concat(to_char(184,'xx'),to_char(199,'xx')) from dual;
CONCAT
------
b8 c7
这个过程完全可逆,在同样字符集的数据库中,可以进行如下转换:
SQL> select to_number('b8c7','xxxxxx') from dual;
TO_NUMBER('B8C7','XXXXXX')
--------------------------
47303
SQL> select chr(47303) from dual;
CH
--
盖
通过以上介绍可以知道这些字符文件非常重要,如果这个字符文件丢失或损坏,则数据库将会出现故障。在Windows系统上做一个简单的测试:
C:\oracle\10.2.0\nls\data>dir lx20354.nlb
2006-10-10 14:52 477,772 lx20354.nlb
C:\oracle\10.2.0\nls\data>move lx20354.nlb lx20354.nlb.b
C:\oracle\10.2.0\nls\data>net start oracleserviceeygle
OracleServiceEYGLE 服务正在启动 ...
OracleServiceEYGLE 服务已经启动成功。
C:\oracle\10.2.0\nls\data>sqlplus "/ as sysdba"
Error 5 initializing SQL*Plus
NLS initialization error
以上测试显示,当字符集文件被移除之后,由于不能正常读取字符集文件,SQL*Plus已经不能正常登录,此时可以修改NLS_LANG参数设置其他字符集,使得SQL*Plus可以完成初始化:
C:\oracle\10.2.0\nls\data>set nls_lang=AMERICAN_AMERICA.US7ASCII
C:\oracle\10.2.0\nls\data>sqlplus "/ as sysdba"
SQL*Plus: Release 10.2.0.3.0 - Production on Mon Jun 18 17:10:46 2007
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
ERROR:
ORA-03113: end-of-file on communication channel
此时SQL*Plus可以执行,但是无法登录数据库,这是因为SQL*Plus执行时就需要调用字符集文件,在Linux系统下,可以通过系统命令strace跟踪到这些调用行为。
以下命令通过strace命令将SQL*Plus的调用过程跟踪写入sqlplus.log文件:
[oracle@wapdb ~]$ strace -o sqlplus.log sqlplus /nolog
SQL*Plus: Release 11.1.0.6.0 - Production on Mon Sep 27 10:23:52 2010
Copyright (c) 1982, 2007, Oracle. All rights reserved.
SQL> exit
过滤一下跟踪文件,可以得到SQL*Plus启动依次调用的字符文件:
[oracle@wapdb ~]$ grep nls sqlplus.log
open("/opt/oracle/product/11.1.0/nls/data/lx1boot.nlb", O_RDONLY) = 3
open("/opt/oracle/product/11.1.0/nls/data/lx00001.nlb", O_RDONLY) = 3
open("/opt/oracle/product/11.1.0/nls/data/lx20354.nlb", O_RDONLY) = 3
open("/opt/oracle/product/11.1.0/nls/data/lx10035.nlb", O_RDONLY) = 3
open("/opt/oracle/product/11.1.0/nls/data/lx20001.nlb", O_RDONLY) = 3
open("/opt/oracle/product/11.1.0/nls/data/lx40001.nlb", O_RDONLY) = 3
open("/opt/oracle/product/11.1.0/nls/data/lx10001.nlb", O_RDONLY) = 8
注意以上调用中lx1boot.nlb是字符集的初始化文件,而lx20354.nlb正是SQL*Plus软件启动时需要调用的ZHS16GBK字符集文件。如果没有了字符集文件,应用软件(包括SQL*Plus和Oracle执行软件)都是无法完成初始化的。