oracle字符集的更改【轉】
oracle字符集的更改
關鍵字: jinguo2. 字符集的更改
資料庫建立以後,如果需要修改字符集,通常需要重建資料庫,通過匯入匯出的方式來轉換。
我們也可以通過以下方式更改
ALTER DATABASE CHARACTER SET
|
注意:修改資料庫字符集時必須謹慎,修改之前一定要為資料庫備份。由於不能回退這項操作,因此可能會造成資料丟失或者損壞。
這是最簡單的轉換字符集的方式,但並不總是有效。
這個命令在Oracle8時被引入Oracle,這個操作在本質上並不轉換任何資料庫字元,只是簡單的更新資料庫中所有跟字符集相關的資訊。
這意味著,你只能在新字符集是舊字符集嚴格超集的情況下使用這種方式轉換。
所謂超集是指:
當前字符集中的每一個字元在新字符集中都可以表示,並使用同樣的程式碼點
比如很多字符集都是US7ASCII的嚴格超集。
如果不是超集,將獲得以下錯誤:
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 AMERICAN NLS_TERRITORY AMERICA NLS_CURRENCY $ NLS_ISO_CURRENCY AMERICA NLS_NUMERIC_CHARACTERS ., NLS_CHARACTERSET US7ASCII NLS_CALENDAR GREGORIAN NLS_DATE_FORMAT DD-MON-RR NLS_DATE_LANGUAGE AMERICAN ………………. NLS_NCHAR_CHARACTERSET AL16UTF16 NLS_RDBMS_VERSION 9.2.0.4.0 20 rows selected. SQL> select name,dump(name) from eygle.test; NAME DUMP(NAME) ------------------------------------------------------ 測試 Typ=1 Len=4: 178,226,202,212 Test Typ=1 Len=4: 116,101,115,116 2 rows selected. |
轉換字符集,資料庫應該在RESTRICTED模式下進行.
c:\>sqlplus "/ as sysdba" SQL*Plus: Release 9.2.0.4.0 - Production on Sat Nov 1 10:52:30 2003 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. Connected to: Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options JServer Release 9.2.0.4.0 - Production SQL> shutdown immediate Database closed. Database dismounted. ORACLE instance shut down. SQL> STARTUP MOUNT; ORACLE instance started. Total System Global Area 76619308 bytes Fixed Size 454188 bytes Variable Size 58720256 bytes Database Buffers 16777216 bytes Redo Buffers 667648 bytes Database 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 120 SQL> ALTER DATABASE CHARACTER SET ZHS16GBK; ALTER DATABASE CHARACTER SET ZHS16GBK * ERROR at line 1: ORA-12721: operation cannot execute when other sessions are active 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 在Oracle9i中,如果資料庫存在CLOB型別欄位,那麼就不允許對字符集進行轉換 SQL> |
這時候,我們可以去檢視alert
ALTER DATABASE CHARACTER SET ZHS16GBK
SYS.METASTYLESHEET (STYLESHEET) - CLOB populated
ORA-12716 signalled during: ALTER DATABASE CHARACTER SET ZHS16GBK... |
對於不同情況,Oracle提供不同的解決方案,如果是使用者資料表,一般我們可以把包含CLOB欄位的表匯出,然後drop掉相關物件,
轉換後再匯入資料庫;對於系統表,可以按照以下方式處理:
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. |
在9.2.0中,轉換完成以後,可以通過執行catmet.sql指令碼來重建Metastylesheet表:
SQL> @?/rdbms/admin/catmet.sql |
轉換後的資料:
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_NCHAR_CHARACTERSET AL16UTF16 NLS_RDBMS_VERSION 9.2.0.4.0 20 rows selected. SQL> select * from eygle.test; NAME ------------------------------ 測試 test 2 rows selected. |
提示:
通過設定sql_trace,我們可以跟蹤很多資料庫的後臺操作,這個工具是DBA常用的“利器”之一。
我們簡單看一下資料庫更改字符集時的後臺處理,我提取了主要的更新部分。
通過以下跟蹤過程,我們看到資料庫在更改字符集的時候,主要更新了12張資料字典表,修改了資料庫的原資料,這也證實了我們以前的說法:
這個更改字符集的操作在本質上並不轉換任何資料庫字元,只是簡單的更新資料庫中所有跟字符集相關的資訊。
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'
|
在這裡我們順便糾正一個由來以及的錯誤方法.
經常可以在網上看到這樣的更改字符集的方法:
1)用SYS使用者名稱登陸ORACLE。
2)檢視字符集內容 SQL>SELECT * FROM PROPS$; 3)修改字符集 SQL> update props$ set value$='新字符集' where name='NLS_CHARACTERSET' 4) COMMIT;
|
我們看到很多人在這個問題上遇到了慘痛的教訓,使用這種方式更改字符集,如果你的value$值輸入了不正確的字符集,在8i中那麼你
的資料庫可能會無法啟動,這種情況是非常嚴重的,有時候你必須從備份中進行恢復;如果是在9i中,可以重新啟動資料庫後再修改回正
確的字符集。但是我們仍然不建議使用這種方式進行任何資料庫修改,這是一種極其危險的操作。
實際上當我們更新了字符集,資料庫啟動時會根據資料庫的字符集自動的來修改控制檔案的字符集,如果字符集可以識別,更新控制文
件字符集等於資料庫字符集;如果字符集不可識別,那麼控制檔案字符集更新為US7ASCII.
通過更新props$表的方式修改字符集,在Oracle7之後就不應該被使用.
以下是我的測試結果,但是嚴禁一切不備份的修改研究,即使是對測試庫的。
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 AMERICAN NLS_TERRITORY AMERICA NLS_CURRENCY $ NLS_ISO_CURRENCY AMERICA NLS_NUMERIC_CHARACTERS ., NLS_CHARACTERSET EYGLE NLS_CALENDAR GREGORIAN NLS_DATE_FORMAT DD-MON-RR NLS_DATE_LANGUAGE AMERICAN …. NLS_NCHAR_CHARACTERSET ZHS16GBK NLS_RDBMS_VERSION 8.1.7.1.1 18 rows selected. 重新啟動資料庫,發現alert.log檔案中記錄如下操作: Mon Nov 03 16:11:35 2003 Updating character set in controlfile to US7ASCII Completed: 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 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_COMP BINARY NLS_NCHAR_CHARACTERSET ZHS16GBK NLS_RDBMS_VERSION 8.1.7.1.1 18 rows selected. 重新啟動資料庫後,發現控制檔案的字符集被更新: Mon Nov 03 16:21:41 2003 Updating character set in controlfile to ZHS16GBK Completed: ALTER DATABASE OPEN oracle9205, 在做字符集轉換的時候,發現只有兩個clob的型別的欄位: User : SYS Table : METASTYLESHEET User : SYS Table : EXTERNAL_TAB$ 在轉換之前,要把兩個表truncate 掉,然後在轉換, 轉換完成後,重新使用rdms/下的sql重建這兩個表, 我看過資料, sys.metastylesheet,可以使用catmet.sql重新建立, 那麼sys.EXTERNAL_TAB$用那個指令碼建立呢? 我在轉換前,用create table aaa as select * from sys.external_tab$,做個backup,我在轉換前,用create table aaa as select * from sys.external_tab$,做個backup,然後truncate這個sys.external_tab$.,轉換完成後再把資料弄回去,這樣就可以了。 然後truncate這個sys.external_tab$.,轉換完成後再把資料弄回去,這樣就可以了。 |
理解了字符集調整的內部操作以後,我們可以輕易的指出,以上的方法是不正確的,通過前面 ” ALTER DATABASE CHARACTER SET” 方式更改字
符集時,Oracle至少需要更改12張資料字典表,而這種直接更新props$表的方式只完成了其中十二分之一的工作,潛在的完整性隱患是可想而知的。
所以,更改字符集儘量要使用正常的途徑。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/241379/viewspace-694442/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle更改字符集Oracle
- oracle資料庫的字符集更改Oracle資料庫
- oracle 字符集 (轉)Oracle
- oracle11g更改資料庫字符集Oracle資料庫
- oracle9i 更改字符集步驟方法Oracle
- ORACLE11G 字符集更改(這裡更改為AL32UTF8)Oracle
- 理解ORACLE 字符集【轉】Oracle
- 轉_oracle的字符集_源於多位元組字符集Oracle
- 更改Oracle字符集:把字符集ZHS16GBK換成UTF8Oracle
- 【字符集】論Oracle字符集“轉碼”過程Oracle
- 遷移資料時oracle字符集的轉換遷移資料時oracle字符集的轉換Oracle
- (轉)Oracle 字符集的檢視和修改Oracle
- Oracle 字符集的檢視和修改(轉)Oracle
- oracle資料庫字符集的轉換Oracle資料庫
- oracle字符集轉換分析工具Oracle
- 【轉】修改Oracle字符集(character set)Oracle
- 字符集問題的初步探討(七)-字符集更改的內部操作
- 更改oracle使用者資訊(轉)Oracle
- [MySQLFAQ]系列–如何更改MySQL的預設字符集MySql
- 生產oracle字符集轉碼問題Oracle
- ORACLE字符集問題總結 (轉載)Oracle
- 巧妙轉換ORACLE資料庫字符集Oracle資料庫
- Oracle字符集問題總結(轉貼)Oracle
- Internal/Oracle的密碼更改用什麼命令(轉)Oracle密碼
- ORACLE學習之九 Oracle 字符集的檢視和修改 (轉帖)Oracle
- Oracle字符集Oracle
- Oracle 字符集Oracle
- Oracle資料庫字符集問題解析(轉)Oracle資料庫
- Oracle字符集的檢視查詢和Oracle字符集的設定修改Oracle
- 修改oracle9i資料庫字符集的方法(轉)Oracle資料庫
- 修改oracle client 的字符集Oracleclient
- linux 字符集和oracle 字符集LinuxOracle
- Oracle字符集和國家字符集Oracle
- (轉載)Oracle資料庫字符集問題解析Oracle資料庫
- Oracle 字符集修改Oracle
- 修改oracle字符集Oracle
- oracle修改字符集Oracle
- oracle字符集修改Oracle