oracle字元集

來源:互聯網
上載者:User

標籤:oracle、字元集

 

                       oracle字元集

1、引言

ORACLE資料庫字元集,即Oracle全球化支援(Globalization Support),或即國家語言支援(NLS)其作用是用本國語言和格式來儲存、處理和檢索資料。利用全球化支援,ORACLE為使用者提供自己熟悉的資料庫母語環境,諸如日期格式、數字格式和儲存序列等。Oracle可以支援多種語言及字元集,其中oracle8i支援48種語言、76個國家地區、229種字元集,而oracle9i則支援57種語言、88個國家地區、235種字元集。

2、概述2.1字元集概述

實質就是按照一定的字元編碼方案,對一組特定的符號,分別賦予不同數值編碼的集合。Oracle資料庫最早支援的編碼方案是US7ASCII。

    Oracle 的字元集命名遵循以下命名規則 :

即:  <語言><位元位元><編碼 >

例:NLS_LANG=AMERICAN_AMERICA.ZHS16GBK

比如: ZHS16GBK表示採用GBK編碼格式、16位(兩個位元組)簡體中文字元集

2.2字元集超級

當一種字元集(字元集A)的編碼數值包含所有另一種字元集(字元集B)的編碼數值,並且兩種字元集相同編碼數值代表相同的字元時,則字元集A是字元集B的超級,或稱字元集B是字元集A的子集。

    Oracle8i 和oracle9i官方文檔資料中備有子集-超級對照表(subset-superset pairs),例如:WE8ISO8859P1是WE8MSWIN1252的子集。由於US7ASCII是最早的Oracle資料庫編碼格式,因此有許多字元集是US7ASCII的超集,例如WE8ISO8859P1、ZHS16CGB231280、ZHS16GBK都是US7ASCII的超集。

2.3oracle資料庫字元集

資料庫字元集在建立資料庫時指定,在建立後通常不能更改。在建立資料庫時,可以指定字元集(CHARACTER SET)和國家字元集(NATIONAL CHARACTERSET)。

2.3.1 字元集
  • 用來儲存CHAR, VARCHAR2,CLOB, LONG等類型資料

  • 用來標示諸如表名、列名以及PL/SQL變數等

  • 用來儲存SQL和PL/SQL程式單元等

  • 國家字元集
  • 用以儲存NCHAR, NVARCHAR2,NCLOB等類型資料

  • 國家字元集實質上是為oracle選擇的附加字元集,主要作用是為了增強oracle的字元處理能力,因為NCHAR資料類型可以提供對亞洲使用定長多位元組編碼的支援,而資料庫字元集則不能。國家字元集在oracle9i中進行了重新定義,只能在unicode編碼中的AF16UTF16和UTF8中選擇,預設值是 AF16UTF16

  • 查詢字元集參數

    可以查詢以下資料字典或視圖查看字元集設定情況

    nls_database_parameters 、props$、 v$nls_parameters

    查詢結果中NLS_CHARACTERSET表示字元集,NLS_NCHAR_CHARACTERSET表示國家字元集

2.3.4 修改資料庫字元集

    按照上文所說,資料庫字元集在建立後原則上不能更改。如果需要修改字元集,通常需要匯出資料庫資料,重建資料庫,再匯入資料庫資料的方式來轉換,或通過ALTER DATABASE CHARACTER SET語句修改字元集,但建立資料庫後修改字元集是有限制的,只有新的字元集是當前字元集的超集時才能修改資料庫字元集,例如UTF8是US7ASCII的超集,修改資料庫字元集可使用ALTER DATABASE CHARACTER SET UTF8。

2.3.5 常見字元集亂碼問題
  • 使用用戶端sqlplus向資料庫儲存資料

這個過程存在3個字元集設定:

    (1)用戶端應用字元集

    (2)用戶端NLS_LANG參數設定

    (3)伺服器端資料庫字元集(Character Set)設定

    用戶端應用sqlplus中能夠顯示什麼樣的字元取決於用戶端作業系統語言環境(用戶端應用字元集),但在應用中錄入這些字元後,這些字元能否在資料庫中正常儲存,還與另外兩個字元集設定緊密相關,其中用戶端NLS_LANG參數主要用於字元資料傳輸過程中的轉換判斷。

    亂碼產生是由於幾個字元集之間轉換不匹配造成,分以下幾種情況:

    (註:字元集之間如果不存在子集、超集對應關係時的情況不予考慮,因為這種情況下字元集之間轉換必產生亂碼)   

 1)伺服器端資料庫字元集與用戶端應用字元集相同,與用戶端NLS_LANG參數設定不同

    如果用戶端NLS_LANG字元集是其它兩種字元集的子集,轉換過程將出現亂碼。

    解決方案:將三種字元集設定成同一字元集,或NLS_LANG字元集是其它兩種字元集的超集

2 )伺服器端資料庫字元集與用戶端NLS_LANG參數設定相同,與用戶端應用字元集不同

    如果用戶端應用字元集是其它兩種字元集的超集時,轉換過程將出現亂碼

3 )用戶端應用字元集、用戶端NLS_LANG參數設定、伺服器端資料庫字元集互不相同

    此種情況較為複雜,但三種字元集之間只要有不能轉換的字元,則必產生亂碼

  

常見的亂碼大致有兩種情形:

    (1)漢字變成問號“?”;

當從字元集A 轉換成字元集B時,如果轉換字元之間不存在對應關係,NLS_LANG使用替代字元“?”替代無法映射的字元;

    (2)漢字變成未知字元(雖然有些是漢字,但與原字元含義不同)

