Oracle 伺服器端用戶端字元集設定對應用程式的影響

來源:互聯網
上載者:User

在Oracle資料庫中如果伺服器端用戶端字元集設定不當,就會造成儲存到資料庫的資料不會正常儲存,或者資料庫裡的資料在用戶端不能正常顯示,出現爛碼的現象。

尤其是以SQLPLUS操作的時候,由於SQLPLUS的"bug"(或者叫使用者使用不當),會造成一些看起來不’正常‘的爛碼現象,下面來解釋一下:

1,查看資料庫的字元集:

SQL> select * from database_properties where property_name='NLS_CHARACTERSET
PROPERTY_NAME                  PROPERTY_VALUE                 DESCRIPTION
------------------------------ ------------------------------ --------------
NLS_CHARACTERSET               UTF8                           Character set

2,用戶端的作業系統環境為中文,在預設的設定下通過sqlplus插入一條資料後提交:

SQL> insert into yorker.test values('中文','SQLPLUS default');

這時候在插入的時候,用戶端的字元,比如’中文 ‘是以作業系統的編碼方式(比如ZHS16GBK)編碼後發送到Oracle伺服器端,Oracle在存入資料庫的時候轉換成

UTF8儲存。

3,以預設的方式開啟SQLPLUS查詢

SQL> select value,nlstype,dump(value) dv from yorker.test;

VALUE                NLSTYPE              DV
-------------------- -------------------- ------------------------------------
中文                 SQLPLUS default      Typ=1 Len=6: 228,184,173,230,150,135

顯示正常,Oracle伺服器讀取欄位的二進位內容,根據用戶端的編碼,轉換成’中文‘在用戶端編碼對應的編碼內容發送到用戶端。

dump(value)就是伺服器端’中文‘的16進位編碼的內容,utf8的內容形式。

4在用戶端設定 nls_lang後進入SQLPLUS

C:\>set nls_lang=american_america.utf8

C:\>sqlplus sys/sys as sysdba

SQL> select value,nlstype,dump(value) dv from yorker.test;
VALUE                          NLSTYPE                        DV
------------------------------ ------------------------------ --------------------------------------
涓枃                           SQLPLUS default                Typ=1 Len=6: 228,184,173,230,150,135

查詢到的結果如上出現爛碼,原因是SQLPLUS在查詢的時候,告訴了Oracle伺服器用戶端的編碼為UTF8,這時候Oracle不做轉換把以UTF8編碼的內容’中文‘發送到

SQLPLUS,而SQLPLUS卻以作業系統的編碼(比如ZHS16GBK)去識別這個內容,結果就是不能識別的爛碼。set nls_lang=american_america.utf8後不以utf8編碼的形式來識別字元是爛碼的原因,Oracle儲存的內容實施正確的,是utf8的正確形式,在別的用戶端仍然可以正確顯示(如預設的SQLPLUS,JAVA應用程式等)

5,在用戶端設定為utf8的sqlplus插入資料

C:\>set nls_lang=american_america.utf8

C:\>sqlplus sys/sys as sysdba

SQL> insert into yorker.test values('中文','SQLPLUS UTF8');

這時候發生了一個“錯誤”,’中文‘是以作業系統的ZHS16GBK的編碼格式發送到Oracle伺服器的,同時sqlplus又告訴了伺服器發送的編碼是utf8,所以Oracle伺服器不做轉換把ZHS16GBK編碼格式的’中文‘儲存到了伺服器的磁碟上,但是Oracle認為這個編碼是utf8,下次如果別的用戶端,不是utf8的用戶端在查詢的時候,Oracle做轉換,這時候會轉換不正確,因為ZHS16GBK編碼格式的’中文‘在utf8裡可能找不到對應的字元或者是不同的字元。

5,在用戶端設定為utf8的sqlplus查詢資料

C:\>set nls_lang=american_america.utf8

C:\>sqlplus sys/sys as sysdba

SQL> select value,nlstype,dump(value) dv from yorker.test;
VALUE                          NLSTYPE                        DV
------------------------------ ------------------------------ ---------------------------------------
中文                            SQLPLUS UTF8                   Typ=1 Len=4: 214,208,206,196

剛才以utf8的編碼顯示正確,這是因為“錯上加錯”就對了:sqlplus告訴Oracle用戶端是utf8,Oracle不做轉換直接把資料庫儲存的二進位內容發到了用戶端,由於和儲存的時候的內容是一致的,所以仍然能夠正確顯示。

這時候如果用戶端設定的nls_lang不是和伺服器的utf8一樣,伺服器在發送到用戶端之前做了一個’轉換‘,顯示就不對了,如下例:

??                 SQLPLUS UTF8         Typ=1 Len=4: 214,208,206,196

在一個JAVA的用戶端應用程式中

private static void testEncoding() throws SQLException {
Connection conn = NONXADBUtil.getConnection("ORCL");
PreparedStatement sta = conn.prepareStatement("select value,nlstype,dump(value) dv from yorker.test");
ResultSet rset = sta.executeQuery();
while (rset.next()) {
System.out.println(rset.getString(1) + "   " + rset.getString(2) + "  "+ rset.getString(3) );
}
rset.close();
sta.close();
conn.close();
}

顯示的內容如下:

中文   SQLPLUS default  Typ=1 Len=6: 228,184,173,230,150,135
��   SQLPLUS UTF8  Typ=1 Len=4: 214,208,206,196

發生爛碼的原因是,Oracle將’中文‘(214,208,206,196)以utf8的編碼格式識別,識別出錯,轉換成JAVA客服端想要的字元這一步更是’錯爛‘的完成的。

*在匯入匯出的時候遵循的原則,

匯出時:用戶端設定nls_lang和資料來源的資料庫一致。

匯入時:用戶端設定為匯出時設定的編碼,如果匯出是由別人完成,一定要知道匯出時候設定的編碼。匯入時候要設定成和匯出時候一致。

匯出的檔案第2,第3個位元組記錄的是該檔案的編碼,用ultraedir可以查看,是16進位。比方說為03 54,先轉成10進位得到

select to_number('0354','xxxx') from dual 得到 852,在可以通過 select nls_charset_name(852) from dual 知道是ZHS16GBK

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.