oracle 字符集亂碼本質驗證(2)

發表于:2014-03-27來源:Csdn作者:蘑菇丁點擊數: 標簽:oracle
數據庫中存儲, 沒有錯, 但是iterm2將UTF8的碼按照GB2312來解釋, 并打在屏幕上, 明顯編碼長度是有問題的. 由此可以得出結論為:若數據庫的字符集是ZHS16GBK,

  數據庫中存儲, 沒有錯, 但是iterm2將UTF8的碼按照GB2312來解釋, 并打在屏幕上, 明顯編碼長度是有問題的.

  由此可以得出結論為:若數據庫的字符集是ZHS16GBK, 那么Oracle會根據內部的MAP,按UTF8截取客戶端發來的字符串, 轉換成ZHS16GBK,因此顯示的結果是正常的,但是存入的數據編碼卻變了。

  實驗 2.

  ~~~~~~~~~~~~~

  a) 設置個人工具的字符集為 GB2312

  b) 設置NLS_LANG=american_america.AL32UTF8

  [oracle@hxy ~]$ export NLS_LANG=american_america.AL32UTF8

  [oracle@hxy ~]$ sqlplus / as sysdba

  SQL*Plus: Release 10.2.0.1.0 - Production on Wed Mar 26 10:57:12 2014

  Copyright (c) 1982, 2005, Oracle. All rights reserved.

  Connected to:

  Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit Production

  With the Partitioning, OLAP and Data Mining options

  SQL> desc t2

  Name Null? Type

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

  NLS_LANG VARCHAR2(20)

  INPUT_CHARSET VARCHAR2(20)

  C1 VARCHAR2(20)

  SQL> insert into t2 values('UTF8','ZHS16GBK','中國' );

  SQL> select c1,dump(c1,16) from t2;

  SQL> insert into t2 values('UTF8','ZHS16GBK,'中國' );

  SQL> commit;

  Commit complete.

  SQL> select * from t2;

  NLS_LANG INPUT_CHARSET C1

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

  UTF8 ZHS16GBK 錛??

  ZHS16GBK ZHS16GBK 涓?浗

  ZHS16GBK UTF8 娑擃厼嫻?

  全部變成亂碼了。

  SQL> select c1, input_charset,dump(c1,16) from t2;

  C1 INPUT_CHARSET DUMP(C1,16)

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

  錛?? ZHS16GBK Typ=1 Len=4: a3,bf,3f,3f

  涓?浗 ZHS16GBK Typ=1 Len=4: d6,d0,b9,fa

  娑擃厼嫻? UTF8 Typ=1 Len=6: e4,b8,ad,e5,9b,bd

  上面標黃色的編碼明顯是錯誤的,這種情況叫garbage-in--garbage-out, 這是最有欺騙性的一種設置.

  將個人工具的字符集修改回與NLS_LANG相同的設置---UTF8就會出現問題.

  SQL> select c1, input_charset,dump(c1,16) from t2;

  C1 INPUT_CHARSET DUMP(C1,16)

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

  ??? <<=== ZHS16GBK Typ=1 Len=4: a3,bf,3f,3f

  中國 ZHS16GBK Typ=1 Len=4: d6,d0,b9,fa

  涓?浗 UTF8 Typ=1 Len=6: e4,b8,ad,e5,9b,bd

  此編碼是不能顯示正常,出現了亂碼行為,這就是一種欺騙性的,日常工作中經常容易發生,但是很難發現問題,這個一定要小心。

  實驗 3.

  個人工具: UTF8

  NLS_LANG: american_america.UTF8

  SQL>insert into t2 values('UTF8','UTF8','中國');

  SQL> set line 200

  SQL> select c1, input_charset,dump(c1,16) from t2;

  C1 INPUT_CHARSET DUMP(C1,16)

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

  ??? ZHS16GBK Typ=1 Len=4: a3,bf,3f,3f

  中國 UTF8 Typ=1 Len=4: d6,d0,b9,fa

  中國 ZHS16GBK Typ=1 Len=4: d6,d0,b9,fa

  涓?浗 UTF8 Typ=1 Len=6: e4,b8,ad,e5,9b,bd

  可以看到只要個人工具的字符集和nls_lang的字符集是是一致的,并且數據庫字符集和客戶端字符集可以相互轉換就不會出現亂碼,

  不出現亂碼并不是之前所說的客戶端字符集并一定是和數據庫字符集一致。

  3. 關于export/import的字符集問題.

  a) 導出時NLS_LANG的設置, 決定存地DMP文件中的字符集.

  b) 導入時的字符集轉換情況分三步:

  b.1 讀取DMP文件的字符集設置, 一般存在文件的2~3個字節. 10g以前, 可以通過更改這兩個字節的值, 來修改字符集. 但是, 10G,11G以后, 字符集還存在于其它地方, 基本沒有修改的可能.

  b.2 將DMP文件里的字符轉換成, import時NLS_LANG所設置的字符集.

  b.3 導入時, 將字符從 NLS_LANG轉為數據庫字集.

  $ export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK

  $ exp \"/ as sysdba\" file=demo.dmp tables=t2;

  Export: Release 11.2.0.4.0 - Production on Sun Mar 23 19:50:24 2014

  Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.

  Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

  With the Partitioning, OLAP, Data Mining and Real Application Testing options

  Export done in ZHS16GBK character set and AL16UTF16 NCHAR character set

  server uses AL32UTF8 character set (possible charset conversion)

原文轉自:http://blog.csdn.net/haoxiaoyan/article/details/22165465

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97