【字符集】論Oracle字符集“轉碼”過程
本文將通過實驗來演示一下Oracle字符集“轉碼”的確認過程。
曾經分享過的有關字符集文章如下:
《檢視本地windows的字符集方法》
http://space.itpub.net/519536/viewspace-580610
《【字符集】“客戶終端字符集”、“NLS_LANG”環境變數以及“資料庫字符集”》
http://space.itpub.net/519536/viewspace-615345
《【字符集】處理Toad顯示亂碼及Windows XP下無法插入“某些漢字”問題》
http://space.itpub.net/519536/viewspace-615379
OK,現在開始我們的實驗之旅。
1.實驗環境說明
客戶端是Windows XP作業系統的SQL*Plus程式,客戶端字符集是936(對應Oracle的ZHS16GBK字符集);
資料庫版本是Oracle 10g,資料庫字符集是AL32UTF8;
NLS_LANG引數將在實驗中進行指定。
1)確認客戶端字符集
C:\>chcp
活動內碼表: 936
註釋:936對應Oracle的ZHS16GBK字符集。
2)檢視資料庫版本資訊:
sec@ora10g> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for Linux: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
3)確認資料庫的字符集:
sec@ora10g> col PARAMETER for a20
sec@ora10g> col value for a20
sec@ora10g> select * from v$nls_parameters where parameter = 'NLS_CHARACTERSET';
PARAMETER VALUE
-------------------- --------------------
NLS_CHARACTERSET AL32UTF8
2.實驗中將會涉及到的兩種場景
“轉碼”場景:設定客戶端的NLS_LANG與客戶端字符集一致,這裡是ZHS16GBK;
“非轉碼”場景:設定客戶端的NLS_LANG與資料庫伺服器端字符集一致,此處是AL32UTF8.
關於如何設定NLS_LANG引數,請參考下面文章:
《【NLS_LANG】不同作業系統平臺NLS_LANG環境變數的檢視與設定方法》
http://space.itpub.net/519536/viewspace-580623
在這個實驗中,為了方便,我將採用set命令設定字符集。您可以按照自己的習慣去設定。
3.建立實驗表T
sec@ora10g> create table t (x number(1), client_characterset varchar2(10), nls_lang varchar2(10), database_characterset varchar2(10), y varchar2(10));
Table created.
sec@ora10g> desc t;
Name Null? Type
----------------------------------- -------- ------------------------
X NUMBER(1)
CLIENT_CHARACTERSET VARCHAR2(10)
NLS_LANG VARCHAR2(10)
DATABASE_CHARACTERSET VARCHAR2(10)
Y VARCHAR2(10)
T表包含五個欄位,分表表示序號、客戶端字符集、客戶端NLS_LANG設定情況以及資料庫伺服器字符集設定情況。
4.兩種NLS_LANG設定方法下分別插入一條資料
1)當客戶端的NLS_LANG設定為ZHS16GBK時,我們插入第一條記錄(“轉碼”場景)。
C:\>set nls_lang=AMERICAN_AMERICA.ZHS16GBK
C:\>sqlplus sec/sec@ora10g
SQL*Plus: Release 10.2.0.3.0 - Production on Fri Feb 5 19:21:31 2010
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning and Data Mining options
sec@ora10g> insert into t values (1,'ZHS16GBK','ZHS16GBK','AL32UTF8','聖');
1 row created.
sec@ora10g> commit;
Commit complete.
2)當客戶端的NLS_LANG設定為AL32UTF8時,我們插入第二條記錄(“非轉碼”場景)。
C:\>set nls_lang=AMERICAN_AMERICA.AL32UTF8
C:\>sqlplus sec/sec@ora10g
SQL*Plus: Release 10.2.0.3.0 - Production on Fri Feb 5 20:41:15 2010
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning and Data Mining options
sec@ora10g> insert into t values (2,'ZHS16GBK','AL32UTF8','AL32UTF8','聖');
1 row created.
sec@ora10g> commit;
Commit complete.
5.兩種NLS_LANG設定方法下分別檢視剛剛插入的兩條資料
1)當客戶端的NLS_LANG設定為ZHS16GBK時(“轉碼”場景)。
sec@ora10g> col x for 9
sec@ora10g> col CLIENT_CHARACTERSET for a8
sec@ora10g> col NLS_LANG for a8
sec@ora10g> col DATABASE_CHARACTERSET for a8
sec@ora10g> col y for a4
sec@ora10g> col dump for a50
sec@ora10g> select t.*,dump(y,1016) dump from t order by 1;
X CLIENT_C NLS_LANG DATABASE Y DUMP
-- -------- -------- -------- ---- --------------------------------------------------
1 ZHS16GBK ZHS16GBK AL32UTF8 聖 Typ=1 Len=3 CharacterSet=AL32UTF8: e5,9c,a3
2 ZHS16GBK AL32UTF8 AL32UTF8 ? Typ=1 Len=2 CharacterSet=AL32UTF8: ca,a5
2)當客戶端的NLS_LANG設定為AL32UTF8時(“非轉碼”場景)。
sec@ora10g> col x for 9
sec@ora10g> col CLIENT_CHARACTERSET for a8
sec@ora10g> col NLS_LANG for a8
sec@ora10g> col DATABASE_CHARACTERSET for a8
sec@ora10g> col y for a4
sec@ora10g> col dump for a50
sec@ora10g> select t.*,dump(y,1016) dump from t order by 1;
X CLIENT_C NLS_LANG DATABASE Y DUMP
-- -------- -------- -------- ---- --------------------------------------------------
1 ZHS16GBK ZHS16GBK AL32UTF8 鍦? Typ=1 Len=3 CharacterSet=AL32UTF8: e5,9c,a3
2 ZHS16GBK AL32UTF8 AL32UTF8 聖 Typ=1 Len=2 CharacterSet=AL32UTF8: ca,a5
BTW:有關dump函式的使用方法可以參考Oracle的官方文件
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/functions046.htm#SQLRF00635
我這裡將return_fmt指定為“1016”,這樣會指示出字符集和字元的16進位制編碼內容。
6.分析與結論
1)“聖”字在ZHS16GBK字符集下的編碼是“ca,a5”
這個資訊可以從微軟的936字符集(ZHS16GBK)中查詢得到。
http://www.microsoft.com/globaldev/reference/dbcs/936/936_CA.mspx
2)“聖”字在AL32UTF8字符集下的編碼是“e5,9c,a3”
怎麼確認“聖”字在UTF8字符集下的編碼呢?使用UltraEdit的十六進位制編輯模式可以完成這個任務。
將漢字“聖”貼上到空白的UltraEdit中,依次點選“檔案” --> “轉換” --> “ASCII轉UTF-8(Unicode 編輯)”,然後再一次點選“編輯” --> “十六進位制函式” --> “十六進位制編輯”(反覆切換十六進位制編輯模式亦可使用Ctrl+H快捷鍵來完成),OK,此時便可以得到“聖”字在UTF8字符集下的編碼是“E5 9C A3”。
當然,確認“聖”字在ZHS16GBK字符集下的編碼也可以使用UltraEdit來完成。
3)結論一
當客戶端的NLS_LANG設定為ZHS16GBK時,“聖”字發生了轉碼,由ZHS16GBK編碼“ca,a5”轉成了AL32UTF8編碼“e5,9c,a3”;
4)結論二
當客戶端的NLS_LANG設定為AL32UTF8時,“聖”字沒有發生轉碼,直接以客戶端的ZHS16GBK編碼“ca,a5”儲存在資料庫中。
5)“?”的由來
當客戶端的NLS_LANG設定為ZHS16GBK時,查詢得到的“?”是由UTF-8編碼“ca,a5”轉換為ZHS16GBK編碼後的產物。
6)“鍦?”的由來
這個“鍦”字讀作“shi1”(參考:http://www.zdic.net/zd/zi/ZdicE9Zdic8DZdicA6.htm)
因為此時NLS_LANG設定為AL32UTF8,客戶端獲取資料庫資訊時將不進行轉碼,因此在客戶端顯示的時候將使用“e5,9c,a3”這個編碼在936字符集(ZHS16GBK)中尋找匹配的內容。前面的“e5,9c”正好拼接成了“鍦”字,因此“鍦”字便展現在了我們面前。
這個“鍦”字的編碼可以在下面的連結中查詢到。
http://www.microsoft.com/globaldev/reference/dbcs/936/936_E5.mspx
7.小結
Oracle字符集相關知識涉及面較廣,需要靜下心來仔細思考其中蘊含的原理。
本文通過實驗給大家展示了有關“轉碼”的相關內容,供參考,希望對大家有幫助。
Good luck.
secooler
10.02.05
-- The End --
曾經分享過的有關字符集文章如下:
《檢視本地windows的字符集方法》
http://space.itpub.net/519536/viewspace-580610
《【字符集】“客戶終端字符集”、“NLS_LANG”環境變數以及“資料庫字符集”》
http://space.itpub.net/519536/viewspace-615345
《【字符集】處理Toad顯示亂碼及Windows XP下無法插入“某些漢字”問題》
http://space.itpub.net/519536/viewspace-615379
OK,現在開始我們的實驗之旅。
1.實驗環境說明
客戶端是Windows XP作業系統的SQL*Plus程式,客戶端字符集是936(對應Oracle的ZHS16GBK字符集);
資料庫版本是Oracle 10g,資料庫字符集是AL32UTF8;
NLS_LANG引數將在實驗中進行指定。
1)確認客戶端字符集
C:\>chcp
活動內碼表: 936
註釋:936對應Oracle的ZHS16GBK字符集。
2)檢視資料庫版本資訊:
sec@ora10g> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for Linux: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
3)確認資料庫的字符集:
sec@ora10g> col PARAMETER for a20
sec@ora10g> col value for a20
sec@ora10g> select * from v$nls_parameters where parameter = 'NLS_CHARACTERSET';
PARAMETER VALUE
-------------------- --------------------
NLS_CHARACTERSET AL32UTF8
2.實驗中將會涉及到的兩種場景
“轉碼”場景:設定客戶端的NLS_LANG與客戶端字符集一致,這裡是ZHS16GBK;
“非轉碼”場景:設定客戶端的NLS_LANG與資料庫伺服器端字符集一致,此處是AL32UTF8.
關於如何設定NLS_LANG引數,請參考下面文章:
《【NLS_LANG】不同作業系統平臺NLS_LANG環境變數的檢視與設定方法》
http://space.itpub.net/519536/viewspace-580623
在這個實驗中,為了方便,我將採用set命令設定字符集。您可以按照自己的習慣去設定。
3.建立實驗表T
sec@ora10g> create table t (x number(1), client_characterset varchar2(10), nls_lang varchar2(10), database_characterset varchar2(10), y varchar2(10));
Table created.
sec@ora10g> desc t;
Name Null? Type
----------------------------------- -------- ------------------------
X NUMBER(1)
CLIENT_CHARACTERSET VARCHAR2(10)
NLS_LANG VARCHAR2(10)
DATABASE_CHARACTERSET VARCHAR2(10)
Y VARCHAR2(10)
T表包含五個欄位,分表表示序號、客戶端字符集、客戶端NLS_LANG設定情況以及資料庫伺服器字符集設定情況。
4.兩種NLS_LANG設定方法下分別插入一條資料
1)當客戶端的NLS_LANG設定為ZHS16GBK時,我們插入第一條記錄(“轉碼”場景)。
C:\>set nls_lang=AMERICAN_AMERICA.ZHS16GBK
C:\>sqlplus sec/sec@ora10g
SQL*Plus: Release 10.2.0.3.0 - Production on Fri Feb 5 19:21:31 2010
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning and Data Mining options
sec@ora10g> insert into t values (1,'ZHS16GBK','ZHS16GBK','AL32UTF8','聖');
1 row created.
sec@ora10g> commit;
Commit complete.
2)當客戶端的NLS_LANG設定為AL32UTF8時,我們插入第二條記錄(“非轉碼”場景)。
C:\>set nls_lang=AMERICAN_AMERICA.AL32UTF8
C:\>sqlplus sec/sec@ora10g
SQL*Plus: Release 10.2.0.3.0 - Production on Fri Feb 5 20:41:15 2010
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning and Data Mining options
sec@ora10g> insert into t values (2,'ZHS16GBK','AL32UTF8','AL32UTF8','聖');
1 row created.
sec@ora10g> commit;
Commit complete.
5.兩種NLS_LANG設定方法下分別檢視剛剛插入的兩條資料
1)當客戶端的NLS_LANG設定為ZHS16GBK時(“轉碼”場景)。
sec@ora10g> col x for 9
sec@ora10g> col CLIENT_CHARACTERSET for a8
sec@ora10g> col NLS_LANG for a8
sec@ora10g> col DATABASE_CHARACTERSET for a8
sec@ora10g> col y for a4
sec@ora10g> col dump for a50
sec@ora10g> select t.*,dump(y,1016) dump from t order by 1;
X CLIENT_C NLS_LANG DATABASE Y DUMP
-- -------- -------- -------- ---- --------------------------------------------------
1 ZHS16GBK ZHS16GBK AL32UTF8 聖 Typ=1 Len=3 CharacterSet=AL32UTF8: e5,9c,a3
2 ZHS16GBK AL32UTF8 AL32UTF8 ? Typ=1 Len=2 CharacterSet=AL32UTF8: ca,a5
2)當客戶端的NLS_LANG設定為AL32UTF8時(“非轉碼”場景)。
sec@ora10g> col x for 9
sec@ora10g> col CLIENT_CHARACTERSET for a8
sec@ora10g> col NLS_LANG for a8
sec@ora10g> col DATABASE_CHARACTERSET for a8
sec@ora10g> col y for a4
sec@ora10g> col dump for a50
sec@ora10g> select t.*,dump(y,1016) dump from t order by 1;
X CLIENT_C NLS_LANG DATABASE Y DUMP
-- -------- -------- -------- ---- --------------------------------------------------
1 ZHS16GBK ZHS16GBK AL32UTF8 鍦? Typ=1 Len=3 CharacterSet=AL32UTF8: e5,9c,a3
2 ZHS16GBK AL32UTF8 AL32UTF8 聖 Typ=1 Len=2 CharacterSet=AL32UTF8: ca,a5
BTW:有關dump函式的使用方法可以參考Oracle的官方文件
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/functions046.htm#SQLRF00635
我這裡將return_fmt指定為“1016”,這樣會指示出字符集和字元的16進位制編碼內容。
6.分析與結論
1)“聖”字在ZHS16GBK字符集下的編碼是“ca,a5”
這個資訊可以從微軟的936字符集(ZHS16GBK)中查詢得到。
http://www.microsoft.com/globaldev/reference/dbcs/936/936_CA.mspx
2)“聖”字在AL32UTF8字符集下的編碼是“e5,9c,a3”
怎麼確認“聖”字在UTF8字符集下的編碼呢?使用UltraEdit的十六進位制編輯模式可以完成這個任務。
將漢字“聖”貼上到空白的UltraEdit中,依次點選“檔案” --> “轉換” --> “ASCII轉UTF-8(Unicode 編輯)”,然後再一次點選“編輯” --> “十六進位制函式” --> “十六進位制編輯”(反覆切換十六進位制編輯模式亦可使用Ctrl+H快捷鍵來完成),OK,此時便可以得到“聖”字在UTF8字符集下的編碼是“E5 9C A3”。
當然,確認“聖”字在ZHS16GBK字符集下的編碼也可以使用UltraEdit來完成。
3)結論一
當客戶端的NLS_LANG設定為ZHS16GBK時,“聖”字發生了轉碼,由ZHS16GBK編碼“ca,a5”轉成了AL32UTF8編碼“e5,9c,a3”;
4)結論二
當客戶端的NLS_LANG設定為AL32UTF8時,“聖”字沒有發生轉碼,直接以客戶端的ZHS16GBK編碼“ca,a5”儲存在資料庫中。
5)“?”的由來
當客戶端的NLS_LANG設定為ZHS16GBK時,查詢得到的“?”是由UTF-8編碼“ca,a5”轉換為ZHS16GBK編碼後的產物。
6)“鍦?”的由來
這個“鍦”字讀作“shi1”(參考:http://www.zdic.net/zd/zi/ZdicE9Zdic8DZdicA6.htm)
因為此時NLS_LANG設定為AL32UTF8,客戶端獲取資料庫資訊時將不進行轉碼,因此在客戶端顯示的時候將使用“e5,9c,a3”這個編碼在936字符集(ZHS16GBK)中尋找匹配的內容。前面的“e5,9c”正好拼接成了“鍦”字,因此“鍦”字便展現在了我們面前。
這個“鍦”字的編碼可以在下面的連結中查詢到。
http://www.microsoft.com/globaldev/reference/dbcs/936/936_E5.mspx
7.小結
Oracle字符集相關知識涉及面較廣,需要靜下心來仔細思考其中蘊含的原理。
本文通過實驗給大家展示了有關“轉碼”的相關內容,供參考,希望對大家有幫助。
Good luck.
secooler
10.02.05
-- The End --
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/519536/viewspace-626952/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle 字符集修改Oracle
- 「Oracle」資料庫字符集編碼修改Oracle資料庫
- 深入理解Emoji(一) —— 字符集,字符集編碼
- 字符集與編碼
- 更改Oracle字符集:把字符集ZHS16GBK換成UTF8Oracle
- 修改Oracle資料庫字符集(zt)Oracle資料庫
- 教你玩轉Eclipse—修改字符集Eclipse
- 字符集編碼(三):UnicodeUnicode
- 字符集編碼(四):UTF
- 字符集
- 修改Oracle字符集為ZHS16GBKOracle
- 字符集編碼(上):Unicode 之前Unicode
- Tomcat字符集Tomcat
- MySQL字符集MySql
- Oracle Linux 7設定中文字符集OracleLinux
- 38、字符集_2(匯出匯入指定字符集)
- 字符集編碼(二):字元編碼模型字元模型
- PYTHON3 cx-Oracle 字符集 轉換錯誤的解決方案PythonOracle
- Oracle 字符集從GBK升級到Utf8Oracle
- 修改sqlserver字符集SQLServer
- 更新Linux字符集Linux
- 批次修改欄位字符集和表表字符集,sql生成SQL
- MySQL字符集亂碼與解決方案MySql
- WebKit Inside: CSS 樣式表解碼字符集WebKitIDECSS
- SQLServer的排序規則(字符集編碼)SQLServer排序
- maven中如何指定原始碼的字符集Maven原始碼
- Oracle 12.2 新特性 | PDB不同字符集變更深入解析Oracle
- 4.2.1.4 選擇字符集
- mysql字符集說明MySql
- 遷移ORACLE資料到MogDB/openGauss時的字符集問題Oracle
- mysql字符集和字元排序MySql字元排序
- CentOS7.5修改字符集CentOS
- weblogic 啟動指定字符集Web
- GB 2312字符集:中文編碼的基石
- Intellij Idea下設定專案字符集編碼IntelliJIdea
- mysql亂碼?一勞永逸修改mysql字符集!MySql
- GB2312漢字編碼字符集對照表
- linux出現故障字符集亂碼故障排查思路Linux
- Oracle 12C 修改字符集為AL32UTF8研究Oracle