個人環境是RH linux 4,數據庫oracle 10.2,字符集是AL32UTF8。現象是這樣的:用select查看原數據,中文顯示亂碼,但java應用程序顯示正常。從linux上用sqlplus插入一條中文,再用select 查詢,新插入的這條中文顯示正常,但java應用程序查詢不出來。數據庫字符集用的utf8,看了一下nls_lang的設置是NLS_LANG=american_america.AL32UTF8; 因而改爲了NLS_LANG=american_america.UTF8(編輯並運行.bash_profile),從新插入數據,用select查看,中文顯示亂碼,但java應用程序顯示正常。再修改NLS_LANG=american_america.ZHS16GBK,用select查詢,中文顯示正常。
今天又遇到了從sql plus insert 中文的問題,主要仍是nls_lang的設置,總結一下。
首先要明確什麼是字符集?字符集是一個字節數據的解釋的符號集合,有大小之分,有相互的包括關係,如us7ascii就是zhs16gbk的子集, 從us7ascii到zhs16gbk不會有數據解釋上的問題,不會有數據丟失,Oracle對這種問題也要求從子集到超集的導出受支持,反之不行。在全部的字符集中utf8應該是最大,由於它基於unicode,雙字節保存字符(也所以在存儲空間上佔用更多)。
其次,一旦數據庫建立後,數據庫的字符集是不能改變的。所以,在設計和安裝之初考慮使用哪種字符集是十分重要的。數據庫字符集應該是操做系統本地字符集的一個超集。存取數據庫的客戶使用的字符集將決定選擇哪個超集,即數據庫字符集應該是全部客戶字符集的超集。
如今,介紹一些與字符集有關的NLS_LANG參數,
NLS_LANG格式:
NLS_LANG = language_territory.charset
有三個組成部分(語言、地域和字符集),每一個成分控制了NLS子集的特性。其中:language 指定服務器消息的語言。
territory 指定服務器的日期和數字格式。
charset 指定字符集
例如:
AMERICAN_AMERICA.US7SCII
AMERICAN _ AMERICA. ZHS16GBK
還有一些子集能夠更明肯定義NLS_LANG參數:
DICT.BASE 數據字典基本 表版本
DBTIMEZONE 數據庫時區
NLS_LANGUAGE 語言
NLS_TERRITORY 地域
NLS_CURRENCY 本地貨幣字符
NLS_ISO_CURRENCY ISO貨幣字符
NLS_NUMERIC_CHARACTERS 小數字符和組 分隔開
NLS_CHARACTERSET 字符集
NLS_CALENDAR 日曆系統
NLS_DATE_FORMAT 缺省的日期格式
NLS_DATE_LANGUAGE 缺省的日期語言
NLS_SORT 字符排序序列
NLS_TIME_FORMAT 時間格式
NLS_TIMESTAMP_FORMAT 時間戳格式
……
查看可選的數據庫字符集:
col nls_charset_id for 99999
col nls_charset_name for a35
col hex_id for a5
select nls_charset_id(value) nls_charset_id,value nls_charset_name,to_char(nls_charset_id (value),'xxxx') hex_id
from v$nls_valid_values
where parameter = 'CHARACTERSET';
查看當前數據庫字符集配置:
col parameter for a35
col value for a35
select * from v$nls_parameters;
或者:
select * from sys.props