欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

字符集問題的初步探討(六)-亂碼的產生

系統 2006 0

最后我們來討論一下亂碼的產生。

通常在我們的現實環境中,存在3個字符集設置。

第一: 客戶端應用字符集(Client Application Character Set)

第二: 客戶端NLS_LANG參數設置

第三: 服務器端,數據庫字符集(Character Set)設置

我們說,一個字符在客戶端應用(比如SQLPLUS,CMD,NOTEPAD等)中以怎樣的字符顯示取決于客戶端操作系統,客戶端能夠顯示怎樣的字符,
我們就可以在應用中錄入這些字符,至于這些字符能否在數據庫中正常存儲,就和另外的兩個字符集設置緊密相關了。

在傳輸過程中,客戶端NLS_LANG主要用于進行轉換判斷

如果NLS_LANG等于數據庫字符集,則不進行任何轉換直接把字符插入數據庫

如果不同則進行轉換,轉換主要有兩個任務

  • 如果存在對應關系,則把相應二進制編碼經過映射后(這一步映射以后,所代表的字符可能發生轉換)傳遞給數據庫
  • 如果不存在對應關系,則傳遞一個替換字符(很多平臺就是?)

數據庫字符集,在和客戶端NLS_LANG不同時,會把經過NLS_LANG轉換的字符進行進一步處理

  • 對于?(即不存在對應關系的字符)直接以?形式存放入數據庫
  • 對于其他字符,在NLS_LANG和數據庫字符集之間進行轉換后存入。

以下我們來看一下最為常見的字符集及亂碼的產生:

1.當NLS_LANG字符集與數據庫字符集不同,同時NLS_LANG不同于Server端字符集設置

在這種情況下,存在兩種可能:

  • 客戶端輸入的字符在NLS_LANG中沒有對應的字符,這時無法轉換,NLS_LANG使用替換字符替代這些無法映射的字符(這一步轉換在TTS中
    完成),在很多字符集中這個替代字符就是”?”
  • 當客戶端的字符在NLS_LANG中對應了不同的字符時,傳遞給數據庫以后發生轉換,存儲的是字符,但是已經丟失了元數據,數據庫中
    的字符不再代表客戶端的輸入。而且這個過程不可逆,這也就是為什么很多時候在客戶端輸入的是正常的編碼,查詢之后會得到未知字符的原因。

字符集問題的初步探討(六)-亂碼的產生

我們通過上圖來簡單說明一下這個過程,當客戶端在WE8ISO8859P15字符集時,輸入歐元符號: €,這時客戶端NLS_LANG和數據庫端字符集不同,
進行第一次轉換,客戶端€符號編碼是A4,在NLS_LANG轉換時,A4對應了NLS_LANG中的‘¤’,這一步的轉換產生了錯誤映射。由于數據庫字符集不
同于NLS_LANG設置,這時進一步的轉換發生了,存入數據庫的編碼變成了C2A4,雖然同NLS_LANG進行了正確的轉換,但是客戶端錄入的數據已經
損壞或者丟失了。

我們可以用我們熟悉的字符集做一個簡單的測試:

測試環境:

客戶端應用為中文18030字符集

NLS_LANG設置為US7ASCII字符集

數據庫CHARACTER SET為ZHS16GBK

                c:\>set NLS_LANG=AMERICAN_AMERICA.US7ASCII

c:\>sqlplus eygle/eygle

SQL*Plus: Release 9.2.0.4.0 - Production on Tue Nov 4 01:19:57 2003

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production

SQL> insert into test values('測試');

1 row created.

SQL> select name,dump(name) from test;

NAME DUMP(NAME)
--------------------------------------------------
2bJT Typ=1 Len=4:
                
                   50,98,74,84
                
                
                  這時候我們發現,查詢出來的是混亂的字符,我們把這些字符轉換為2進制就是
110010   1100010   1001010   1010100
補全8位就是       00110010  01100010  01001010  01010100
我們把首位換成1   10110010  11100010  11001010  11010100
                
                

我們來看正確的存儲:
                
c:\>set nls_lang=AMERICAN_AMERICA.ZHS16GBK

c:\>sqlplus eygle/eygle

SQL*Plus: Release 9.2.0.4.0 - Production on Tue Nov 4 01:40:18 2003

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production

SQL> insert into test values('測試');

1 row created.

SQL> col dump(name) for a30
SQL> select name,dump(name) from test;

NAME DUMP(NAME)
---------- ------------------------------
測試 Typ=1 Len=4: 178,226,202,212

1 row selected.

                我們把這個結果轉換為2進制表示
                
10110010 11100010 11001010 11010100

這個結果正是我們前面亂碼首位補全1后的結果。

