1. 程式人生 > >oracle修改字符集

oracle修改字符集

       Oracle字符集是一個位元組資料的解釋的符號集合,有大小之分,有相互的包容關係。ORACLE 支援國家語言的體系結構允許你使用本地化語言來儲存,處理,檢索資料。它使資料庫工具,錯誤訊息,排序次序,日期,時間,貨幣,數字,和日曆自動適應本地化語言和平臺。

影響Oracle資料庫字符集最重要的引數是NLS_LANG引數。

它的格式如下: NLS_LANG = language_territory.charset

它有三個組成部分(語言、地域和字符集),每個成分控制了NLS子集的特性。

其中:

Language 指定伺服器訊息的語言, 影響提示資訊是中文還是英文

Territory

 指定伺服器的日期和數字格式,

Charset指定字符集。

:AMERICAN _ AMERICA. ZHS16GBK

NLS_LANG的組成我們可以看出,真正影響資料庫字符集的其實是第三部分

所以兩個資料庫之間的字符集只要第三部分一樣就可以相互匯入匯出資料,前面影響的只是提示資訊是中文還是英文

二.字符集的相關知識:

2.1 字符集
實質就是按照一定的字元編碼方案,對一組特定的符號,分別賦予不同數值編碼的集合。Oracle資料庫最早支援的編碼方案是US7ASCII
    Oracle的字符集命名遵循以下命名規則:
    <Language><bit size><encoding>
    

: <語言><位元位數><編碼>
    
比如: ZHS16GBK表示採用GBK編碼格式、16位(兩個位元組)簡體中文字符集
 
  
2.2 
字元編碼方案


2.2.1 單位元組編碼
1單位元組7位字符集,可以定義128個字元,最常用的字符集為US7ASCII
    
2單位元組8位字符集,可以定義256個字元,適合於歐洲大部分國家

例如:WE8ISO8859P1(西歐、8位、ISO標準8859P1編碼)

2.2.2 多位元組編碼
1)變長多位元組編碼
某些字元用一個位元組表示,其它字元用兩個或多個字元表示,變長多位元組編碼常用於對亞洲語言的支援,例如日語、漢語、印地語等


例如:AL32UTF8(其中AL代表ALL,指適用於所有語言)、zhs16cgb231280
    
2)定長多位元組編碼

每一個字元都使用固定長度位元組的編碼方案,目前oracle唯一支援的定長多位元組編碼是AF16UTF16,也是僅用於國家字符集

2.2.3 unicode編碼
    Unicode是一個涵蓋了目前全世界使用的所有已知字元的單一編碼方案,也就是說Unicode為每一個字元提供唯一的編碼。UTF-16unicode16位編碼方式,是一種定長多位元組編碼,用2個位元組表示一個unicode字元,AF16UTF16UTF-16編碼字符集
    UTF-8unicode8位編碼方式,是一種變長多位元組編碼,這種編碼可以用123個位元組表示一個unicode字元,AL32UTF8UTF8UTFEUTF-8編碼字符集 
  
