Oracle漢字亂碼問題原因及解決方案
by wangd
原因:
出現中文亂碼的主要原因是字元集不同。
在Oracle中,我們關心三個地方的字元集:
l Oracle伺服器內部的字元集
l NLS_LANG變數裡儲存的字元集
l 用戶端應用的字元集
Oracle伺服器內部的字元集
這是Oracle資料庫儲存資料使用的字元集。
在Oracle中可能使用
Select userenv('language') from dual;
或者:
Select name, value$ from props$;
查看。
NLS_LANG變數裡儲存的字元集
這個是Oracle設定的一個變數。
在Windows中,這個變數儲存在註冊表中:
HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/HOME0儲存著NLS_LANG變數。
在Unix/Linux中,則需要自己進行設定了。我本人是在.profile裡面加上
NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
export NLS_LANG
用戶端應用的字元集
使用Oracle裡資料或者向Oracle提供資料的應用程式。
如果 Oracle伺服器內部的字元集 和 NLS_LANG變數裡儲存的字元集 相同,在進行Oracle查詢時,就會將Oracle中的資料直接查出來,返回給查詢使用者。進行Oracle的插入操作,就會直接將插入的資料儲存進資料庫中。
但是如果不同的話,Oracle查詢時,會根據這兩個字元集的一個映射,將資料庫中的資料作一個轉換,再返回給查詢使用者。進行插入操作時,也會根據映射,將插入的資料作一個轉換,再插入資料庫。這也是產生亂碼的原因,這一層轉換,把資料都給轉亂了。
解決辦法:
將資料庫的字元集和NLS_LANG字元集設定的一樣,就可以避免亂碼的出現了。
修改資料庫字元集的步驟如下:
1、擁有修改許可權(用系統管理使用者登入)。
SQL> conn sys/sys as sysdba;
2、關閉資料庫。
SQL>shutdown immediate;
3、啟動資料庫到Mount狀態下。
SQL> STARTUP MOUNT;
ORACLE instance started.
Total System Global Area 76619308 bytes
Fixed Size 454188 bytes
Variable Size 58720256 bytes
Database Buffers 16777216 bytes
Redo Buffers 667648 bytes
Database mounted.
SQL> ALTER SESSION SET SQL_TRACE=TRUE;
Session altered.
SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;
System altered.
SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
System altered.
SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;
System altered.
4、啟動資料庫
SQL> Alter database open;
5、修改字元集
SQL> ALTER DATABASE CHARACTER SET ZHS16GBK;
註:
1. 如果資料庫表中有CLOB類型的列,是不允許修改字元集的,解決方案為,先匯出這個表的內容,然後刪除這個表,修改完後,再匯入這個表的內容就可以了。
2. 舊的字元集必須是新的字元集的子集,否則不能修改。
修改完後,可以查看一下修改是否成功。
6、關閉資料庫
SQL> Shutdown immediate;
7、重新啟動資料庫
SQL> startup;
經過設定完Oracle字元集後,一般的亂碼問題應該解決掉了。
在開發中,還遇到了這樣一個問題:
資料庫伺服器和應用伺服器都布署在Solaris上面了,建庫的指令碼也是在Solaris上面執行的,在Solaris上面查詢資料是正常的,但是在Windows上用瀏覽器看時,就會變成。了。
這個問題的解決辦法是,將資料庫建庫指令碼在Windows上執行,再查看就都變正常了。