如何在10g中修改資料庫字符集

space6212發表於2019-06-24
一般來說,資料庫在建立完成後就不能修改字符集了,如要修改字符集,需要對原有資料進行匯入匯出後重建資料庫來修改。但是也有一些例外的,如果從子集升級到超集,則可以直接修改而無需重建資料庫。

[php]

子集到超集,在8I/9I中,簡單的修改步驟如下:
SHUTDOWN IMMEDIATE;
-- make sure there is a database backup you can rely on, or create one
STARTUP MOUNT;
ALTER SYSTEM ENABLE RESTRICTED SESSION;
ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
ALTER SYSTEM SET AQ_TM_PROCESSES=0;
ALTER DATABASE OPEN;
ALTER DATABASE CHARACTER SET ;
-- a alter database takes typically only a few minutes or less,
-- it depends on the number of columns in the database, not the
-- amount of data.
SHUTDOWN;
-- If you use Oracle8 then also do:
STARTUP RESTRICT;
SHUTDOWN;

但是,以上步驟只適用於8I/9I,對於10g,oracle明確指出不能這樣幹了,在10g,oracle提供了一個新工具CSALER來修改字符集。

下面說明如何在10g用修改字符集。

1、當前字符集> select userenv('language') from dual;

USERENV('LANGUAGE')
------------------------------------------------------
SIMPLIFIED CHINESE_CHINA.ZHS16CGB231280

2、插入一些生僻字

> create table a(a varchar2(100));

表已建立。

> insert into a values('珮');

已建立 1 行。

> commit;

提交完成。

> select *from a;

A
--------------------

可見,ZHS16CGB231280包含的漢字太少,需要升級包含漢字更多的ZHS16GBK。ZHS16GBK是ZHS16CGB231280的超集,可以直接修改字符集。

3、關閉資料庫並備份
由於更新資料庫操作不可回滾,安全起見,最好對資料庫做一個全備。

4、使用csscan檢查字符集轉換是否可行
csscan掃描資料庫的所有資料並測試字符集轉換是否可行。
csscan有四種掃描模式:全庫掃描、按使用者掃描、按表掃描、按列掃描。
因為我們這裡是測試改變全庫的字符集,所以要用全庫掃描模式,並且要求掃描使用者有DBA許可權:



執行csscan需要一系列的許可權和表,因此需要先執行一個指令碼,否則會報錯:
> @E:oracleora10gRDBMSADMINcsminst.sql
......


檢視已建立。


同義詞已刪除。


同義詞已建立。


檢視已建立。


檢視已建立。


提交完成。

從 Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining options 斷開

執行CSSCAN掃描資料庫:

E:oracleora10gBIN>CSSCAN SYSTEM/AAA FULL=y FROMCHAR=ZHS16CGB231280 TOCHAR=ZHS16GBK ARRAY=1024000 PROCESS=1
簡單說一下幾個引數的含義:
username/password :資料庫使用者名稱和口令,需要有dba許可權
FULL :是否進行全庫掃描
FROMCHAR :原字符集,可以省略,預設為連線資料庫的當前字符集
TOCHAR :目標字符集
ARRAY :讀取資料的緩衝區大小
PROCESS :同時啟動幾個程式進行掃描

Character Set Scanner v2.1 : Release 10.2.0.0.0 - Production on 星期四 12月 27 18:49:55 2007

Copyright (c) 1982, 2005, Oracle. All rights reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining options

Enumerating tables to scan...
.......
. process 1 scanning SYS.WRH$_LATCH_MISSES_SUMMARY[AAACUwAADAAAAzRAAA]
. process 1 scanning SYSTEM.LOGMNR_COL$[AAABbGAADAAAAeZAAA]
. process 1 scanning SYSTEM.LOGMNR_ATTRCOL$[AAABa/AADAAAAhpAAA]
......
Creating Database Scan Summary Report...

Creating Individual Exception Report...

Scanner terminated successfully.

預設情況下,csscan掃描結束後,會產生三個檔案:scan.txt、scan.err、scan.out,分別檢視這三個檔案,如果沒有異常,則可以往下執行了。

csscan會把最近一次執行掃描的引數寫入表csm$parameters中,這個表的引數非常重要,它決定著下一步進行字符集轉換需要的引數,如要轉成什麼字符集等。
> select * from csm$parameters;