2.3 
字符集超級
當一種字符集(字符集A)的編碼數值包含所有另一種字符集(字符集B)的編碼數值,並且兩種字符集相同編碼數值代表相同的字元時,則字符集A是字符集B的超級,或稱字符集B是字符集A的子集。
    Oracle8ioracle9i官方文件資料中備有子集-超級對照表(subset-superset pairs,例如:WE8ISO8859P1WE8MSWIN1252的子集。由於US7ASCII是最早的Oracle資料庫編碼格式,因此有許多字符集是US7ASCII的超集,例如WE8ISO8859P1ZHS16CGB231280ZHS16GBK都是US7ASCII的超集。 
  
2.4 
資料庫字符集(oracle伺服器端字符集)
資料庫字符集在建立資料庫時指定,在建立後通常不能更改。在建立資料庫時,可以指定字符集(CHARACTER SET)和國家字符集(NATIONAL CHARACTER SET)

2.4.1字符集
    (1)用來儲存CHAR, VARCHAR2, CLOB, LONG等型別資料
    (2)用來標示諸如表名、列名以及PL/SQL變數等
    (3)用來儲存SQLPL/SQL程式單元等

2.4.2國家字符集:
    (1)用以儲存NCHAR, NVARCHAR2, NCLOB等型別資料
    (2)國家字符集實質上是為oracle選擇的附加字符集,主要作用是為了增強oracle的字元處理能力,因為NCHAR資料型別可以提供對亞洲使用定長多位元組編碼的支援,而資料庫字符集則不能。國家字符集在oracle9i中進行了重新定義,只能在unicode編碼中的AF16UTF16UTF8中選擇,預設值是AF16UTF16

2.4.3查詢字符集引數
可以查詢以下資料字典或檢視檢視字符集設定情況
    nls_database_parametersprops$v$nls_parameters
    
查詢結果中NLS_CHARACTERSET表示字符集NLS_NCHAR_CHARACTERSET表示國家字符集

2.4.4修改資料庫字符集
按照上文所說,資料庫字符集在建立後原則上不能更改。不過有2種方法可行。

1. 如果需要修改字符集,通常需要匯出資料庫資料,重建資料庫,再匯入資料庫資料的方式來轉換

2. 通過ALTER DATABASE CHARACTER SET語句修改字符集,但建立資料庫後修改字符集是有限制的,只有新的字符集是當前字符集的超集時才能修改資料庫字符集,例如UTF8US7ASCII的超集,修改資料庫字符集可使用ALTER DATABASE CHARACTER SET UTF8 
  
2.5 
客戶端字符集(NLS_LANG引數)


2.5.1客戶端字符集含義
客戶端字符集定義了客戶端字元資料的編碼方式,任何發自或發往客戶端的字元資料均使用客戶端定義的字符集編碼,客戶端可以看作是能與資料庫直接連線的各種應用,例如sqlplus,exp/imp等。客戶端字符集是通過設定NLS_LANG引數來設定的。

2.5.2 NLS_LANG引數格式
    NLS_LANG=<language>_<territory>.<client character set> 
    Language: 
顯示oracle訊息,校驗,日期命名
    Territory指定預設日期、數字、貨幣等格式
    Client character set指定客戶端將使用的字符集
例如:NLS_LANG=AMERICAN_AMERICA.US7ASCII 
    AMERICAN
是語言,AMERICA是地區,US7ASCII是客戶端字符集

2.5.3客戶端字符集設定方法
     1)UNIX環境
         $NLS_LANG=“simplified chinese”_china.zhs16gbk
         $export NLS_LANG
         
編輯oracle使用者的profile檔案
    2)Windows環境
編輯登錄檔
         Regedit.exe --- HKEY_LOCAL_MACHINE ---SOFTWARE --- ORACLE-HOME

2.5.4 NLS引數查詢
    Oracle提供若干NLS引數定製資料庫和使用者機以適應本地格式,例如有NLS_LANGUAGE,NLS_DATE_FORMAT,NLS_CALENDER等,可以通過查詢以下資料字典或v$檢視檢視。
NLS_DATABASE_PARAMETERS:顯示資料庫當前NLS引數取值,包括資料庫字符集取值
NLS_SESSION_PARAMETERS顯示由NLS_LANG 設定的引數,或經過alter session 改變後的引數值(不包括由NLS_LANG 設定的客戶端字符集)
NLS_INSTANCE_PARAMETE 顯示由引數檔案init<SID>.ora 定義的引數

V$NLS_PARAMETERS顯示資料庫當前NLS引數取值

2.5.5修改NLS引數
使用下列方法可以修改NLS引數
1)修改例項啟動時使用的初始化引數檔案
2)修改環境變數NLS_LANG
    
