1 一、oracle服務端字符集 2 SQL> select userenv('language') from dual ; 3 4 USERENV('LANGUAGE') 5 ---------------------------------------------------- 6 AMERICAN_AMERICA.ZHS16GBK 7 8 9 二、oracle客戶段字符集 10 11 2.1 window環境下,修改注冊表ORACLE_HOME目錄下的環境變量NLS_LANG。 12 13 2.2 unix/linux環境下,就是環境變量$NLS_LANG 14 15 [oracle@wang ~]$ echo $NLS_LANG 16 AMERICAN_AMERICA.ZHS16GBK 17 18 查看數據庫字符集 19 20 數據庫服務器字符集select * from nls_database_parameters;,其來源於props$,是表示數據庫的字符集。 21 22 客戶端字符集環境select * from nls_instance_parameters;,其來源於v$parameter,表示客戶端的字符集的設置,可能是參數文件,環境變量或者是注冊表 23 24 如何查詢dmp文件的字符集 25 26 用oracle的exp工具導出的dmp文件也包含了字符集信息,dmp文件的第2和第3個字節記錄了dmp文件的字符集。如果dmp文件不大,比如只有幾M或幾十M,可以用UltraEdit打開(16進制方式),看第2第3個字節的內容,如0354,然后用以下SQL查出它對應的字符集: 27 28 SQL> select nls_charset_name(to_number('0354','xxxx')) from dual; 29 30 ZHS16GBK 31 32 如果dmp文件很大,比如有2G以上(這也是最常見的情況),用文本編輯器打開很慢或者完全打不開,可以用以下命令(在unix主機上): 33 cat exp.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 3-6 34 然后用上述SQL也可以得到它對應的字符集
2.od 命令解釋
#od命令功能說明:輸出文件內容。 語 法:od [-abcdfhilovx][-A <字碼基數>][-j <字符數目>][-N <字符數目>][-s <字符串字符數>][-t <輸出格式>][-w <每列字符數>][--help][--version][文件...] 補充說明:od指令會讀取所給予的文件的內容,並將其內容以八進制字碼呈現出來。 參 數: -a 此參數的效果和同時指定"-ta"參數相同。 -A<字碼基數> 選擇要以何種基數計算字碼。 -b 此參數的效果和同時指定"-toC"參數相同。 -c 此參數的效果和同時指定"-tC"參數相同。 -d 此參數的效果和同時指定"-tu2"參數相同。 -f 此參數的效果和同時指定"-tfF"參數相同。 -h 此參數的效果和同時指定"-tx2"參數相同。 -i 此參數的效果和同時指定"-td2"參數相同。 -j<字符數目>或--skip-bytes=<字符數目> 略過設置的字符數目。 -l 此參數的效果和同時指定"-td4"參數相同。 -N<字符數目>或--read-bytes=<字符數目> 到設置的字符數目為止。 -o 此參數的效果和同時指定"-to2"參數相同。 -s<字符串字符數>或--strings=<字符串字符數> 只顯示符合指定的字符數目的字符串。 -t<輸出格式>或--format=<輸出格式> 設置輸出格式。 -v或--output-duplicates 輸出時不省略重復的數據。 -w<每列字符數>或--width=<每列字符數> 設置每列的最大字符數。 -x 此參數的效果和同時指定"-h"參數相同。 --help 在線幫助。 --version 顯示版本信息。 實 例: 1 2 3 [linuxde@localhost ~]$ echo abcdef g > tmp [linuxde@localhost ~]$ cat tmp abcdef g 說明:先准備一個tmp文件 1 2 3 [linuxde@localhost ~]$ od -b tmp 0000000 141 142 143 144 145 146 040 147 012 0000011 說明:使用單字節八進制解釋進行輸出,注意左側的默認地址格式為八字節 1 2 3 [linuxde@localhost ~]$ od -c tmp 0000000 a b c d e f g \n 0000011 說明:使用ASCII碼進行輸出,注意其中包括轉義字符 1 2 3 [linuxde@localhost ~]$ od -t d1 tmp 0000000 97 98 99 100 101 102 32 103 10 0000011 說明:使用單字節十進制進行解釋 1 2 3 [linuxde@localhost ~]$ od -A d -c tmp 0000000 a b c d e f g \n 0000009 說明:設置地址格式為十進制。 1 2 3 [linuxde@localhost ~]$ od -A x -c tmp 000000 a b c d e f g \n 000009 說明:設置地址格式為十六進制 1 2 3 [linuxde@localhost ~]$ od -j 2 -c tmp 0000002 c d e f g \n 0000011 說明:跳過開始的兩個字節 1 2 3 [linuxde@localhost ~]$ od -N 2 -j 2 -c tmp 0000002 c d 0000004 說明:跳過開始的兩個字節,並且僅輸出兩個字節 1 2 3 4 5 6 7 8 9 10 11 [linuxde@localhost ~]$ od -w1 -c tmp 0000000 a 0000001 b 0000002 c 0000003 d 0000004 e 0000005 f 0000006 0000007 g 0000010 \n 0000011 說明:每行僅輸出1個字節 1 2 3 4 5 6 7 [linuxde@localhost ~]$ od -w2 -c tmp 0000000 a b 0000002 c d 0000004 e f 0000006 g 0000010 \n 0000011 說明:每行輸出兩個字節 1 2 3 4 5 [linuxde@localhost ~]$ od -w3 -b tmp 0000000 141 142 143 0000003 144 145 146 0000006 040 147 012 0000011 說明:每行輸出3個字節,並使用八進制單字節進行解釋
1、字符集和國家字符集 字符集在創建數據庫實例時指定,可以指定字符集(CHARACTER SET)和國家字符集(NATIONAL CHARACTER SET)。 1)字符集(CHARACTER SET) 用來存儲char、varchar2、clob、long等類型數據,還可以用來標識表名、列名以及PL/SQL變量等。 2)國家字符集(NATIONAL CHARACTER SET) 用以存儲nchar、nvarchar2、nclob等類型數據。國家字符集實質上是為Oracle選擇的附加字符集,主要作用是為了增強字符處理能力,因為nchar數據類型可以提供對亞洲使用定長多字節編碼的支持,而數據庫字符集則不一定能。國家字符集只能在unicode編碼中的AF16UTF16和UTF8中選擇,默認值是AF16UTF16。 2、支持中文的字符集 Oracle支持漢字(簡體中文,繁體不介紹)的字符集有多種,常用的有ZHS16GBK、UTF8、AL32UTF8和AL16UTF16。 1)ZHS16GBK 表示簡體中文,一個字符需要16位比特,采用GBK編碼標准。 2)UTF8 Oracle從8i版本開始使用的屬於UTF-8編碼的字符集,采用的Unicode標准為3.0,在11.2版本中,UTF8已經不是推薦字符集列表中的一員了。 3)AL32UTF8 與UTF8相比,它采用的Unicode版本更新,在10g版本中使用的是Unicode 4.01標准,而UTF8因為兼容性的考慮,在10g版本中用的是Unicode 3.0標准。 4)AL16UTF16 是ORACLE第一種采用UTF-16編碼方式的字符集,從ORACLE9開始使用,是作為缺省的國家字符集使用,它不能被用作數據庫的字符集。 3、NLS_LANG參數 Oracle數據庫字符集最重要的參數是NLS_LANG參數。 格式: NLS_LANG='language_territory.charset',不區分大小寫,例如' SIMPLIFIED CHINESE_CHINA.ZHS16GBK'。 它有三個組成部分:語言(language)、地域(territory)和字符集(charset)。 其中: language:數據庫服務器提示信息的語言。 territory:數據庫的日期和數字格式,意義不大。 charset:數據庫的字符集。 真正影響數據庫字符集的其實是第三部分charset,兩個數據庫之間的字符集只要第三部分相同,交換數據時中文不會出現亂碼。language影響的只是提示信息是中文還是英文。 三、服務端的字符集 1、查看服務端字符集 執行以下SQL可以查看服務端的字符集。 select * from NLS_DATABASE_PARAMETERS where parameter like '%CHARACTERSET%'; 在這里插入圖片描述 執行以下SQL也可以查看服務端的字符集。 select userenv('language') from dual; 在這里插入圖片描述 2、修改服務端字符集 Oracle數據庫實例創建后,如果沒有開始業務運行,可以修改字符集,如果已經業務化運行,不建議修改字符集,會造成數據中的漢字亂碼。 用DBA權限,執行以下步驟修改Oracle數據庫的字符集(例如修改為ZHS16GBK)。 1)修改服務端操作系統的NLS_LANG環境變量。 export NLS_LANG='Simplified Chinese_China.ZHS16GBK' 2)關閉Oracle數據庫。 shutdown immediate; 3)把數據庫啟動到mount狀態。 startup mount; 4)把數據庫改為restricted模式。 alter system enable restricted session; alter system set job_queue_processes=0; alter system set aq_tm_processes=0; 5)打開數據庫。 alter database open; 6)修改數據庫的字符集。 alter database character set internal_use ZHS16GBK; 7)重啟數據庫。 shutdown immediate; startup; 四、客戶端的字符集 Oracle客戶端的字符集必須與服務端相同,否則中文會出現亂碼。 1、Linux環境 客戶端的字符集由NLS_LANG環境變量控制。 1)查看NLS_LANG環境變量。 env|grep NLS_LANG 在這里插入圖片描述 2)設置環境變量 修改環境變量參數文件(系統或用戶的profile文件)。 export NLS_LANG='Simplified Chinese_China.ZHS16GBK' 2、Windows環境 打開注冊表( 執行regedit.exe) HKEY_LOCAL_MACHINE -> SOFTWARE -> ORACLE -> KEY_OraClient11g_home1 在這里插入圖片描述 五、應用經驗 1)數據庫在業務化之前,就應該確定Oracle的字符集,然后不再改變。數據庫在業務化后,修改字符集是一件很麻煩的事情,最好別惹這個麻煩。 2)如果項目沒有全球化的需求,數據庫字符集建議采用ZHS16GBK,操作系統語言建議采用gbk。 3)只要把客戶端和服務端設置成相同的字符集,就不會有亂碼,沒什么技術難點。 4)雖然GB18030字符集比GBK更豐富,但是GB18030中有部分漢字是4字節,這一點讓程序員很郁悶,所以,程序員更傾向GBK字符集