天天看點

ORACLE字元集基礎知識

<b>概念描叙</b>

   oracle

資料庫有國家字元集(national character set)與資料庫字元集(database character

set)之分。兩者都是在建立資料庫時需要設定的。國家字元集主要是用于nchar、nvarchar、nclob類型的字段資料,而資料庫字元集使用很

廣泛,它用于:char、varchar、clob、long類型的字段資料;

oracle的字元集名字一般由以下部分組成:語言或區域、表示一個字元的比特位數、标準字元集名稱(可選項,s或c,表示伺服器或用戶端)。

oracle字元集utf8與utfe不符合此規定,其它基本都是這種格式。nls_lang=&lt;language&gt;_&lt;

territory&gt;.&lt;clients characterset&gt;

set nls_lang=american_america.utf8

set nls_lang=simplified chinese_america.utf8

nls( national language support)國家語言支援。nls是資料庫的一個非常強大的特性,它控制着資料的許多方面:比如資料如何存儲,一般來說它控制着以下兩個方面:

文本資料持久存儲在磁盤上時如何編碼

透明的将資料從一個字元集轉換到另外一個字元集。

設你在資料庫中用we8iso8859p1 字元集存儲8 位的資料,但是你的某些客戶使用的是一種7

位字元集,如us7ascii字元集轉換過程通常會修改資料,而你往往會把一個較大的字元集(在此例中就是8

位字元集)映射到一個較小的字元集(此例中的7 位字元集)。這是一種有損轉換(lossy

conversion),字元就會被修改,這隻是因為:較小的字元集不可能表示較大字元集中的每一個字元。但是這種轉換必須發生。這也是亂碼産生的原因。

如果資料庫以一種單位元組字元集存儲資料,但是客戶(如一個java 應用,因為java

語言使用unicode)希望資料采用多位元組表示,就必須執行轉換,隻有這樣客戶應用才能使用這些資料。

oracle支援的unicode字元集有以下幾種,下面的清單給出了字元集的名稱、對應的資料庫版本範圍、采用的unicode的版本。

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基本相同。

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之間卻不是嚴格的超集與子集的關系,

主要是有些漢字的編碼在兩個字元集中的數值是不同的,是以它們進行字元集轉換時會出現問題。

<b>檢視字元集參數</b><b> </b><b></b>

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$,是表示資料庫的字元集。

ORACLE字元集基礎知識

用戶端字元集環境

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

3.2 可以通過修改系統資料庫鍵值永久設定

hkey_local_machine/software/oracle/key_xxxx_home1/nls_lang

unix &amp; linux

3.3

export nls_lang=american_america.utf8

3.4可以編輯 bash_profile 檔案進行永久設定

vi .bash_profile

export nls_lang="simplified chinese_china.zhs16gbk"

用戶端的字元集要求與伺服器一緻,才能正确顯示資料庫的非ascii字元。如果多個設定存在的時候<b>,</b>優先級關系為:sql function &gt;alter session&gt;環境變量&gt;系統資料庫&gt;參數檔案<b> </b>字元集要求一緻,但是語言設定卻可以不同,語言設定建議用英文。如字元集是zhs16gbk,則nls_lang可以是american_america.zhs16gbk。

<b></b><b></b>

<b>修改資料庫字元集</b>

據庫字元集在建立後原則上不能更改。是以,在前期規劃和安裝之初考慮使用哪一種字元集十分重要。對資料庫伺服器而言,錯誤的修改字元集将會導緻很多不可測

的後果,可能會嚴重影響資料庫的正常運作,是以在修改之前一定要确認兩種字元集是否存在子集和超集的關系。一般來說,除非萬不得已,我們不建議修改

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

subset

superset

ar8ados710

ar8ados710t

ar8ados720

ar8ados720t

ar8aptec715

ar8aptec715t

ar8arabicmact

ar8arabicmac

ar8iso8859p6

ar8asmo708plus

ar8asmo8x

ar8mussad768

ar8mussad768t

ar8nafitha711

ar8nafitha711t

ar8nafitha721

ar8nafitha721t

ar8sakhr707

ar8sakhr707t

blt8cp921

blt8iso8859p13

lt8mswin921

d7dec

d7siemens9780x

dk7siemens9780x

n7siemens9780x

i7dec

i7siemens9780x

iw8ebcdic424

iw8ebcdic1086

ko16ksc5601

ko16mswin949

us7ascii

see table a-12, "us7ascii supersets".

utf8

al32utf8

we8dec

tr8dec

we8ncr4970

we8iso8859p1

we8mswin1252

we8iso8859p9

tr8mswin1254

we8pc850

we8pc858

--可以從子集到父集

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;就可解決上述問題。