3)使用ALTER SESSION語句,在oracle會話中修改

4)使用某些SQL函式
    NLS作用優先級別Sql function > alter session > 環境變數或登錄檔 引數檔案 資料庫預設引數

三.EXP/IMP 字符集

3.1 EXP/IMP
    Export  Import 是一對讀寫Oracle資料的工具。Export  Oracle 資料庫中的資料輸出到作業系統檔案中, Import 把這些檔案中的資料讀到Oracle 資料庫中,由於使用exp/imp進行資料遷移時,資料從源資料庫到目標資料庫的過程中有四個環節涉及到字符集,如果這四個環節的字符集不一致,將會發生字符集轉換。 
EXP
     ____________ _________________ _____________
     |imp
匯入檔案|<-|環境變數NLS_LANG|<-|資料庫字符集
|
      ------------   -----------------   -------------

IMP 
     ____________ _________________ _____________
     |imp
匯入檔案|->|環境變數NLS_LANG|->|資料庫字符集
|
      ------------   -----------------   -------------

四個字符集是
1)源資料庫字符集2Export過程中使用者會話字符集(通過NLS_LANG設定)
3Import過程中使用者會話字符集(通過NLS_LANG設定)
4)目標資料庫字符集 
  
3.2
匯出的轉換過程

Export過程中,如果源資料庫字符集與Export使用者會話字符集不一致,會發生字符集轉換,並在匯出檔案的頭部幾個位元組中儲存Export使用者會話字符集的ID號。在這個轉換過程中可能發生資料的丟失。

:如果源資料庫使用ZHS16GBK,而Export使用者會話字符集使用US7ASCII,由於ZHS16GBK16位字符集,US7ASCII7位字符集,這個轉換過程中,中文字元在US7ASCII中不能夠找到對等的字元,所以所有中文字元都會丟失而變成“?? ”形式,這樣轉換後生成的Dmp檔案已經發生了資料丟失。
因此如果想正確匯出源資料庫資料,則Export過程中使用者會話字符集應等於源資料庫字符集或是源資料庫字符集的超集 
  
3.3
匯入的轉換過程

1)確定匯出資料庫字符集環境
通過讀取匯出檔案頭,可以獲得匯出檔案的字符集設定
2)確定匯入session的字符集,即匯入Session使用的NLS_LANG環境變數
3IMP讀取匯出檔案
讀取匯出檔案字符集ID,和匯入程序的NLS_LANG進行比較
4)如果匯出檔案字符集和匯入Session字符集相同,那麼在這一步驟內就不需要轉換,如果不同,就需要把資料轉換為匯入Session使用的字符集。可以看出,匯入資料到資料庫過程中發生兩次字符集轉換


第一次:匯入檔案字符集與匯入Session使用的字符集之間的轉換,如果這個轉換過程不能正確完成,Import向目標資料庫的匯入過程也就不能完成。
第二次:匯入Session字符集與資料庫字符集之間的轉換。

檢視資料庫字符集

涉及三方面的字符集,

端的字符集;

2. oracle client端的字符集;

3. dmp檔案的字符集。

在做資料匯入的時候,需要這三個字符集都一致才能正確匯入。

4.1 查詢oracle server端的字符集

有很多種方法可以查出oracle server端的字符集,比較直觀的查詢方法是以下這種:

SQL> select userenv('language') from dual;

USERENV('LANGUAGE')

----------------------------------------------------

SIMPLIFIED CHINESE_CHINA.ZHS16GBK

SQL>select userenv(‘language’) from dual;

AMERICAN _ AMERICA. ZHS16GBK

4.2 如何查詢dmp檔案的字符集

oracleexp工具匯出的dmp檔案也包含了字符集資訊,dmp檔案的第2和第3個位元組記錄了dmp檔案的字符集。如果dmp檔案不大,比如只有幾M或幾十M,可以用UltraEdit開啟(16進位制方式),看第23