字符集问题的初步探讨(三)

王朝mssql·作者佚名  2006-12-17
窄屏简体版  字體:   |    |    |  超大  

字符集问题的初步探讨(三)

字符集问题的初步探讨(三) link:

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

2. 字符集的更改

ALTER DATABASE CHARACTER SET

注意:修改数据库字符集时必须谨慎,修改之前一定要为数据库备份。由于不能回退这项操作,因此可能会造成数据丢失或者损坏。

这是最简单的转换字符集的方式,但并不总是有效。

这个命令在Oracle8时被引入Oracle,这个操作在本质上并不转换任何数据库字符,只是简单的更新数据库中所有跟字符集相关的信息。

SQL> ALTER DATABASE CHARACTER SET ZHS16CGB231280;

ALTER DATABASE CHARACTER SET ZHS16CGB231280

*

ERROR at line 1:

ORA-12712: new character set must be a superset of old character set

下面我们来看一个测试(以下测试在Oracle9.2.0下进行,Oracle9i较Oracle8i在编码方面有较大改变,在Oracle8i中,测试结果可能略有不同):

SQL> select name,value$ from props$ where name like '%NLS%';NAME VALUE$------------------------------ ------------------------------NLS_LANGUAGE AMERICANNLS_TERRITORY AMERICANLS_CURRENCY $NLS_ISO_CURRENCY AMERICANLS_NUMERIC_CHARACTERS .,NLS_CHARACTERSET US7ASCIINLS_CALENDAR GREGORIANNLS_DATE_FORMAT DD-MON-RRNLS_DATE_LANGUAGE AMERICAN……………….NLS_NCHAR_CHARACTERSET AL16UTF16NLS_RDBMS_VERSION 9.2.0.4.020 rows selected.SQL> select name,dump(name) from eygle.test;NAME DUMP(NAME)------------------------------------------------------测试 Typ=1 Len=4: 178,226,202,212Test Typ=1 Len=4: 116,101,115,1162 rows selected.

转换字符集,数据库应该在RESTRICTED模式下进行.

c:\>sqlplus "/ as sysdba"SQL*Plus: Release 9.2.0.4.0 - Production on Sat Nov 1 10:52:30 2003Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.Connected to:Oracle9i Enterprise Edition Release 9.2.0.4.0 - ProductionWith the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining optionsJServer Release 9.2.0.4.0 - ProductionSQL> shutdown immediateDatabase closed.Database dismounted.ORACLE instance shut down.SQL> STARTUP MOUNT;ORACLE instance started.Total System Global Area 76619308 bytesFixed Size 454188 bytesVariable Size 58720256 bytesDatabase Buffers 16777216 bytesRedo Buffers 667648 bytesDatabase mounted.SQL> ALTER SESSION SET SQL_TRACE=TRUE;Session altered.SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;System altered.SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;System altered.SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;System altered.SQL> ALTER DATABASE OPEN;Database altered.SQL> set linesize 120SQL> ALTER DATABASE CHARACTER SET ZHS16GBK;ALTER DATABASE CHARACTER SET ZHS16GBK*ERROR at line 1:ORA-12721: operation cannot execute when other sessions are activeSQL> ALTER DATABASE CHARACTER SET ZHS16GBK;ALTER DATABASE CHARACTER SET ZHS16GBK*ERROR at line 1:ORA-12716: Cannot ALTER DATABASE CHARACTER SET when CLOB data exists在Oracle9i中,如果数据库存在CLOB类型字段,那么就不允许对字符集进行转换SQL>

ALTER DATABASE CHARACTER SET ZHS16GBK

SYS.METASTYLESHEET (STYLESHEET) - CLOB populated

ORA-12716 signalled during: ALTER DATABASE CHARACTER SET ZHS16GBK...

SQL> truncate table Metastylesheet;

Table truncated.

