ORACLE字符集基礎知識


概念描敘web

   ORACLE數據庫有國家字符集(national character set)與數據庫字符集(database character set)之分。二者都是在建立數據庫時須要設置的。國家字符集主要是用於NCHAR、NVARCHAR、NCLOB類型的字段數據,而數據庫字符集使用很普遍,它用於:CHAR、VARCHAR、CLOB、LONG類型的字段數據;數據庫

  

   ORACLE的字符集名字通常由如下部分組成:語言或區域、表示一個字符的比特位數、標準字符集名稱(可選項,S或C,表示服務器或客戶端)。ORACLE字符集UTF8與UTFE不符合此規定,其它基本都是這種格式。NLS_LANG=<Language>_<Territory>.<Clients Characterset>bash

set nls_lang=AMERICAN_AMERICA.UTF8服務器

set nls_lang=SIMPLIFIED CHINESE_AMERICA.UTF8session

NLS( National Language Support)國家語言支持。NLS是數據庫的一個很是強大的特性,它控制着數據的許多方面:好比數據如何存儲,通常來講它控制着如下兩個方面:oracle

文本數據持久存儲在磁盤上時如何編碼app

透明的將數據從一個字符集轉換到另一個字符集。編碼

假設你在數據庫中用WE8ISO8859P1 字符集存儲8 位的數據,可是你的某些客戶使用的是一種7 位字符集,如US7ASCII字符集轉換過程一般會修改數據,而你每每會把一個較大的字符集(在此例中就是8 位字符集)映射到一個較小的字符集(此例中的7 位字符集)。這是一種有損轉換(lossy conversion),字符就會被修改,這只是由於:較小的字符集不可能表示較大字符集中的每個字符。可是這種轉換必須發生。這也是亂碼產生的緣由。若是數據庫以一種單字節字符集存儲數據,可是客戶(如一個Java 應用,由於Java 語言使用Unicode)但願數據採用多字節表示,就必須執行轉換,只有這樣客戶應用才能使用這些數據。spa

ORACLE支持的Unicode字符集有如下幾種,下面的列表給出了字符集的名稱、對應的數據庫版本範圍、採用的Unicode的版本。.net

AL24UTFFSS:是ORACLE第一種支持Unicode的字符集,從7.2版本開始使用,可是它支持的Unicode版本爲1.1,所以從9i開始就不支持此字符集了。

UTF8 : 是ORACLE從ORACLE8開始使用的屬於UTF-8編碼的字符集,從ORACLE8.0到ORACLE8.16,Unicode版本爲2.1,而ORACLE817到10g,採用的Unicode標 準爲3.0

UTFE :用於EBCDIC碼平臺上的數據庫Unicode字符集。所以它屬於專用系統使用的字符集,其它屬性與UTF8基本相同。

AL32UTF8 :是從ORACLE9開始使用的屬於UTF-8編碼的字符集,與UTF8相比,它採用的Unicode版本更新,在10g版本中使用的是Unicode 4.01標準,而UTF8因 爲兼容性的考慮,在10g版本中用的是Unicode 3.0標準。

AL16UTF16:是ORACLE第一種採用UTF-16編碼方式的字符集,從ORACLE9開始使用,是做爲缺省的國家字符集使用,它不能被用做數據庫的字符集。這是由於數 據庫的字符集決定了SQL與PL/SQL源碼的編碼方式,對於UTF-16這種使用固定的兩個字節來表示英文字母的編碼方案來講,確實不適於用做數據庫 的字符集,ORACLE目前採用的數據庫字符集都是基於ASCII或EBCDID做爲子集的編碼方案。

對於US7ASCII,表示區域是US,用7個比特位表示一個字符,標準的字符集名稱爲ASCII。

