小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

數(shù)據(jù)庫(kù)出現(xiàn)亂碼的原因和解決辦法

 昵稱19451 2007-02-08
數(shù)據(jù)庫(kù)出現(xiàn)亂碼的原因和解決辦法

 

 

SQL*Plusinsert進(jìn)的都是中文的,為什么一存入服務(wù)器后,再select出的就是???”

 

有的時(shí)候,服務(wù)器數(shù)據(jù)先導(dǎo)出,重裝服務(wù)器,再導(dǎo)入數(shù)據(jù),結(jié)果,發(fā)生數(shù)據(jù)查詢成???”

 

… …

這些問(wèn)題,一般,是因?yàn)樽址O(shè)置不對(duì)照成的。

 

很久以來(lái),字符集一直是困擾著眾多Oracle愛(ài)好者的問(wèn)題,筆者從事Oracle數(shù)據(jù)庫(kù)管理和應(yīng)用已經(jīng)幾年了,經(jīng)常接到客戶的類似上面提到的有關(guān)數(shù)據(jù)庫(kù)字符集的“告急”和“求救”,今天,就這個(gè)問(wèn)題打算做一些分析和探討。

首先,我們要明確什么是字符集?字符集是一個(gè)字節(jié)數(shù)據(jù)的解釋的符號(hào)集合,有大小之分,有相互的包括關(guān)系,us7ascii就是zhs16gbk的子集,us7asciizhs16gbk不會(huì)有數(shù)據(jù)解釋上的問(wèn)題,不會(huì)有數(shù)據(jù)丟失,oracle對(duì)這種問(wèn)題也要求從子集到超集的導(dǎo)出受支持,反之不行。在所有的字符集中utf8應(yīng)該是最大,因?yàn)樗?span lang=EN>unicode,雙字節(jié)保存字符(也因此在存儲(chǔ)空間上占用更多)。

其次,一旦數(shù)據(jù)庫(kù)創(chuàng)建后,數(shù)據(jù)庫(kù)的字符集是不能改變的。因此,在設(shè)計(jì)和安裝之初考慮使用哪一種字符集是十分重要的。數(shù)據(jù)庫(kù)字符集應(yīng)該是操作系統(tǒng)本地字符集的一個(gè)超集。存取數(shù)據(jù)庫(kù)的客戶使用的字符集將決定選擇哪一個(gè)超集,即數(shù)據(jù)庫(kù)字符集應(yīng)該是所有客戶字符集的超集。

在實(shí)際的應(yīng)用中,和字符集問(wèn)題最相關(guān)的恐怕就是exp/imp了。在做exp/imp是,如果client servernls_lang設(shè)置是一樣的,一般就沒(méi)有問(wèn)題。但是,要在兩個(gè)不同字符集的系統(tǒng)之間導(dǎo)數(shù)據(jù)就經(jīng)常會(huì)有這樣那樣的問(wèn)題,如,導(dǎo)出時(shí)數(shù)據(jù)庫(kù)的顯示正常,是中文,當(dāng)導(dǎo)入到其他系統(tǒng)時(shí),就成了亂碼,這也是一類常見(jiàn)問(wèn)題。對(duì)于這個(gè)問(wèn)題,有一個(gè)常用的轉(zhuǎn)換方法,首先用一個(gè)二進(jìn)制編輯器(如,UltraEdit)察看到出文件(DMP文件)的第二和第三字節(jié),這兩個(gè)字節(jié)的內(nèi)容是服務(wù)器端的字符集,比如0001,那么在數(shù)據(jù)庫(kù)中查找出它代表的字符集:

bepone> sqlplus internal

SQL> select nls_charset_name(to_number(‘0001‘,‘xxxx‘)) from dual;