NAME VALUE
------------------------------ ----------------------------------------
SCANNER_VERSION 5
SCAN_TYPE ALL
SCAN_CHAR YES
TO_CHARSET_NAME ZHS16GBK
FROM_CHARSET_NAME ZHS16CGB231280
SCAN_NCHAR NO
MAX_ARRAY_SIZE 1024000
MAX_ROWS_IN_HEAP 100
NUMBER_OF_PROCESS 1
SUPPRESS_ERROR_LOG_BY -1
INSERT_SUPPRESSED NO
CAPTURE_CONVERTIBLE_DATA NO
SCANNER_SCRIPT NO
SCANNER_PRESERVE NO
MIGRATE_TO_SUPERSET 0
CSLD_ENABLE 0
PREVIOUS_CHARACTER_SET ZHS16CGB231280
PREVIOUS_NCHAR_SET AL16UTF16
TIME_START 2007-12-27 18:50:02
TIME_END 2007-12-27 18:51:35


5、執行CSALTER修改字符集
CSALTER是10g新推出的用於修改oracle字符集的工具,它位於$ORACLE_HOME/RDBMS/ADMIN/中,其實這個工具並不神秘,它只不過是把文章開頭提到的9i中修改字符集的主要步驟寫成指令碼,並新增一些自動檢查功能,簡化操作並儘量避免錯誤產生。
> @E:oracleora10gRDBMSADMINCSALTER.PLB

已建立0行。


函式已建立。


函式已建立。


過程已建立。

This script will update the content of the Oracle Data Dictionary.
Please ensure you have a full backup before initiating this procedure.
Would you like to proceed (Y/N)?y
原值 6: if (UPPER('&conf') <> 'Y') then
新值 6: if (UPPER('y') <> 'Y') then
Checking data validility...
begin converting system objects

PL/SQL 過程已成功完成。

Alter the database character set...
CSALTER operation completed, please restart database

PL/SQL 過程已成功完成。


已刪除0行。


函式已刪除。


函式已刪除。


過程已刪除。

這裡注意到,oracle並沒有要求我們輸入引數來執行要把當前資料庫字符集轉換為什麼字符集,實際上,CSALERT讀取csm$parameters中設定的引數值來進行字符集轉換。
這個操作會很快完成,因為csalter並沒有修改實際資料,只是把資料字典中的後設資料修改一下而已。
從後臺日誌可以看出這個過程執行的操作:
Thu Dec 27 22:25:43 2007
ALTER SYSTEM enable restricted session;
MMNL started with pid=11, OS id=3516
Thu Dec 27 22:25:43 2007
ALTER SYSTEM SET job_queue_processes=0 SCOPE=BOTH;
Thu Dec 27 22:25:43 2007
ALTER SYSTEM SET aq_tm_processes=0 SCOPE=BOTH;
Thu Dec 27 22:25:43 2007
alter database character set internal_use ZHS16GBK
Thu Dec 27 22:25:46 2007
Updating character set in controlfile to ZHS16GBK
Synchronizing connection with database character set information
Refreshing type attributes with new character set information
Completed: alter database character set internal_use ZHS16GBK

6、重啟資料庫
> shutdown immediate
資料庫已經關閉。
已經解除安裝資料庫。
ORACLE 例程已經關閉。
> startup
ORACLE 例程已經啟動。

Total System Global Area 603979776 bytes
Fixed Size 1250380 bytes
Variable Size 159386548 bytes
Database Buffers 436207616 bytes
Redo Buffers 7135232 bytes
資料庫裝載完畢。
資料庫已經開啟。

7、驗證
> select userenv('language') from dual;

USERENV('LANGUAGE')
----------------------------------------------------
SIMPLIFIED CHINESE_CHINA.ZHS16GBK

--可見,資料庫字符集已經變為ZHS16GBK了。
再查原來是亂碼的資料:
> select * from a;

A
----------

查詢結果是亂碼,這也就是說對於原來庫中已經是亂碼的資料,修改字符集是無能為力的。

我們再看看此時是否可以插入原來是亂碼的漢字:

> insert into a values('珮');

已建立 1 行。

> select * from a;

A
----------

原來是亂碼的漢字現在可以正常插入和顯示,字符集修改成功。

.

[/php]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/231499/viewspace-63891/,如需轉載,請註明出處,否則將追究法律責任。

相關文章