免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
深入分析Oracle字符集(轉(zhuǎn)載)
如何選擇數(shù)據(jù)庫(kù)的字符集是一個(gè)有爭(zhēng)議的話題,字符集本身涉及的范圍很廣,它與應(yīng)用程序、客戶的本地環(huán)境、操作系統(tǒng)、服務(wù)器等關(guān)系很密切,因此要做出合適的選擇,需要明白這些因素之間的關(guān)系。另外對(duì)字符集的基本概念,ORACLE數(shù)據(jù)庫(kù)字符集的一些知識(shí)也需要了解。
隨著國(guó)內(nèi)的軟件產(chǎn)品逐步走向海外,對(duì)于多語(yǔ)言的支持已經(jīng)成為軟件的一個(gè)基本要求,采用UNICODE標(biāo)準(zhǔn)也逐漸成為通用的設(shè)計(jì)方案,此時(shí)ORACLE數(shù)據(jù)庫(kù)的字符集應(yīng)該如何選擇?很多人都有自己的見解,在網(wǎng)上也可以看到很多關(guān)于字符集的文章。這些文章有很多精華值得去學(xué)習(xí),但是另一方面還存在一些錯(cuò)誤,尤其對(duì)UNICODE,存在一些概念不清的地方。
數(shù)據(jù)庫(kù)字符集的選擇并不存在絕對(duì)意義上的正確或錯(cuò)誤,每種字符集都有它適用的環(huán)境。對(duì)于我們來(lái)說(shuō),了解得越多,越能幫助自己做出適當(dāng)?shù)剡x擇,而且可以采取措施去主動(dòng)防范或規(guī)避可能出現(xiàn)的問(wèn)題。反之,如果數(shù)據(jù)庫(kù)字符集選擇不恰當(dāng),會(huì)給后面的工作帶來(lái)很多的麻煩,需要花費(fèi)很多時(shí)間和精力去解決問(wèn)題,有些問(wèn)題甚至?xí)绊懙娇蛻舻臉I(yè)務(wù)使用。本文希望可以給大家提供一些相對(duì)全面的知識(shí),方便大家了解數(shù)據(jù)庫(kù)字符集的相關(guān)概念,因此有些繁瑣,請(qǐng)大家見諒。另外由于個(gè)人的局限,有何不妥之處還請(qǐng)大家不吝指正。
下面我們由淺入深,先由概念入手,再給出幾種常用的字符集設(shè)置建議,對(duì)一些可能遇到的問(wèn)題做出分析,最后給出自己的建議。
1、字符集的一些基本知識(shí)
講到數(shù)據(jù)庫(kù)的字符集設(shè)置,首先需要對(duì)字符集的知識(shí)有些了解。以下是字符集的基本知識(shí)介紹:由于計(jì)算機(jī)只能存儲(chǔ)使用二進(jìn)制數(shù)據(jù),因此對(duì)于一些字符或符號(hào),需要對(duì)它們進(jìn)行編碼,用編碼后的數(shù)值來(lái)表示這些字符。對(duì)于一組符號(hào)的編碼集合就是字符集。
字符集有很多種,最初的字符集是ASCII,它用一個(gè)字節(jié)中的7位來(lái)表示128個(gè)字符,第8位沒有使用。它包括大小寫字母、數(shù)字0-9、標(biāo)點(diǎn)符號(hào)、非打印字符(換行符、制表符等4個(gè))以及控制字符(退格、響鈴等)等。由于ASCII支持的字符很有限,因此隨后又出現(xiàn)了很多的編碼方案,這些編碼方案大部分都是包括了ASCII的,它們只是做了擴(kuò)展,這些擴(kuò)展的內(nèi)容一般各不相同,因此說(shuō)ASCII是一個(gè)比較基本的編碼,EBCDIC編碼是另一個(gè)比較基本的編碼,它的部分字符采用了和ASCII不同的編碼值,因此兩者是不兼容的基本編碼方案。采用EBCDIC編碼的比較少,目前主要是IBM的系統(tǒng)采用,如AS400及S390系統(tǒng),大部分的系統(tǒng)都是基于ASCII編碼的。
由于亞洲國(guó)家的字符集相對(duì)復(fù)雜一些,因此一般都使用了兩個(gè)及以上的字節(jié)進(jìn)行編碼的方案。對(duì)于簡(jiǎn)體中文,GB2312碼是國(guó)家1981年實(shí)施的編碼標(biāo)準(zhǔn),通行于大陸。新加坡等地也使用此編碼。GBK編碼是GB2312碼的擴(kuò)展,是1995年發(fā)布的指導(dǎo)性規(guī)范,它在字匯一級(jí)支持ISO/IEC 10646-1 和GB13000-1 的全部中日韓 (CJK)漢字(20902字)。目前最新的漢字字符集是2000年的GB18030,它是取代GBK1.0的正式國(guó)家標(biāo)準(zhǔn)。該標(biāo)準(zhǔn)收錄了27484個(gè)漢字,同時(shí)還收錄了藏文、蒙文、維吾爾文等主要的少數(shù)民族文字。目前簡(jiǎn)體WINDOWS的缺省內(nèi)碼還是GBK,可以通過(guò)GB18030升級(jí)包升級(jí)到GB18030。不過(guò)GB18030相對(duì)GBK增加的字符,普通人是很難用到的,因此GBK還是我們目前最常用的簡(jiǎn)體中文字符集。
由于編碼方案太多且彼此之間不兼容,存在互相之間存在沖突的情況,即對(duì)于同一個(gè)編碼數(shù)值,在兩種不同的編碼方案中代表的是兩個(gè)不同的字符。這樣對(duì)于一些WEB應(yīng)用來(lái)說(shuō),由于多種語(yǔ)言文字的同時(shí)使用及存儲(chǔ),需要采用一種統(tǒng)一的字符集。為此,國(guó)際標(biāo)準(zhǔn)化組織(ISO)制定了ISO10646碼表,而Unicode協(xié)會(huì)制定了Unicode規(guī)范,這兩個(gè)體系剛開始時(shí)是獨(dú)立建立的,在1991年,雙方都認(rèn)識(shí)到世界不需要兩個(gè)不兼容的字符集。于是它們開始合并雙方的工作成果,并為創(chuàng)立一個(gè)單一編碼表而協(xié)同工作。從Unicode2.0開始,Unicode項(xiàng)目采用了與ISO10646-1相同的字庫(kù)和字碼。目前兩個(gè)項(xiàng)目仍都存在,并獨(dú)立地公布各自的標(biāo)準(zhǔn)。Unicode協(xié)會(huì)現(xiàn)在的最新版本是2006年的Unicode5.0。ISO的最新標(biāo)準(zhǔn)是10646-3:2003。下面簡(jiǎn)單介紹一下幾種常見的編碼方式:
UCS(UniversalCharacter Set)是按ISO-10646定義的字符集,有兩種最常用編碼方式:UCS-2和UCS-4。
UCS-2:使用0-65535之間的數(shù)表示一個(gè)unicode字符。UCS-2無(wú)法表示所有的unicode字符,只能表示其前65536個(gè)字符(稱為BasicMultilingual Plane,BMP)。我們一般經(jīng)常使用的UNICODE碼就是指這個(gè)編碼方案。
UCS-4:使用0-FFFFFFFF之間的數(shù)表示一個(gè)unicode字符,但為了和unicode體系兼容(unicode體系是一個(gè)20bit系統(tǒng)),ISO-10646表示所有定義的字符將不超過(guò)10FFFF。UCS-4可以表示所有的unicode字符。
Unix下使用 UCS-2/UCS-4會(huì)導(dǎo)致非常嚴(yán)重的問(wèn)題,因?yàn)橛幸恍┨厥獾淖址?比如 ''\0'' 或''/'',它們?cè)谖募推渌鸆的庫(kù)函數(shù)參數(shù)里都有特別的含義,C語(yǔ)言使用''\0''作為字符串結(jié)尾,而Unicode里恰恰有很多字符都有一個(gè)字節(jié)為0,這樣一來(lái),C語(yǔ)言的字符串函數(shù)將無(wú)法正常處理Unicode,除非把世界上所有用C寫的程序以及他們所用的函數(shù)庫(kù)全部換掉。
為了解決這個(gè)問(wèn)題,于是產(chǎn)生了將Unicode編碼規(guī)則和計(jì)算機(jī)的實(shí)際編碼對(duì)應(yīng)起來(lái)的一個(gè)規(guī)則,UTF,英文為UCSTransformationFormat,即UCS轉(zhuǎn)換格式,目前常用的有UTF-8、UTF-16、UTF-32三種。(還有UTF-7在此就不介紹了)。正如名字所示,它們分別使用8位、16位、32位比特對(duì)UCS進(jìn)行編碼。
UTF-8:一種變長(zhǎng)的Unicode編碼方式,使用1到4個(gè)字節(jié)表示一個(gè)字符。這種方式的最大好處,是UTF-8保留了ASCII字符的編碼作為它的一部分,因此在ASCII表示的128個(gè)字符在UTF-8的編碼沒有變化,它的兼容性比較好。UTF-8在目前WEB應(yīng)用上使用很廣泛。
UTF-16:一種變長(zhǎng)Unicode編碼方式,使用兩個(gè)或者四個(gè)字節(jié)表示一個(gè)字符。這種編碼方式比較節(jié)省空間,因?yàn)樗炎畛J褂玫淖址加脙蓚€(gè)字節(jié)來(lái)表示,而那些不常用的字節(jié)則用兩個(gè)或四個(gè)字節(jié)來(lái)表示。但對(duì)于英文字符來(lái)說(shuō),它要用兩個(gè)字節(jié)來(lái)編碼。
UTF-32:一種固定長(zhǎng)度的Unicode編碼方式,使用四個(gè)字節(jié)表示一個(gè)字符,它適用在內(nèi)存很充足,需要定長(zhǎng)的編碼場(chǎng)合。
2、ORACLE數(shù)據(jù)庫(kù)的字符集
ORACLE的字符集名字一般由以下部分組成:語(yǔ)言或區(qū)域、表示一個(gè)字符的比特位數(shù)、標(biāo)準(zhǔn)字符集名稱(可選項(xiàng),S或C,表示服務(wù)器或客戶端)。ORACLE字符集UTF8與UTFE不符合此規(guī)定,其它基本都是這種格式。
對(duì)于US7ASCII,表示區(qū)域是US,用7個(gè)比特位表示一個(gè)字符,標(biāo)準(zhǔn)的字符集名稱為ASCII。
對(duì)于中文字符集ZHS16GBK,表示簡(jiǎn)體中文(ZHT為繁體中文),一個(gè)字符需要16位比特,標(biāo)準(zhǔn)的字符集名稱為GBK。而ZHS16CGB231280表示簡(jiǎn)體中文,一個(gè)字符需要16位比特,標(biāo)準(zhǔn)的字符集名稱為GB231280,屬于我們前面提過(guò)的1981年發(fā)布的GB2312-80標(biāo)準(zhǔn)。雖然我們說(shuō),GBK編碼標(biāo)準(zhǔn)是GB2312編碼標(biāo)準(zhǔn)的擴(kuò)展,但是數(shù)據(jù)庫(kù)字符集ZHS16GBK與ZHS16CGB231280之間卻不是嚴(yán)格的超集與子集的關(guān)系,主要是有些漢字的編碼在兩個(gè)字符集中的數(shù)值是不同的,因此它們進(jìn)行字符集轉(zhuǎn)換時(shí)會(huì)出現(xiàn)問(wèn)題。
在本文中,有時(shí)候使用的是標(biāo)準(zhǔn)字符集名稱,有時(shí)候又需要使用ORACLE字符集的名稱,因此希望大家明白兩者之間的對(duì)應(yīng)關(guān)系。
ORACLE數(shù)據(jù)庫(kù)有國(guó)家字符集(nationalcharacter set)與數(shù)據(jù)庫(kù)字符集(databasecharacterset)之分。兩者都是在創(chuàng)建數(shù)據(jù)庫(kù)時(shí)需要設(shè)置的。國(guó)家字符集主要是用于NCHAR、NVARCHAR、NCLOB類型的字段數(shù)據(jù),而數(shù)據(jù)庫(kù)字符集使用很廣泛,它用于:CHAR、VARCHAR、CLOB、LONG類型的字段數(shù)據(jù);表名、列名、PL/SQL中的變量名;輸入及保存在數(shù)據(jù)庫(kù)的SQL和PL/SQL的源碼。
ORACLE支持的Unicode字符集有以下幾種,下面的列表給出了字符集的名稱、對(duì)應(yīng)的數(shù)據(jù)庫(kù)版本范圍、采用的Unicode的版本。
字符集
對(duì)應(yīng)的數(shù)據(jù)庫(kù)版本范圍
Unicode的版本
AL24UTFFSS
7.2-8.1
1.1
UTF8
8.0-10g
2.1 (8.0-8.1.6)
3.0 (8.1.7-10g)
UTFE
8.0-10g
2.1 (8.0-8.1.6)
3.0 (8.1.7-10g)
AL32UTF8
9.0-10g
3.0 (9.0)
3.1 (9.2)
3.2 (10.1)
4.01(10.2)
AL16UTF16
9.0-10g
3.0 (9.0)
3.1 (9.2)
3.2(10.1)
4.01(10.2)
AL24UTFFSS:是ORACLE第一種支持Unicode的字符集,從7.2版本開始使用,但是它支持的Unicode版本為1.1,因此從9i開始就不支持此字符集了。
UTF8:是ORACLE從ORACLE8開始使用的屬于UTF-8編碼的字符集,從ORACLE8.0到ORACLE8.16,Unicode版本為2.1,而ORACLE817到10g,采用的Unicode標(biāo)準(zhǔn)為3.0
UTFE:用于EBCDIC碼平臺(tái)上的數(shù)據(jù)庫(kù)Unicode字符集。因此它屬于專用系統(tǒng)使用的字符集,其它屬性與UTF8基本相同。
AL32UTF8:是從ORACLE9開始使用的屬于UTF-8編碼的字符集,與UTF8相比,它采用的Unicode版本更新,在10g版本中使用的是Unicode4.01標(biāo)準(zhǔn),而UTF8因?yàn)榧嫒菪缘目紤],在10g版本中用的是Unicode3.0標(biāo)準(zhǔn)。
AL16UTF16:是ORACLE第一種采用UTF-16編碼方式的字符集,從ORACLE9開始使用,是作為缺省的國(guó)家字符集使用,它不能被用作數(shù)據(jù)庫(kù)的字符集。這是因?yàn)閿?shù)據(jù)庫(kù)的字符集決定了SQL與PL/SQL源碼的編碼方式,對(duì)于UTF-16這種使用固定的兩個(gè)字節(jié)來(lái)表示英文字母的編碼方案來(lái)說(shuō),確實(shí)不適于用作數(shù)據(jù)庫(kù)的字符集,ORACLE目前采用的數(shù)據(jù)庫(kù)字符集都是基
于ASCII或EBCDID作為子集的編碼方案。
從以上幾種字符集的介紹來(lái)看,Unicode字符集一般使用UTF8和AL32UTF8。如果數(shù)據(jù)庫(kù)版本都在9i及其以上,不需要考慮ORACLE8的數(shù)據(jù)庫(kù),建議使用AL32UTF8字符集,它采用的Unicode標(biāo)準(zhǔn)要比UTF8采用的Unicode標(biāo)準(zhǔn)更新,支持的字符也更多一些。如果要考慮ORACLE8數(shù)據(jù)庫(kù),建議使用UTF8字符集,它的兼容性好,在ORACLE8及8I數(shù)據(jù)庫(kù)上使用AL32UTF8字符集容易出現(xiàn)問(wèn)題。
3、如何選擇合適的數(shù)據(jù)庫(kù)字符集
前面我們介紹了字符集的一些概念,并對(duì)ORACLE數(shù)據(jù)庫(kù)的常用幾個(gè)字符集有了一些了解,下面就具體對(duì)數(shù)據(jù)庫(kù)字符集的選擇闡述一些個(gè)人的觀點(diǎn):
3.1、數(shù)據(jù)庫(kù)需要存儲(chǔ)的數(shù)據(jù)類型是字符集選擇的首要考慮目標(biāo)。
由于數(shù)據(jù)庫(kù)的主要功能在于存儲(chǔ)數(shù)據(jù),因此要保證數(shù)據(jù)的正確性。采用何種數(shù)據(jù)庫(kù)字符集需要看存儲(chǔ)數(shù)據(jù)是何種類型的。對(duì)于只存儲(chǔ)英文信息的數(shù)據(jù)庫(kù)等來(lái)說(shuō),一般采用US7ASCII或WE8ISO8859P1等單字節(jié)的字符集就比較合適,在性能和空間上也是最優(yōu),如果采用ZHS16GBK編碼,雖然可以使用,但從數(shù)據(jù)庫(kù)字符集本身的含義來(lái)說(shuō),屬于不恰當(dāng)?shù)倪x擇。同樣,存儲(chǔ)了中文信息的數(shù)據(jù)庫(kù),如果采用單字節(jié)的字符集,也是不合適的。在這種情況下,數(shù)據(jù)庫(kù)的字符集雖然是US7ASCII或WE8ISO8859P1編碼,但里面存儲(chǔ)的數(shù)據(jù)編碼實(shí)際上卻是另外的編碼格式,這種不一致的情況很容易引起問(wèn)題,建議不要這樣使用。ORACLE提供了很多種類的字符集供客戶選擇,就是要滿足各種文字不同的編碼需要。
3.2、字符集的選擇需要優(yōu)先考慮應(yīng)用程序的需要。
目前出于國(guó)際化的需要,軟件需要可以對(duì)不同的語(yǔ)言文字進(jìn)行處理,尤其一個(gè)系統(tǒng)中需要容納多種語(yǔ)言文字的時(shí)候,一般都會(huì)采用Unicode這樣的通用解決方案,即使會(huì)有一些空間和運(yùn)行效率的損失也是值得的。此時(shí)數(shù)據(jù)庫(kù)字符集建議可以采用AL32UTF8或UTF8編碼,一種比較理想的模式就是由程序負(fù)責(zé)編碼格式的轉(zhuǎn)換,而數(shù)據(jù)庫(kù)只提供一個(gè)透明的數(shù)據(jù)存儲(chǔ)。
上圖中,客戶在應(yīng)用程序中輸入數(shù)據(jù),此時(shí)數(shù)據(jù)的編碼格式是由客戶操作系統(tǒng)的區(qū)域及語(yǔ)言設(shè)置決定的,如在簡(jiǎn)體中文XP的環(huán)境下,輸入的中文編碼屬于GBK編碼。在客戶輸入結(jié)束后,程序首先判斷客戶的本地環(huán)境,并把編碼轉(zhuǎn)換成UNICODE,并通過(guò)NET傳送到服務(wù)器端。由于客戶端與服務(wù)器數(shù)據(jù)庫(kù)的字符集均為UTF8格式,ORACLE在傳送過(guò)程中不會(huì)進(jìn)行字符轉(zhuǎn)換,直接把數(shù)據(jù)按UTF8格式存儲(chǔ)到數(shù)據(jù)庫(kù)中。查詢時(shí)是一個(gè)反向的過(guò)程,應(yīng)用程序從數(shù)據(jù)庫(kù)中取出UTF8編碼的數(shù)據(jù),再由應(yīng)用程序根據(jù)客戶的本地環(huán)境,把UTF8編碼的數(shù)據(jù)轉(zhuǎn)換成客戶本地的編碼格式,最后把結(jié)果數(shù)據(jù)顯示給客戶。此方案的關(guān)鍵在于應(yīng)用程序要能很好的支持UNICODE編碼,編碼的轉(zhuǎn)換由應(yīng)用程序來(lái)負(fù)責(zé),數(shù)據(jù)庫(kù)只是提供了一個(gè)數(shù)據(jù)存儲(chǔ)功能。
對(duì)于部分程序來(lái)說(shuō),由于對(duì)UNICODE支持不夠,沒有提供編碼的轉(zhuǎn)換功能,則可以使用ORACLE提供的字符集轉(zhuǎn)換功能來(lái)實(shí)現(xiàn)同樣的目的。
從上圖可以看到,客戶在應(yīng)用程序中輸入數(shù)據(jù),此時(shí)數(shù)據(jù)的編碼格式是由客戶操作系統(tǒng)的區(qū)域及語(yǔ)言設(shè)置決定的,如在簡(jiǎn)體中文XP的環(huán)境下,輸入的中文編碼屬于GBK編碼。在客戶輸入結(jié)束后,程序直接把數(shù)據(jù)并通過(guò)NET傳送到服務(wù)器端。由于客戶端與服務(wù)器數(shù)據(jù)庫(kù)的字符集不一致,因此ORACLE會(huì)把客戶端的編碼轉(zhuǎn)換成UTF8格式,再把數(shù)據(jù)按UTF8格式存儲(chǔ)到數(shù)據(jù)庫(kù)中。這種方案的優(yōu)點(diǎn)就是程序可以不用支持UNICODE,由ORACLE數(shù)據(jù)庫(kù)自動(dòng)進(jìn)行轉(zhuǎn)換。由于數(shù)據(jù)庫(kù)的字符集為UTF8,是其它字符集的超集,因此在轉(zhuǎn)換過(guò)程中不會(huì)發(fā)生數(shù)據(jù)丟失的情況。對(duì)于英文的字符符號(hào),在UTF8中使用單字節(jié)存儲(chǔ),轉(zhuǎn)換的工作量很小,可以忽略,而對(duì)于一些亞洲字符集,在UTF8中一般需要兩到三個(gè)字節(jié)存儲(chǔ),需要的數(shù)據(jù)庫(kù)空間增加,而且轉(zhuǎn)換的工作量也相對(duì)大一些,性能會(huì)有一些損失。
4、與字符集相關(guān)的問(wèn)題分析
4.1、在UTF8環(huán)境下運(yùn)行SQL語(yǔ)句報(bào)錯(cuò)的問(wèn)題:
我們前面講過(guò),SQL*PLUS工具不提供編碼自動(dòng)轉(zhuǎn)換的功能,當(dāng)數(shù)據(jù)庫(kù)字符集為UTF8,客戶端的NLS_LANG如果也是UTF8,那么在SQL*PLUS中運(yùn)行SQL語(yǔ)句時(shí),語(yǔ)句全是英文,不會(huì)出現(xiàn)問(wèn)題,如果語(yǔ)句包含了中文或其它一些特殊字符,SQL語(yǔ)句運(yùn)行時(shí)就會(huì)報(bào)錯(cuò)。對(duì)于返回的含中文的結(jié)果,SQL*PLUS也會(huì)顯示亂碼。
造成此錯(cuò)誤的原因在于當(dāng)SQL語(yǔ)句中包含漢字等一些特殊字符時(shí),由于這些字符的編碼屬于GBK,ORACLE沒有進(jìn)行字符轉(zhuǎn)換,而是直接把SQL語(yǔ)句送到服務(wù)器上進(jìn)行解析。此時(shí)服務(wù)器的字符集是UTF8,因此它按UTF8編碼格式對(duì)SQL語(yǔ)句中GBK編碼的字符解析時(shí)就會(huì)產(chǎn)生錯(cuò)誤。如果把客戶端的NLS_LANG設(shè)置為本地環(huán)境的字符集,如ZHS16GBK,此時(shí)可以直接在SQL*PLUS中輸入包含中文的SQL語(yǔ)句,ORACLE在把SQL語(yǔ)句提交到服務(wù)器時(shí)會(huì)自動(dòng)轉(zhuǎn)換成UTF8編碼格式,因此SQL語(yǔ)句可以正常運(yùn)行。對(duì)于英文字母,由于它在UTF8中的編碼數(shù)值采用的還是ASCII的編碼數(shù)值,因此英文字母可以直接使用而不需要轉(zhuǎn)換,這就是如果SQL語(yǔ)句或輸出結(jié)果全是英文時(shí)不會(huì)出現(xiàn)錯(cuò)誤的原因。
正確的做法是先把需要運(yùn)行的SQL做成腳本文件,用代碼轉(zhuǎn)換工具把它轉(zhuǎn)換成UTF8編碼格式的文件,(注意!XP中的記事本是提供了代碼轉(zhuǎn)換功能的,可以在保存文件或選擇文件另存為的時(shí)候,彈出的對(duì)話框最后一項(xiàng),編碼,選擇UTF8,再保存,即可把文件轉(zhuǎn)換成UTF8編碼格式)。完成后用IE打開這個(gè)腳本,選擇編碼-》UTF8,觀察此時(shí)SQL腳本是否含有亂碼或“?”符號(hào)。如果沒有,說(shuō)明編碼格式已經(jīng)是UTF8了,此時(shí)在SQL*PLUS中運(yùn)行這個(gè)腳本就不會(huì)產(chǎn)生錯(cuò)誤了。運(yùn)行結(jié)束后,輸出的結(jié)果中如果包含中文,需要把結(jié)果SPOOL輸出到一個(gè)文件中,然后用代碼轉(zhuǎn)換工具把這個(gè)結(jié)果文件由UTF8轉(zhuǎn)換成本地編碼格式,再用寫字板打開,才能看到正常顯示的漢字。由于IE具有代碼轉(zhuǎn)換功能,因此也可以不用代碼轉(zhuǎn)換工具,直接在IE中打開輸出的結(jié)果文件,選擇UTF8編碼,也能正常顯示含中文的結(jié)果文件。
4.2、數(shù)據(jù)庫(kù)出現(xiàn)亂碼的問(wèn)題:
數(shù)據(jù)庫(kù)出現(xiàn)亂碼的問(wèn)題主要和客戶的本地化環(huán)境,客戶端NLS_LANG設(shè)置,服務(wù)器端的數(shù)據(jù)庫(kù)字符集設(shè)置這三者有關(guān),如果它們的設(shè)置不一致或者某個(gè)設(shè)置錯(cuò)誤,就會(huì)很容易出現(xiàn)亂碼,下面我們簡(jiǎn)要介紹以下幾種情況:
4.2.1、數(shù)據(jù)庫(kù)字符集設(shè)置不當(dāng)引起的亂碼:
這種錯(cuò)誤是由于數(shù)據(jù)庫(kù)字符集選擇錯(cuò)誤而引起的。我們前面講過(guò),由于每種語(yǔ)言文字都有一些自己特殊的字符,甚至一些字符的寫法都有不同的講究,因此即使對(duì)于歐美國(guó)家來(lái)說(shuō),也不是可以隨便通用的。像西歐的字符集標(biāo)準(zhǔn)ISO8859-1是8位編碼,它就有自己的一些特殊符號(hào),這些字符在US7ASCII編碼中找不到對(duì)應(yīng)的編碼值。如果需要使用這些特殊符號(hào),就必須選用本地字符集或者是它的超集的字符集。如果選用的字符集兩者都不是,那么在數(shù)據(jù)庫(kù)存儲(chǔ)的數(shù)據(jù)實(shí)際編碼和數(shù)據(jù)庫(kù)字符集的設(shè)置就產(chǎn)生了不一致,很容易產(chǎn)生亂碼。
例如:一個(gè)存儲(chǔ)簡(jiǎn)體中文字符的數(shù)據(jù)庫(kù),它的字符集選用了US7ASCII,當(dāng)它的客戶端NLS_LANG也選用US7ASCII時(shí),這個(gè)系統(tǒng)單獨(dú)使用是沒有問(wèn)題的,因?yàn)閮烧咴O(shè)置一致,因此ORACLE不會(huì)進(jìn)行字符集的轉(zhuǎn)換,客戶輸入的GBK碼被直接在數(shù)據(jù)庫(kù)中存儲(chǔ)起來(lái),當(dāng)查詢數(shù)據(jù)時(shí),實(shí)際客戶端取出來(lái)的數(shù)據(jù)也是GBK的編碼,因此顯示也是正常的。但當(dāng)其它的系統(tǒng)需要從這個(gè)數(shù)據(jù)庫(kù)取數(shù)據(jù),或者它的數(shù)據(jù)要EXP出來(lái),IMP到其它數(shù)據(jù)庫(kù)時(shí),問(wèn)題就會(huì)開始出現(xiàn)了。其它系統(tǒng)的字符集一般是ZHS16GBK,或者其它系統(tǒng)客戶端的NLS_LANG設(shè)置為ZHS16GBK,此時(shí)必然會(huì)產(chǎn)生字符集的轉(zhuǎn)換。雖然數(shù)據(jù)庫(kù)字符集設(shè)置為US7ASCII,但我們知道,實(shí)際存儲(chǔ)的數(shù)據(jù)編碼是ZHS16GBK的??上RACLE不會(huì)知道,它會(huì)把存儲(chǔ)的ZHS16GBK編碼數(shù)據(jù)當(dāng)作US7ASCII編碼的數(shù)據(jù),按照US7ASCII轉(zhuǎn)換成ZHS16GBK的轉(zhuǎn)換算法進(jìn)行轉(zhuǎn)換,可以想象,這種情況下,亂碼的產(chǎn)生是必然的。
結(jié)論是:如果要選擇一個(gè)非本地環(huán)境的數(shù)據(jù)庫(kù)字符集,在不需要考慮和其它系統(tǒng)的數(shù)據(jù)接口和數(shù)據(jù)交換的情況下,或者你有面對(duì)這種麻煩的心理準(zhǔn)備的話,那么這種選擇是可行的,但是別忘了數(shù)據(jù)庫(kù)字符集一定要和客戶端的NLS_LANG保持一致。
4.2.2、數(shù)據(jù)庫(kù)字符集與客戶端NLS_LANG設(shè)置不同引起的亂碼:
由于ORACLE提供了字符集的轉(zhuǎn)換功能,因此數(shù)據(jù)庫(kù)字符集與客戶端NLS_LANG設(shè)置不同是可以接受的,前提條件是數(shù)據(jù)庫(kù)的字符集必須是客戶端NLS_LANG設(shè)置字符集的超集,那么由于客戶端使用的字符是屬于數(shù)據(jù)庫(kù)字符集中的一部分,因此不會(huì)產(chǎn)生轉(zhuǎn)換時(shí)數(shù)據(jù)丟失及亂碼的情況。
例如:對(duì)于一個(gè)需要存儲(chǔ)簡(jiǎn)體文信息的數(shù)據(jù)庫(kù)來(lái)說(shuō),它的字符集設(shè)置和客戶端NLS_LANG設(shè)置一般可以使用ZHS16GBK編碼。但是如果數(shù)據(jù)庫(kù)字符集選用了UTF8的話,也是可以的,因?yàn)閆HS16GBK編碼屬于UTF8的子集。ORACLE在數(shù)據(jù)庫(kù)與客戶端進(jìn)行數(shù)據(jù)交換時(shí)自動(dòng)進(jìn)行編碼的轉(zhuǎn)換,在數(shù)據(jù)庫(kù)中實(shí)際存儲(chǔ)的也是UTF8編碼的數(shù)據(jù)。此時(shí)其它數(shù)據(jù)庫(kù)和此數(shù)據(jù)庫(kù)也可以正常的進(jìn)行數(shù)據(jù)交換,因?yàn)镺RACLE會(huì)自動(dòng)進(jìn)行數(shù)據(jù)的轉(zhuǎn)換。在實(shí)際使用中,遇到過(guò)繁體XP的字符集ZHT16MSWIN950轉(zhuǎn)換成AL32UTF8字符集時(shí),一些特殊的字符和個(gè)別冷僻的漢字會(huì)變成亂碼。后來(lái)證實(shí)是XP需要安裝一個(gè)字庫(kù)補(bǔ)丁軟件,最后順利解決此問(wèn)題。
結(jié)論:對(duì)于數(shù)據(jù)庫(kù)字符集為UTF8,而客戶端采用本地字符集的情況,最好進(jìn)行測(cè)試驗(yàn)證,因?yàn)閁NICODE標(biāo)準(zhǔn)本身發(fā)展很快,一些客戶端的操作系統(tǒng)對(duì)UNICODE標(biāo)準(zhǔn)支持的力度不一致,有些操作系統(tǒng)支持不好,有些特殊字符在轉(zhuǎn)換后會(huì)產(chǎn)生亂碼。由于這個(gè)話題已經(jīng)超出了本文的范疇,在此就不詳細(xì)討論了。
4.2.3、客戶端NLS_LANG與本地化環(huán)境不同引起的亂碼:
一般情況下,客戶端NLS_LANG與本地化環(huán)境采用了不同的字符集會(huì)出現(xiàn)亂碼,除非本地化環(huán)境的字符集是客戶端NLS_LANG設(shè)置字符集的子集。如果把客戶端NLS_LANG設(shè)置為UTF8就屬于這種情況,由于目前還沒有可以直接使用UNICODE字符集的操作系統(tǒng),因此客戶本地化環(huán)境使用的字符集只能是某種語(yǔ)言支持的字符集,它屬于UTF8的子集。下面我們就著重討論這種情況。
雖然目前WINDOWS的內(nèi)核是支持UNICODE的,但是WINDOWS并不支持直接顯示UNICODE編碼的字符,而且它并不知道目前的字符采用了何種字符集,所以默認(rèn)情況下,它使用缺省的代碼頁(yè)來(lái)解釋字符。因此,對(duì)于其它類型的編碼,需要先進(jìn)行轉(zhuǎn)換,變成系統(tǒng)目前的缺省代碼頁(yè)支持的字符集才能正常使用。
WINDOWS中的缺省代碼頁(yè)是由控制面板設(shè)置中的語(yǔ)言及區(qū)域的選擇所決定的,屬于客戶本地化的環(huán)境設(shè)置。簡(jiǎn)體中文WINDOWS的字符編碼就是GBK,它的缺省代碼頁(yè)是936。對(duì)于其它非WINDOWS的操作系統(tǒng),我們可以把它們目前缺省使用的字符集作為用戶的本地化環(huán)境設(shè)置。另外,我們使用的大部分工具,如寫字板,SQL*PLUS等,它們沒有提供編碼轉(zhuǎn)換功能,因此在客戶端直接輸入或查詢數(shù)據(jù)往往都會(huì)遇到亂碼的問(wèn)題,必須由應(yīng)用程序或一些工具去做編碼的轉(zhuǎn)換,才能保證正常的使用。比如SQL*PLUS遇到的問(wèn)題,我們?cè)?.1節(jié)中已經(jīng)進(jìn)行了詳細(xì)的論述。
5、最后的結(jié)論及建議:
以上不厭其煩的列舉了種種因?yàn)檫x用了不恰當(dāng)?shù)臄?shù)據(jù)庫(kù)字符集而出現(xiàn)的問(wèn)題,最后總結(jié)歸納起來(lái),以下幾點(diǎn)就是我個(gè)人的建議了:
1)一般情況下,建議優(yōu)先考慮客戶的本地化環(huán)境,選用本地通用的字符集作為數(shù)據(jù)庫(kù)的字符集和客戶端NLS_LANG的設(shè)置,使得數(shù)據(jù)庫(kù)、客戶端NLS_LANG、客戶端操作系統(tǒng)三者的字符集可以完全兼容,這樣出現(xiàn)的問(wèn)題和麻煩最少。就簡(jiǎn)體中文而言,目前最常用的字符集是ZHS16GBK,建議大家選用。
2)如果系統(tǒng)需要支持多語(yǔ)言,采用了UNICODE標(biāo)準(zhǔn),那么ORACLE數(shù)據(jù)庫(kù)字符集在版本9以上可以選用AL32UTF8,如果涉及到ORACLE8及8i的數(shù)據(jù)庫(kù),字符集可以選用UTF8。
3)如果應(yīng)用程序完全支持UNICODE,可以根據(jù)客戶的本地化環(huán)境自動(dòng)轉(zhuǎn)換編碼,則客戶端的NLS_LANG可以設(shè)置成和數(shù)據(jù)庫(kù)服務(wù)器端字符集完全一致。如果應(yīng)用程序不能自動(dòng)進(jìn)行編碼的轉(zhuǎn)換或需要在客戶端進(jìn)行一些管理維護(hù)活動(dòng),則建議把客戶端的NLS_LANG設(shè)置成本地環(huán)境使用的字符集,由ORACLE來(lái)進(jìn)行編碼的轉(zhuǎn)換工作。此時(shí)需要對(duì)客戶端的操作系統(tǒng)進(jìn)行驗(yàn)證測(cè)試,因?yàn)槟壳案鱾€(gè)操作系統(tǒng)對(duì)UNICODE標(biāo)準(zhǔn)支持的程度不同,有時(shí)會(huì)出現(xiàn)一些特殊字符轉(zhuǎn)換不正常的情況。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
設(shè)置ORACLE客戶端字符集
struts原理與實(shí)踐(4)
關(guān)于字符集和亂碼的思考
Oracle數(shù)據(jù)庫(kù)中文亂碼問(wèn)題
搞懂oracle字符集 - Oracle數(shù)據(jù)庫(kù)管理 - ITPUB論壇 - 澳信傳媒旗下專...
循序漸進(jìn)Oracle:數(shù)據(jù)庫(kù)的字符集和字符集文件
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服