Oracle中char類型亂談

今天有個朋友問我關於char類型和varchar2類型的取捨問題,我自然推薦他使varchar2。因爲我就是這麼幹的,varchar2靈活且不浪費存儲空間就是我的理由,後來就順手測試了下。這裏把測試拿出來,這裏重點討論下char的問題:

在測試的過程中,使用的基本SQL判斷語句就是:
1: 查看數據庫的parameters; select * from nls_database_parameters;
2: 使用dump查看數據的存儲情況; select dump(col_name) from dual;
-----------------------------------
步驟一,查看數據庫的字符集(NLS_NCHAR_CHARACTERSET),和NLS_LENGTH_SEMANTICS的取值情況,執行完語句:

    select * from nls_database_parameters;


後我們可以發現這兩個需要注意的PARAMETER的取值:
 NLS_NCHAR_CHARACTERSET = UTF8
NLS_LENGTH_SEMANTICS = BYTE


其中NLS_LENGTH_SEMANTICS決定了Oracle使用byte還是char來解析 col_name char的含義;因爲測試的庫中NLS_LENGTH_SEMANTICS的取值爲byte,爲此col_name char 和col_name(1 byte)是等價的;同時因爲NLS_NCHAR_CHARACTERSET的取值爲utf8,我測試的結果是在這種情況下col_name char(2 byte) 和col_name(1 char)是一種長度上的等價關係,當然編碼
這個問題,這裏不再展開考慮,只是指明1 byte = n char 需要考慮NLS_NCHAR_CHARACTERSET後纔能有個正確的答案;

步驟二,創建測試數據表並測試

create table test_s_char(id number primary key, char_data_byte char(2), char_data_char char(1 char));
insert into test_s_char(1, 'a', 'a');
insert into test_s_char(2,'安','安');
insert into test_s_char(2,'安','安');

之後查看其存儲方式,我們不難發現char_data_byte類型的數據在存儲時總是長度爲2(定義的長度),[color=red]而char(1 char)的則不同,其形式等價與varchar2!?[/color]
sql>select char_data_byte,dump(char_data_byte) from test_s_char;
--------------------------------------------
a Typ=96 Len=2: 97,32
安 Typ=96 Len=2: 176,178

sql>select char_data_char,dump(char_data_char) from test_s_char;
--------------------------------------------
a Typ=96 Len=1: 97
安 Typ=96 Len=2: 176,178


需要注意的是如果我們使用Oracle自己的length來讀取數據的話, 則會發現字符的長度爲1,這個可能是length在使用的時候自身處理的結果.
select length(char_data_char), length(char_data_byte) from test_s_char;

而在使用jdbc的ResultSet來獲取char的數據時,使用getString()方法返回的數據總是數據定義的長度,如果不足則使用ASCII取值爲32的space來填充,這個是需要注意的地方,同事這個也是我那哥們出岔子的地方,他雖然在表上同一格式化了數據,且使用length得到的數據也是自己期望的,但是程序搗鼓出來的就是不對,癥結就在於此。
發佈了16 篇原創文章 · 獲贊 0 · 訪問量 3572
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章