轉換存在對應關係,但字元集A 中的字元編碼與字元集B 中的字元編碼代表不同含義。

  • 匯入/匯出過程

這個過程存在4個字元集設定:

   (1)來源資料庫字元集

   (2)EXP過程中NLS_LANG參數

   (3)IMP過程中NLS_LANG參數

   (4)目標資料庫字元集

    出現亂碼原因

    1 )當來源資料庫字元集不等於EXP過程中NLS_LANG參數,且來源資料庫字元集是EXP過程中NLS_LANG的子集,才能保證匯出檔案正確,其他情況則匯出檔案字元亂碼

    2 )EXP過程中NLS_LANG字元集不等於IMP過程中NLS_LANG字元集,且EXP過程中NLS_LANG字元集是IMP過程中NLS_LANG字元集的子級,才能保證第一次轉換正常,否則第一次轉換中出現亂碼。

    3 )如果第一次轉換正常,IMP過程中NLS_LANG字元集是目標資料庫字元集的子集或相同,才能保證第二次轉換正常,否則則第二次轉換中出現亂碼。

3、現狀分析

對目前實施資料庫資源集區的幾個試驗網省進行字元集統計

 

字元集

數量

佔比

AL32UTF8

15

17.86%

UTF8

20

23.81%

WE8MSWIN1252

1

1.19%

ZHS16GBK

45

53.57%

空白

3

3.57%

合計

84


 

以上為試驗網省目前在運行oracle資料庫抽檢的共84套,其中字元集ZHS16GBK和UTF8 兩種共佔比約77.38%。由於字元集多樣,存在國網公司向網省公司下發資料時存在無法寫入的問題及網省內不同資料庫遷移出現亂碼問題。

4、風險後果
  • 可能出現資料庫資料混亂的情況。

  • 可能會出現char、varchar2、LOB等欄位長度不夠,需要重新定義表結構。

  • 可能會造成資料庫表char、varchar2、CLOB、LONG欄位出現亂碼。

  • 可能會損壞資料檔案,遺失資料。

  • 作業系統和資料庫伺服器字元集不相容,存入伺服器裡資料錯誤而不易察覺。

  • 不能存入一些特殊的符號。

 

5、解決建議

資料庫字元集在建立後原則上不能更改。因此,在設計和安裝之初考慮使用哪一種字元集十分重要。對資料庫server而言,錯誤的修改字元集將會導致很多不可測的後果,可能會嚴重影響資料庫的正常運行,所以在修改之前一定要確認兩種字元集是否存在子集和超集的關係。一般來說,除非萬不得已,我們不建議修改oracle資料庫server端的字元集。特別說明,我們最常用的兩種字元集ZHS16GBK和Al32UTF8之間不存在子集和超集關係,因此理論上講這兩種字元集之間的相互轉換不受支援。

為了避免字元集不統一,先制定以下幾點建議:

  • 對於新系統,嚴格按照國網統一標準的字元集;

  • 對於舊系統,如果字元集是國網統一標準的字元集或者子集,可以修改保持統一;

  • 對於舊系統,不是國網統一標準的字元集及子集,ZHS16GBK可以轉換為AL32UTF8,在遷移過程中,用戶端隨便為其中的一種編碼,遷移資料不會出現亂碼,但是會出現列長度不夠現象,反之則不行;

  • 對於其他字元集,為了避免在資料庫遷移過程中由於字元集不同導致的資料損失,oracle提供了字元集掃描工具(character set scanner),通過這個工具我們可以測試在資料移轉過程中由於字元集轉換可能帶來的問題,然後根據測試結果,確定資料移轉過程中最佳字元集解決方案。

修改資料庫字元集有以下方法:

5.1 從子集修改到超集

通過ALTER DATABASECHARACTER SET語句修改字元集,但建立資料庫後修改字元集是有限制的,只有新的字元集是當前字元集的超集時才能修改資料庫字元集,例如UTF8是US7ASCII的超集,修改資料庫字元集可使用ALTER DATABASE CHARACTER SET UTF8。

5.2 修改dmp檔案

dmp檔案的第2第3位元組記錄了字元集資訊,因此直接修改dmp檔案的第2第3位元組的內容就可以‘騙’過oracle的檢查。這樣做理論上也僅是從子集到超集可以修改,但很多情況下在沒有子集和超集關係的情況下也可以修改,我們常用的一些字元集,如US7ASCII,WE8ISO8859P1,ZHS16CGB231280,ZHS16GBK基本都可以改。因為改的只是dmp檔案,所以影響不大。

具體的修改方法比較多,最簡單的就是直接用UltraEdit修改dmp檔案的第2和第3個位元組。

比如想將dmp檔案的字元集改為ZHS16GBK,可以用以下SQL查出該種字元集對應的16進位代碼:SQL> select to_char(nls_charset_id(‘ZHS16GBK‘), ‘xxxx‘) from dual;

0354

然後將dmp檔案的2、3位元組修改為0354即可。

5.3 epx/imp修改字元集

需要匯出資料庫資料,重建資料庫,再匯入資料庫資料的方式來轉換

  • 備份資料庫中所有使用者的資料

  • 評估轉換成後的風險(使用csscan工具)

  • 更改資料庫的字元集或建立新資料庫

  • 匯入備份的使用者資料

注意:轉換之前,要使用Oracle的csscan工具對資料庫掃描,評估字元集轉換前後,資料有可能的損壞情況,如果評估樂觀,可以進行轉換嘗試,但是沒有任何專家建議這種做,即使是在實驗的資料庫上,無外乎“安全”二字;如果評估情況糟糕,那就絕對要放棄了。

 

 

 

                         

 


oracle字元集

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.