對於中文字符集ZHS16GBK,表示簡體中文(ZHT爲繁體中文),一個字符須要16位比特,標準的字符集名稱爲GBK。而ZHS16CGB231280表示簡體中文,一個字符須要16位比特,標準的字符集名稱爲GB231280,屬於咱們前面提過的1981年發佈的GB2312-80標準。雖然咱們說,GBK編碼標準是GB2312編碼標準的擴展,可是數據庫字符集ZHS16GBK與ZHS16CGB231280之間卻不是嚴格的超集與子集的關係,主要是有些漢字的編碼在兩個字符集中的數值是不一樣的,所以它們進行字符集轉換時會出現問題。

查看字符集參數

1:查看NLS_CHARACTERSET:字符集,NLS_NCHAR_CHARACTERSET:國家字符集

實例字符集環境

SELECT * FROM NLS_INSTANCE_PARAMETERS

主要涉及NLS_LANGUAGE、NLS_TERRITORY的值. NLS_INSTANCE_PARAMETERS其來源於v$parameter,注意:網上不少資料都說"NLS_INSTANCE_PARAMETERS 表示客戶端的字符集的設置,能夠是參數文件,環境變量或者是註冊表",並且網上都人人亦云。記住它是表示實例的字符集環境。

數據庫可用字符集參數設置

SELECT * FROM V$NLS_VALID_VALUES

數據庫服務器字符集

SELECT * FROM NLS_DATABASE_PARAMETERS

 

NLS_DATABASE_PARAMETERS其來源於props$,是表示數據庫的字符集。

clip_image002

客戶端字符集環境

SELECT * FROM V$NLS_PARAMETERS;

SELECT USERENV('language') FROM DUAL;

USERENV、 V$NLS_PARAMETERS表示當前字符集環境。若是你在客戶端執行,則表示客戶端字符集環境。

會話字符集環境

SELECT * FROM NLS_SESSION_PARAMETERS;

它來源於v$nls_parameters,表示會話本身的設置,多是會話的環境變量或者是ALTER SESSION完成,若是會話沒有特殊的設置,將與 V$NLS_PARAMETERS一致。

2: 查看客戶端字符集(NLS_LANG) 的方法

若是系統是LINUX或UNIX平臺,則也能夠經過下面命令查看(前提是必須設置了NLS_LANG,不然查出來的是空值)

[etl@m1 ~]$env | grep NLS_LANG

NLS_LANG=AMERICAN_AMERICA.ZHS16GBK

[etl@m1 ~]$echo $NLS_LANG

AMERICAN_AMERICA.ZHS16GBK

若是系統是WINDOWS平臺,則能夠經過下面命令查看:

1:在運行裏面,輸入regedit進入註冊表,HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraDb11g_home1\裏面(最後一項與實例名、數據庫版本有關係),找到NLS_LANG選項,雙擊它,你就能夠看到相應的值。

2:echo %NLS_LANG% 。若是沒有設置NLS_LANG,用這個命令看不到相關信息。

3: 設置NLS_LANG的方法

Windows平臺:

3.1

set NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

set NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

3.2 能夠經過修改註冊表鍵值永久設置

HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/KEY_XXXX_home1/NLS_LANG

UNIX & LINUX

3.3

export NLS_LANG=AMERICAN_AMERICA.UTF8

3.4能夠編輯 bash_profile 文件進行永久設置

vi .bash_profile

export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"

客戶端的字符集要求與服務器一致,才能正確顯示數據庫的非Ascii字符。若是多個設置存在的時候優先級關係爲:SQL Function >Alter session>環境變量>註冊表>參數文件 字符集要求一致,可是語言設置卻能夠不一樣,語言設置建議用英文。如字符集是zhs16gbk,則nls_lang能夠是American_America.zhs16gbk。

修改數據庫字符集

數據庫字符集在建立後原則上不能更改。所以,在前期規劃和安裝之初考慮使用哪種字符集十分重要。對數據庫服務器而言,錯誤的修改字符集將會致使不少不可測的後果,可能會嚴重影響數據庫的正常運行,因此在修改以前必定要確認兩種字符集是否存在子集和超集的關係。通常來講,除非萬不得已,咱們不建議修改ORACLE數據庫SERVER端的字符集。