這個測試說明在US7ASCII轉換中文的時候除去了首位的 1,這樣就丟失了元數據,導致亂碼出現,NLS_LANG的轉換作用由此可加一斑!

              

3. NLS_LANG和數據庫字符集相同時
在這種情況下,數據庫端對客戶端傳遞過來的編碼不進行任何轉換(這樣可以提高性能),直接存儲進入數據庫,那么這時候就存在和上面同樣的問題,
如果客戶端傳遞過來的字符集在數據庫中有正確的對應就可以正確存儲,如果沒有,就會被替換字符置換成?,亂碼就這樣產生了。

字符集問題的初步探討(六)-亂碼的產生

如上圖所示,當NLS_LANG和數據庫字符集設置相同都為UTF8時,客戶端的歐元符號的編碼A4就不會經過任何轉換就插入到數據庫中,而在UTF8的數
據庫中,A4代表的是一個非法字符。

我們來看一個簡單的測試

測試環境:

客戶端字符集應用為中文GB18030

客戶端NLS_LANG為US7ASCII

數據庫字符集為US7ASCII

我們知道這個時候,存入的數據,數據庫不進行任何轉換,在以下的測試中,我們看到中文在US7ASCII字符集下得以正確顯示。

              c:\>set nls_lang=AMERICAN_AMERICA.US7ASCII

c:\>sqlplus eygle/eygle

SQL*Plus: Release 9.2.0.4.0 - Production on Tue Nov 4 01:02:04 2003

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production

SQL> insert into test values('測試');

1 row created.

SQL> commit;

Commit complete.

SQL> select * from test;

NAME
----------
測試

1 row selected.

SQL> col dump(name) for a30
SQL> select name,dump(name) from test;

NAME       DUMP(NAME)
---------- ------------------------------
測試       Typ=1 Len=4: 178,226,202,212

1 row selected.

SQL> select * from nls_database_parameters;

PARAMETER                      VALUE
------------------------------ ----------------------------------------
NLS_LANGUAGE                   AMERICAN
NLS_TERRITORY                  AMERICA
NLS_CURRENCY                   $
NLS_ISO_CURRENCY               AMERICA
NLS_NUMERIC_CHARACTERS         .,
NLS_CHARACTERSET               US7ASCII
NLS_CALENDAR                   GREGORIAN
NLS_DATE_FORMAT                DD-MON-RR
NLS_DATE_LANGUAGE              AMERICAN
NLS_SORT                       BINARY
NLS_TIME_FORMAT                HH.MI.SSXFF AM

PARAMETER                      VALUE
------------------------------ ----------------------------------------
NLS_TIMESTAMP_FORMAT           DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT             HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT        DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY              $
NLS_COMP                       BINARY
NLS_LENGTH_SEMANTICS           BYTE
NLS_NCHAR_CONV_EXCP            FALSE
NLS_NCHAR_CHARACTERSET         AL16UTF16
NLS_RDBMS_VERSION              9.2.0.4.0

20 rows selected.

SQL>
       
            

結語:

對于DBA來說,有一個很重要的原則就是:不要把你的數據庫置于危險的境地!

這就要求我們,在進行任何可能對數據庫結構發生改變的操作之前,先做有效的備份,很多DBA沒有備份的操作中得到了慘痛的教訓。

-----

字符集問題的初步探討(六)-亂碼的產生


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久草精品视频在线观看 | 国产在视频线精品视频www666 | 午夜精品久久久久久久99热浪潮 | 日日撸视频 | 一区二区在线不卡 | 国产精品91久久久久 | 黄色免费av | 久久人人爽人人爽人人片av不 | 国产精品免费视频网站 | 激情五月婷婷 | 性做久久久久免费看 | 色婷婷视频 | 色吊丝国产 | 国产目拍亚洲精品区一区 | 国产一区久久 | 超碰3| 国产精品xxxav免费视频 | 国产成人精品视频频 | 久久天天躁夜夜躁狠狠 | 亚洲综合久久伊人热 | 久久久久久久久久免观看 | 欧美日韩中文一区 | 色拍拍视频 | 欧美成人a∨高清免费观看 久久亚洲欧美日韩精品专区 | 亚洲不卡视频 | 日韩免费在线视频 | 亚洲日日干| 国产综合久久久久 | 欧美a级成人淫片免费看 | 天天射影院 | 欧美一级久久久久久久久大 | 看黄在线| 国产午夜视频 | 狠狠综合久久久久综 | 国产一极毛片 | 欧美亚洲理伦电影毛片在线播放 | 91视频在 | 亚洲欧洲精品一区二区 | 91成人免费看 | www.国产| 九九热在线精品 |