NLS_CHARSET_NAME(TO_NUMBER(‘0001‘,‘XXXX‘)

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

US7ASCII

SQL>

 

然后,如果在導(dǎo)入數(shù)據(jù)時(shí)需要修改為ZHS16GBK,我們就需要知道如何修改這兩個(gè)字節(jié)才能讓他們和ZHS16GBK對(duì)應(yīng):

bepone> sqlplus internal

SQL> SQL> select to_char(nls_charset_id(‘ZHS16GBK‘), ‘xxxx‘) from dual;

TO_CH

-----

  354

SQL>

因此,可以將這兩個(gè)字節(jié)手工修改為0354(不足4位時(shí)前面補(bǔ)0),然后就可以正常導(dǎo)入數(shù)據(jù)了。

 

 

現(xiàn)在,為了進(jìn)一步搞清楚字符集的秘密,介紹一些與字符集有關(guān)的NLS_LANG參數(shù),

NLS_LANG格式:

NLS_LANG = language_territory.charset

有三個(gè)組成部分(語(yǔ)言、地域和字符集),每個(gè)組成成分控制了NLS子集的特性。其中:language 指定服務(wù)器消息的語(yǔ)言。

 territory 指定服務(wù)器的日期和數(shù)字格式。

 Charset 指定字符集

例如:

AMERICAN_AMERICA.US7SCII

AMERICAN _ AMERICA. ZHS16GBK

 

還有一些子集可以更明確定義NLS_LANG參數(shù):

DICT.BASE                   數(shù)據(jù)字典基本表版本                                              

DBTIMEZONE                  數(shù)據(jù)庫(kù)時(shí)區(qū)                                                                   

NLS_LANGUAGE                語(yǔ)言                                                                        

NLS_TERRITORY               地域                                                                      

NLS_CURRENCY                本地貨幣字符                                                                  

NLS_ISO_CURRENCY            ISO貨幣字符                                                                

NLS_NUMERIC_CHARACTERS      小數(shù)字符和組分隔開

NLS_CHARACTERSET            字符集                                                                  

NLS_CALENDAR                日歷系統(tǒng)                                                                 

NLS_DATE_FORMAT             缺省的日期格式                                                                     

NLS_DATE_LANGUAGE           缺省的日期語(yǔ)言                                                                    

NLS_SORT                    字符排序序列                                                           

NLS_TIME_FORMAT             時(shí)間格式                                                                    

NLS_TIMESTAMP_FORMAT        時(shí)間戳格式

。。。 。。。

                                                             

通過(guò)props$動(dòng)態(tài)性能視圖,我們可以查看數(shù)據(jù)庫(kù)的字符集信息:

$> sqlplus internal

SQL> desc props$

Name     Type           Nullable Default Comments

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

NAME     VARCHAR2(30)                            

VALUE$   VARCHAR2(4000) Y                        

COMMENT$ VARCHAR2(4000) Y  

                     

SQL> set arraysize 1

SQL> col value$ format a40

SQL> select name,value$ from props$ where name=‘NLS_CHARACTERSET‘;

NAME                           VALUE$

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

NLS_CHARACTERSET               ZHS16GBK

 

SQL> select * from sys.props$;                             

                                                            

NAME                           VALUE$                      

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

DICT.BASE                 2                                

DBTIMEZONE                0:00                             

NLS_LANGUAGE              AMERICAN                         

NLS_TERRITORY             AMERICA                          

NLS_CURRENCY              $                                

NLS_ISO_CURRENCY          AMERICA                          

NLS_NUMERIC_CHARACTERS    .,                               

NLS_CHARACTERSET          ZHS16GBK                         

NLS_CALENDAR              GREGORIAN                        

NLS_DATE_FORMAT           DD-MON-RR                        

NLS_DATE_LANGUAGE         AMERICAN                         

NLS_SORT                  BINARY                           

NLS_TIME_FORMAT           HH.MI.SSXFF AM                   

NLS_TIMESTAMP_FORMAT      DD-MON-RR HH.MI.SSXFF AM         

NLS_TIME_TZ_FORMAT        HH.MI.SSXFF AM TZH:TZM           

NLS_TIMESTAMP_TZ_FORMAT   DD-MON-RR HH.MI.SSXFF AM TZH:TZM 

NLS_DUAL_CURRENCY         $                                

NLS_COMP                  BINARY                           

NLS_NCHAR_CHARACTERSET    ZHS16GBK                          

NLS_RDBMS_VERSION         8.1.6.0.0                        

                                                           

NAME                      VALUE$                           

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

GLOBAL_DB_NAME            SCPDB1                           

EXPORT_VIEWS_VERSION           8                           

                                                           

22 rows selected                                           

                                                            

SQL>

從接過(guò)可以看出:

NLS_LANG = AMERICAN _ AMERICA. ZHS16GBK

                                                    

 

雖然,數(shù)據(jù)庫(kù)的字符集是在create database的時(shí)候指定的,以后不允許改變,但在一個(gè)已經(jīng)建立好的數(shù)據(jù)庫(kù)上,我們可以通過(guò)修改SYS.PROPS$來(lái)修改主要是對(duì)應(yīng)客戶端的顯示,與存儲(chǔ)無(wú)關(guān)。

 

如:

 

SQL> conn / as sysdba

Connected.

SQL> SQL> select * from sys.props$                      

  2  WHERE NAME=‘NLS_LANGUAGE‘;                    

                                                   

NAME                           VALUE$              

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

NLS_LANGUAGE                   AMERICAN

                                                   

SQL>                                               

SQL> UPDATE sys.PROPS$ SET VALUE$=‘SIMPLIFIED CHINESE‘

2  WHERE NAME=‘NLS_LANGUAGE‘;

1 row updated

                                                    

SQL>                                               

SQL> select * from sys.props$                      

  2  WHERE NAME=‘NLS_LANGUAGE‘;                    

NAME                           VALUE$              

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

NLS_LANGUAGE                   SIMPLIFIED CHINESE  

                                                   

SQL>                                                 

 

 

通常我們常見(jiàn)問(wèn)題的原因,基本上可以分為三種:

1.     服務(wù)器指定字符集與客戶字符集不同,而與加載數(shù)據(jù)字符集一致。

解決方法:對(duì)于這種情況,只需要設(shè)置客戶端字符集與服務(wù)器端字符集一致就可以了,具體操作如下:

§         察看當(dāng)前字符集:

SQL> select * from sys.props$           

  2  WHERE NAME=‘NLS_CHARACTERSET‘;     

NAME                           VALUE$   

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

NLS_CHARACTERSET               ZHS16GBK 

SQL>                                        

可以看出,現(xiàn)在服務(wù)器端ORACLE數(shù)據(jù)庫(kù)的字符集為‘ZHS16GBK‘

 

§         根據(jù)服務(wù)器的字符集在客戶端坐相應(yīng)的配置或者安裝ORACLE的客戶端軟件時(shí)指定:

如過(guò)還沒(méi)安裝客戶端,那么在安裝客戶端時(shí),指定與服務(wù)器相吻合的字符集即可;如果已經(jīng)安裝好了客戶端,并且客戶端為 sql*net 2.0 以下版本,進(jìn)入Windows的系統(tǒng)目錄,編輯oracle.ini文件,用US7ASCII替換原字符集,重新啟動(dòng)計(jì)算機(jī),設(shè)置生效;否則,如果,客戶端為 sql*net 2.0 以上版本,在WIN98 下 運(yùn) 行REGEDIT,第一步選HKEY_LOCAL_MACHINE,第二步選擇SOFTWARE, 第三步選擇 ORACLE, 第四步選擇 NLS_LANG, 鍵 入 與服 務(wù) 器 端 相 同 的 字 符 集

(本例為:HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\NLS_LANG AMERICAN _ AMERICA. ZHS16GBK)。

如過(guò)是UNIX客戶端,則:

SQL> conn / as sysdba

Connected.

SQL> SQL> UPDATE sys.PROPS$ SET VALUE$=‘SIMPLIFIED CHINESE‘

  2  WHERE NAME=‘NLS_LANGUAGE‘;

1 row updated

SQL> COMMIT;

Commit complete

SQL>

 

 

 

2.     服務(wù)器指定字符集與客戶字符集相同,與加載數(shù)據(jù)字符集不一致。

解決方法:強(qiáng)制加載數(shù)據(jù)字符集與服務(wù)器端字符集一致。要做到這一點(diǎn),可以通過(guò)重新創(chuàng)建數(shù)據(jù)庫(kù),并選擇與原卸出數(shù)據(jù)一致的字符集,然后IMP數(shù)據(jù),這種情況僅僅適用于空庫(kù)和具有同一種字符集的數(shù)據(jù)。

解決這類問(wèn)題,也可以先將數(shù)據(jù)加載到具有相同字符集的服務(wù)器上,然后用轉(zhuǎn)換工具卸出為foxbase 格式或access格式數(shù)據(jù)庫(kù),再用轉(zhuǎn)換工具轉(zhuǎn)入到不同字符集的ORACLE數(shù)據(jù)庫(kù)中,這樣就避免了ORACLE字符集的困擾。目前數(shù)據(jù)庫(kù)格式轉(zhuǎn)換的工具很多,power builder5.0以上版本提供的pipeline,Microsoft Access數(shù)據(jù)庫(kù)提供的數(shù)據(jù)導(dǎo)入/導(dǎo)出功能等。

 

3.     服務(wù)器指定字符集與客戶字符集不同,與輸入數(shù)據(jù)字符集不一致。

對(duì)于這種情況,目前為止的都還沒(méi)有太好的解決方法。

 

通過(guò)上面的了解,我們知道,導(dǎo)致在后期使用數(shù)據(jù)庫(kù)時(shí)出現(xiàn)種種關(guān)于字符記得問(wèn)題,多半是由于在數(shù)據(jù)庫(kù)設(shè)計(jì)、安裝指出沒(méi)有很好的考慮到以后的需要,所以,我們完全可以通過(guò)在服務(wù)器上和客戶端使用相同的字符集來(lái)避免有此類問(wèn)題引出的麻煩。

 

 

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多