注意: 1.修改數(shù)據(jù)庫字符集時(shí)必須謹(jǐn)慎,修改之前一定要做數(shù)據(jù)庫全量備份。(由于不能回退該項(xiàng)操作,因此可能會(huì)造成數(shù)據(jù)丟失或者損壞。) 2.使用 "alter database character set ZHS16GBK;" 方式更改字符集時(shí)候,至少需要更改12張數(shù)據(jù)字典表; 3.使用"update props$ set value$='ZHS16GBK' where name='NLS_CHARACTERSET';" 方式更改字符集時(shí)候,只是修改了 props$ 表,只完成了十幾的十二分之一的內(nèi)容,存在數(shù)據(jù)完整性的隱患。因此,更改字符集盡量使用正常的途徑。 4.設(shè)置 sql_trace 跟著后臺(tái)操作:在 mount 模式(SQL> STARTUP MOUNT;)下面,把會(huì)話修改為trace模式(SQL> ALTER SESSION SET SQL_TRACE=TRUE;),可以跟著數(shù)據(jù)庫的后臺(tái)操作。(sql_trace是DBA的常用利器之一) 5.實(shí)際上當(dāng)我們更新了字符集,數(shù)據(jù)庫啟動(dòng)時(shí)會(huì)根據(jù)數(shù)據(jù)庫的字符集自動(dòng)的來修改控制文件的字符集,如果字符集可以識(shí)別,更新控制文件字符集等于數(shù)據(jù)庫字符集;如果字符集不可識(shí)別,那么控制文件字符集更新為US7ASCII。通過更新props$表的方式修改字符集,在Oracle7之后就不應(yīng)該被使用.
本節(jié)重點(diǎn)解釋方法二: 通過 "alter database character set ZHS16GBK;" 方式修改,但并不總是有效。該命令在Oracle8時(shí)被引入Oracle,這個(gè)操作在本質(zhì)上并不轉(zhuǎn)換任何數(shù)據(jù)庫字符,只是簡單的更新數(shù)據(jù)庫中所有跟字符集相關(guān)的信息。 查詢字符集信息: "SQL> select name,value$ from props$ where name like '%NLS%';",結(jié)果有二十行。 修改步驟: 注意:轉(zhuǎn)換字符集,數(shù)據(jù)庫應(yīng)該在RESTRICTED模式下進(jìn)行. (使用DBA登錄數(shù)據(jù)庫) SQL> SHUTDOWN IMMEDIATE; SQL> STARTUP MOUNT; SQL> ALTER SESSION SET SQL_TRACE=TRUE; SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION; SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0; SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0; SQL> ALTER DATABASE OPEN; SQL> set linesize 120; SQL> ALTER DATABASE CHARACTER SET ZHS16GBK;
常見問題: 問題1: 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 原因: 字符集超集問題,所謂超集是指:當(dāng)前字符集中的每一個(gè)字符在新字符集中都可以表示,并使用同樣的代碼點(diǎn),比如很多字符集都是US7ASCII的嚴(yán)格超集。如果不是超集,將獲得以上錯(cuò)誤。 解決方式: SQL> alter database character set internal_use ZHS16GBK; SQL> select * from v$nls_parameters; SQL> SHUTDOWN IMMEDIATE; SQL> STARTUP; 備注: ALTER DATABASE CHARACTER SET操作的內(nèi)部過程是完全相同的,也就是說INTERNAL_USE提供的幫助就是使Oracle數(shù)據(jù)庫繞過了子集與超集的校驗(yàn)。該方法某些方面有用處,比如測試環(huán)境;應(yīng)用于產(chǎn)品環(huán)境大家應(yīng)該格外小心,除了你以外,沒有人會(huì)為此帶來的后果負(fù)責(zé)。
問題2: ALTER DATABASE CHARACTER SET ZHS16GBK * ERROR at line 1: ORA-12721: operation cannot execute when other sessions are active 原因: 字符集超集問題。 解決方式: SQL> alter database character set internal_use ZHS16GBK; SQL> select * from v$nls_parameters; SQL> SHUTDOWN IMMEDIATE; SQL> STARTUP;
問題3: SQL> 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 原因: 數(shù)據(jù)庫存在CLOB類型字段,那么就不允許對字符集進(jìn)行轉(zhuǎn)換 解決方式: 這時(shí)候,我們可以去查看alert<sid>.log日志文件,看CLOB字段存在于哪些表上: 內(nèi)容如: ALTER DATABASE CHARACTER SET ZHS16GBK SYS.METASTYLESHEET (STYLESHEET) - CLOB populated ORA-12716 signalled during: ALTER DATABASE CHARACTER SET ZHS16GBK... 對于用戶表,可以先將該表導(dǎo)出,然后把該表刪掉,等字符轉(zhuǎn)換完畢后在導(dǎo)入。
例子1: SQL> select name,value$ from props$ where name like '%NLS%'; NAME VALUE$ ------------------------------ -------------------------------------------------------------------------------- NLS_LANGUAGE AMERICAN NLS_TERRITORY AMERICA NLS_CURRENCY $ NLS_ISO_CURRENCY AMERICA NLS_NUMERIC_CHARACTERS ., NLS_CHARACTERSET ZHS16GBK NLS_CALENDAR GREGORIAN NLS_DATE_FORMAT DD-MON-RR NLS_DATE_LANGUAGE AMERICAN NLS_SORT BINARY NLS_TIME_FORMAT HH.MI.SSXFF AM NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR NLS_DUAL_CURRENCY $ NLS_COMP BINARY NLS_LENGTH_SEMANTICS BYTE NLS_NCHAR_CONV_EXCP FALSE NLS_NCHAR_CHARACTERSET AL16UTF16 NLS_RDBMS_VERSION 11.1.0.6.0 20 rows selected SQL>
例子2: 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.