警示:AL32UTF8字符集不是ZHS16GBK字符集的超集

今天有客戶向我諮詢:數據庫由ZHS16GBK字符集修改成AL32UTF8字符集,發現中文的數據中小部分出現亂碼,客戶認爲AL32UTF8明明能夠支持更多的文字,不該該出現這樣的狀況纔對。
從現象看,基本能夠確認故障是字符集轉換致使的,Oracle也強烈不建議作這種字符集轉換的操做,幸虧該客戶的操做只是在一個測試環境中操做的。不過,以前也一直有個誤區,咱們都知道AL32UTF8是能夠支持多國語言的字符集,對於中文字節存儲佔用空間比ZHS16GBK多,而後第一反應就認爲AL32UTF8應該是ZHS16GBK的超集。而若是是絕對的超集,就不該該出現任何亂碼的狀況,可實際用戶反饋的現象的確是有小部分出現亂碼的狀況,因此有必要在測試環境再次驗證一下。數據庫

1.首先個人庫ZHS16GBK的字符集工具

SQL> select userenv('language') from dual;

USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.ZHS16GBK

2.嘗試修改字符集爲AL32UTF8
直接嘗試修改,會發現Oracle明確給出錯誤提示ORA-12712:新的字符集必須是舊字符集的超集。這就說明咱們要改的AL32UTF8字符集並非ZHS16GBK的超集。測試

SQL> alter database character set al32utf8;
alter database character set al32utf8
*
ERROR at line 1:
ORA-12712: new character set must be a superset of old character set

若是非要修改,能夠加internal_use參數強制修改,而這樣的操做,天然就頗有可能會形成部分數據出現亂碼:code

SQL> alter database character set internal_use al32utf8;

Database altered.

SQL> select userenv('language') from dual;

USERENV('LANGUAGE')
--------------------------------------------------------------------------------
AMERICAN_AMERICA.AL32UTF8

此時若是咱們經過PL/SQL Developer工具鏈接到數據庫,還會有這樣的警告信息:

而客戶端是Windows,chcp結果是936,也就是ZHS16GBK,這也進一步說明了ZHS16GBK和AL32UTF8字符集的不一樣。blog

同時實驗還驗證,若是數據庫字符集自己是AL32UTF8,想修改爲爲ZHS16GBK字符集,也是同樣的狀況,須要加internal_use參數才能夠轉換,也就是說這種轉換同樣可能出現亂碼,不過這個狀況反倒好理解,也符合咱們以前的認知,就再也不贅述了。亂碼

相關文章
相關標籤/搜索