有兩種方法修改數據庫字符集設置

1. 一般須要導出數據庫數據,重建數據庫,而後再導入數據庫數據的方式來轉換。

2. 經過ALTER DATABASE CHARACTER SET語句修改字符集,但建立數據庫後能夠修改的字符集是有限制的,只有新的字符集是當前字符集的超集時才能修改數據庫字符集,例如UTF8是US7ASCII的超集,修改數據庫字符集可以使用ALTER DATABASE CHARACTER SET UTF8。

特別說明,咱們最經常使用的兩種字符集ZHS16GBK和ZHS16CGB231280之間不存在子集和超集關係,所以理論上講這兩種字符集之間的相互轉換不受支持修改

關於數據庫子集-超級對照表(subset-superset pairs),能夠參考官方文檔,例如ORACLE 10g的http://docs.oracle.com/cd/B19306_01/server.102/b14225/applocaledata.htm

Table A-11 Subset-Superset Pairs

Subset

Superset

AR8ADOS710

AR8ADOS710T

AR8ADOS720

AR8ADOS720T

AR8ADOS720T

AR8ADOS720

AR8APTEC715

AR8APTEC715T

AR8ARABICMACT

AR8ARABICMAC

AR8ISO8859P6

AR8ASMO708PLUS

AR8ISO8859P6

AR8ASMO8X

AR8MUSSAD768

AR8MUSSAD768T

AR8MUSSAD768T

AR8MUSSAD768

AR8NAFITHA711

AR8NAFITHA711T

AR8NAFITHA721

AR8NAFITHA721T

AR8SAKHR707

AR8SAKHR707T

AR8SAKHR707T

AR8SAKHR707

BLT8CP921

BLT8ISO8859P13

BLT8CP921

LT8MSWIN921

D7DEC

D7SIEMENS9780X

D7SIEMENS9780X

D7DEC

DK7SIEMENS9780X

N7SIEMENS9780X

I7DEC

I7SIEMENS9780X

I7SIEMENS9780X

IW8EBCDIC424

IW8EBCDIC424

IW8EBCDIC1086

KO16KSC5601

KO16MSWIN949

LT8MSWIN921

BLT8ISO8859P13

LT8MSWIN921

BLT8CP921

N7SIEMENS9780X

DK7SIEMENS9780X

US7ASCII

See Table A-12, "US7ASCII Supersets".

UTF8

AL32UTF8

WE8DEC

TR8DEC

WE8DEC

WE8NCR4970

WE8ISO8859P1

WE8MSWIN1252

WE8ISO8859P9

TR8MSWIN1254

WE8NCR4970

TR8DEC

WE8NCR4970

WE8DEC

WE8PC850

WE8PC858

 1: SQL>CONN / AS SYSDBA;
 2:  
 3: SQL>SHUTDOWN IMMEDIATE;
 4:  
 5: SQL>STARTUP MOUNT;
 6:  
 7: SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION;
 8:  
 9: SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
 10:  
 11: SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0;
 12:  
 13: SQL>ALTER DATABASE OPEN;

--能夠從子集到父集

 1: SQL>ALTER DATABASE CHARACTER SET ZHS16GBK;
 2:  
 3: --若是是從父集到子集,須要使用INTERNAL_USE參數,跳過超子集檢測
 4:  
 5: SQL>ALTER DATABASE NATIONAL CHARACTER SET UTF8;
 6:  
 7: --SQL>ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE UTF8;
 8:  
 9: SQL>SHUTDOWN IMMEDIATE;
 10:  
 11: SQL>STARTUP;

ALTER DATABASE NATIONAL CHARACTER SET UTF8;

有可能會出現ORA-12717: Cannot ALTER DATABASE NATIONAL CHARACTER SET when NCLOB data exists 這樣的提示信息.這時你用ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE UTF8;就可解決上述問題。

參考資料:

      http://blog.csdn.net/jkl_123/article/details/6157379

       http://blog.csdn.net/tianlesoftware/article/details/4915223

相關文章
相關標籤/搜索