1. 程式人生 > >Oracle10g更改資料庫字符集

Oracle10g更改資料庫字符集

一、軟體環境

1)oracle 10g

二、問題描述

Oracle資料庫中文字元出現亂碼,所以的中文字元顯示’?’符號

三、原因分析

Oracle的字符集有互相的包容關係。如us7ascii就是zhs16gbk的子集,從us7ascii到zhs16gbk不會有資料解釋上的問題,不會有資料丟失。在所有的字符集中utf8應該是最大,因為它基於unicode,雙位元組儲存字元(也因此在儲存空間上佔用更多)。
     一旦資料庫建立後,資料庫的字符集理論上講是不能改變的。因此,在設計和安裝之初考慮使用哪一種字符集十分重要。根據Oracle的官方說明,字符集的轉換是從子集到超集受支援,反之不行。如果兩種字符集之間根本沒有子集和超集的關係,那麼字符集的轉換是不受oracle支援的。對資料庫server而言,錯誤的修改字符集將會導致很多不可測的後果,可能會嚴重影響資料庫的正常執行,所以在修改之前一定要確認兩種字符集是否存在子集和超集的關係。一般來說,除非萬不得已,我們不建議修改oracle資料庫。

四、解決方案

    需要修改資料庫字符集為'us7ascii'。
    檢視資料庫當前資料集有兩種方式:
      a).select name,value$ from props$ where name like '%NLS%',其中NLS_CHARACTERSET所對應的為當前資料庫的字符集;
      b).select userenv('language') from dual;

   1.常規方案修改資料庫字符集

      1).以管理員身份登入:conn  sys/xxx  as sysdba,或者conn  /  as sysdba;
      2).關閉資料庫:shutdown immediate;
      3).以mount方式開啟資料庫:startup mount
      4).限制其它使用者連線資料庫使用資源: alter system enable restricted session;
      5).檢視系統當前的程序(最大連線數):show parameter processes;
      6).設定job_queue_processes=0殺掉CJQ0及相應job程序: alter system set job_queue_processes=0;
      7).修改引數alter system set aq_tm_processes=0;
      8).更改資料庫為open方式:alter database open;
      9).更改字符集:alter database character set us7ascii;
      a).*

在這裡,如果當前資料庫的字符集是系統字符集us7asci的超集,更改不會出問題;如果不是,將會提示:
     ORA-12712: 新字符集必須為舊字符集的超集
     
b).*如果資料庫資料有CLOB型別,系統將會提示:
     ORA-12716: Cannot ALTER DATABASE CHARACTER SET when CLOB data exists

2.使用INTERNAL_USE跳過超集檢測

針對以上的錯誤a)的解決方案:
     
10).ALTER DATABASE character set INTERNAL_USE us7ascii;--跳過超集檢查

   3.使用internal_convert轉換含有CLOB欄位的表

  針對以上的錯誤b)的解決方案:
  10).截斷表truncate table Metastylesheet;
  11).alter database character set internal_convert zhs16gbk;-- ORACLE會自動轉換含有CLOB
  12).因為前面清空了SYS.METASTYLESHEET表,需要重新建立
       9.2通過@?/rdbms/admin/catmet.sql建立;
          10g中沒有catmet.sql這個指令碼,通過執行catmeta.sql指令碼來重建
          @?/rdbms/admin/catmeta.sql
          (注意這個地方有待商榷,不確定,最好不要使用這種方法修改)

   4.完成方案a)和b)後再做如下步驟:

  1).檢視當前字符集,確認是否正確修改;
  2).解除限制其它使用者連線資料庫使用資源: alter system disable restricted session;
  3).最好也也設定一下set NLS_LANG
  4).關閉資料庫再開啟;

*以上內容通過參考整理而來,已經通過實踐驗證!