SQL> ALTER SESSION SET SQL_TRACE=TRUE;Session altered.SQL> ALTER DATABASE CHARACTER SET ZHS16GBK;Database altered.SQL> ALTER SESSION SET SQL_TRACE=FALSE;Session altered.

SQL> @?/rdbms/admin/catmet.sql

SQL> select name,value$ from props$ where name like '%NLS%';NAME VALUE$------------------------------ ------------------------------NLS_LANGUAGE AMERICANNLS_TERRITORY AMERICANLS_CURRENCY $NLS_ISO_CURRENCY AMERICANLS_NUMERIC_CHARACTERS .,NLS_CHARACTERSET ZHS16GBK…..NLS_NCHAR_CHARACTERSET AL16UTF16NLS_RDBMS_VERSION 9.2.0.4.020 rows selected.SQL> select * from eygle.test;NAME------------------------------测试test2 rows selected.

这个更改字符集的操作在本质上并不转换任何数据库字符,只是简单的更新数据库中所有跟字符集相关的信息。

update props$ set value$ = :1 where name = :2update "SYS"."KOTAD$" set SYS_NC_ROWINFO$ = :1 where SYS_NC_OID$ = :2update seq$ set increment$=:2,minvalue=:3,maxvalue=:4,cycle#=:5,order$=:6, cache=:7,highwater=:8,audit$=:9,flags=:10 where obj#=:1update kopm$ set metadata = :1, length = :2 where name='DB_FDO'

1)用SYS用户名登陆ORACLE。

2)查看字符集内容

SQL>SELECT * FROM PROPS$;

3)修改字符集

SQL> update props$ set value$='新字符集' where name='NLS_CHARACTERSET'

4) COMMIT;

SQL> update props$ set value$='EYGLE' where name='NLS_CHARACTERSET';1 row updated.SQL> commit;Commit complete.SQL> select name,value$ from props$ where name like '%NLS%';NAME VALUE$------------------------------ -----------------------------------NLS_LANGUAGE AMERICANNLS_TERRITORY AMERICANLS_CURRENCY $NLS_ISO_CURRENCY AMERICANLS_NUMERIC_CHARACTERS .,NLS_CHARACTERSET EYGLENLS_CALENDAR GREGORIANNLS_DATE_FORMAT DD-MON-RRNLS_DATE_LANGUAGE AMERICAN….NLS_NCHAR_CHARACTERSET ZHS16GBKNLS_RDBMS_VERSION 8.1.7.1.118 rows selected.重新启动数据库,发现alert.log文件中记录如下操作:Mon Nov 03 16:11:35 2003Updating character set in controlfile to US7ASCIICompleted: ALTER DATABASE OPEN启动数据库后恢复字符集设置:SQL> update props$ set value$='ZHS16GBK' where name='NLS_CHARACTERSET';1 row updated.SQL> commit;Commit complete.SQL> select name,value$ from props$ where name like '%NLS%';NAME VALUE$------------------------------ -----------------------------------NLS_LANGUAGE AMERICANNLS_TERRITORY AMERICANLS_CURRENCY $NLS_ISO_CURRENCY AMERICANLS_NUMERIC_CHARACTERS .,NLS_CHARACTERSET ZHS16GBKNLS_CALENDAR GREGORIANNLS_DATE_FORMAT DD-MON-RRNLS_DATE_LANGUAGE AMERICAN………NLS_COMP BINARYNLS_NCHAR_CHARACTERSET ZHS16GBKNLS_RDBMS_VERSION 8.1.7.1.118 rows selected.重新启动数据库后,发现控制文件的字符集被更新:Mon Nov 03 16:21:41 2003Updating character set in controlfile to ZHS16GBKCompleted: ALTER DATABASE OPEN

符集时,Oracle至少需要更改12张数据字典表,而这种直接更新props$表的方式只完成了其中十二分之一的工作,潜在的完整性隐患是可想而知的。

所以,更改字符集尽量要使用正常的途径。

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航