数据库

本类阅读TOP10

·SQL语句导入导出大全
·SQL Server日期计算
·SQL语句导入导出大全
·SQL to Excel 的应用
·Oracle中password file的作用及说明
·MS SQLServer OLEDB分布式事务无法启动的一般解决方案
·sqlserver2000数据库置疑的解决方法
·一个比较实用的大数据量分页存储过程
·如何在正运行 SQL Server 7.0 的服务器之间传输登录和密码
·SQL中两台服务器间使用连接服务器

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
字符集问题的初步探讨(七)----关于字符集更改的内部操作

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

原文链接:

http://www.eygle.com/special/NLS_CHARACTER_SET_07.htm

前面我们提到,通过修改props$的方式更改字符集在Oracle7之后是一种极其危险的方式,应该尽量避免。

我们又知道,通过ALTER DATABASE CHARACTER SET更改字符集虽然安全可靠,但是有严格的子集和超集的约束,实际上我们很少能够
用到这种方法。


实际上Oracle还存在另外一种更改字符集的方式.

如果你注意过的话,在Oracle的alert<sid>.log文件中,你可能看到过这样的日志信息:


alter database character set INTERNAL_CONVERT ZHS16GBK
Updating character set in controlfile to ZHS16GBK
 SYS.SNAP$ (REL_QUERY) - CLOB representation altered
 SYS.METASTYLESHEET (STYLESHEET) - CLOB representation altered
 SYS.EXTERNAL_TAB$ (PARAM_CLOB) - CLOB representation altered
 XDB.XDB$RESOURCE (SYS_NC00027$) - CLOB representation altered
 ODM.ODM_PMML_DTD (DTD) - CLOB representation altered
 OE.WAREHOUSES (SYS_NC00003$) - CLOB representation altered
 PM.ONLINE_MEDIA (SYS_NC00042$) - CLOB representation altered
 PM.ONLINE_MEDIA (SYS_NC00062$) - CLOB representation altered
 PM.ONLINE_MEDIA (PRODUCT_TEXT) - CLOB representation altered
 PM.ONLINE_MEDIA (SYS_NC00080$) - CLOB representation altered
 PM.PRINT_MEDIA (AD_SOURCETEXT) - CLOB representation altered
 PM.PRINT_MEDIA (AD_FINALTEXT) - CLOB representation altered
Completed: alter database character set INTERNAL_CONVERT ZHS1


在这里面,我们看到这样一条重要的,Oracle非公开的命令:


alter database character set INTERNAL_CONVERT/ INTERNAL_USE ZHS16GBK
                      

 

这个命令是当你选择了使用典型方式创建了种子数据库以后,Oracle会根据你选择的字符集设置,把当前种子数据库的字符集更改为期望字符
集,这就是这条命令的作用.

在使用这个命令时,Oracle会跳过所有子集及超集的检查,在任意字符集之间进行强制转换,所以,使用这个命令时你必须十分小心,你必须
清楚这一操作会带来的风险.
我们之前讲过的内容仍然有效,你可以使用csscan扫描整个数据库,如果在转换的字符集之间确认没有严重的数据损坏,或者你可以使用有效
的方式更改,你就可以使用这种方式进行转换.
我们来看一下具体的操作过程及Oracle的内部操作:

这是alert.log文件中的记录信息:

Tue Oct 19 16:26:30 2004

Database Characterset is ZHS16GBK

replication_dependency_tracking turned off
(no async multimaster replication found)

Completed: ALTER DATABASE OPEN

Tue Oct 19 16
:27:07 2004

alter database character set INTERNAL_USE ZHS16CGB231280

Updating character set in controlfile to ZHS16CGB231280

Tue Oct 19 16
:27:15 2004

Thread 1 advanced to log sequence 118

  Current log
# 2 seq# 118 mem# 0: /opt/oracle/oradata/primary/redo02.log

Tue Oct 19 16:27:15 2004

ARC0
: Evaluating archive   log 3 thread 1 sequence 117

ARC0
: Beginning to archive log 3 thread 1 sequence 117

Creating archive destination LOG_ARCHIVE_DEST_1
: '/opt/oracle/oradata/primary/archive/1_117.dbf'

ARC0: Completed archiving  log 3 thread 1 sequence 117

Tue Oct 19 16
:27:20 2004

Completed
: alter database character set INTERNAL_USE ZHS16CGB231280

Shutting down instance
: further logons disabled

Shutting down instance
(immediate)

License high water mark = 1

Tue Oct 19 16
:29:06 2004

ALTER DATABASE CLOSE NORMAL

...

...

格式化10046跟踪文件,得到以下信息(摘要):

alter session set events '10046 trace name context forever,level 12'


alter database character set INTERNAL_USE ZHS16CGB231280


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      4.88       6.04        910      16825      18099           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      4.88       6.04        910      16825      18099           0

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: SYS

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  control file sequential read                    4        0.00          0.00
  control file parallel write                     2        0.05          0.08
  log file sync                                   2        0.08          0.08
  SQL*Net message to client                       1        0.00          0.00
  SQL*Net message from client                     1       18.06         18.06
********************************************************************************

....

update col$ set charsetid = :1 
where
 charsetform = :2

....

update argument$ set charsetid = :1 
where
 charsetform = :2

....

update collection$ set charsetid = :1 
where
 charsetform = :2

....

update attribute$ set charsetid = :1 
where
 charsetform = :2
....

update parameter$ set charsetid = :1 
where
 charsetform = :2
....

update result$ set charsetid = :1 
where
 charsetform = :2

....

update partcol$ set spare1 = :1 
where
 charsetform = :2

....

update subpartcol$ set spare1 = :1 
where
 charsetform = :2

....

update props$ set value$ = :1 
where
 name = :2

....

update "SYS"."KOTAD$" set SYS_NC_ROWINFO$ = :1 
where
 SYS_NC_OID$ = :2
....

update seq$ set increment$=:2,minvalue=:3,maxvalue=:4,cycle#=:5,order$=:6,
  cache=:7,highwater=:8,audit$=:9,flags=:10 
where
 obj#=:1

....

update kopm$ set metadata = :1,  length 
  = :2 
where
 name='DB_FDO'

....

ALTER DATABASE CLOSE NORMAL
                      

此处生成的日志你可以在这里下载(供参考):

http://www.eygle.com/special/primary_ora_13730.zip
http://www.eygle.com/special/primary_ora_13730.tkf.log

我们看到这个过程和之前ALTER DATABASE CHARACTER SET操作的内部过程是完全相同的,也就是说INTERNAL_USE提供的帮助就是使
Oracle数据库绕过了子集与超集的校验.
这一方法在某些方面是有用处的,比如测试;应用于产品环境大家应该格外小心,除了你以外,没有人会为此带来的后果负责:

结语(我们不妨再说一次):

对于DBA来说,有一个很重要的原则就是:不要把你的数据库置于危险的境地!

这就要求我们,在进行任何可能对数据库结构发生改变的操作之前,先做有效的备份,很多DBA没有备份的操作中得到了惨痛的教训。

 

 

本文作者:
eygle,Oracle技术关注者,来自中国最大的Oracle技术论坛itpub.
www.eygle.com是作者的个人站点.你可通过[email protected]来联系作者.欢迎技术探讨交流以及链接交换.


原文出处:

http://www.eygle.com/special/NLS_CHARACTER_SET_07.htm






相关文章

相关软件