今天在工作時遇到一件奇怪的問題,

user反映明明欄位開了CHAR(6 byte),但裡面的文字卻只呈現5個byte,使用length去算整個欄位長度,卻顯示是6,

好吧,就來查查看是遇到甚麼問題了。

 

select dump(BEFORECOSIGNEREMPNO) from A.test

where NURSEGIVEDRUGIDSE IN (289839402,289769909) AND BEFORECOSIGNEREMPNO IS not NULL;

-------------------------------------

Typ=96 Len=6: 0,0,0,0,10,0
Typ=96 Len=6: 80,48,48,50,55,0
 

 

看這兩筆資料,很明顯最後一個byte被塞了acciss碼0的字元,

ascii中0代表 空字元 Null character

理論上,文字欄位不應該有文字後又加了一個null字元,

也難怪套上oracle nvl()還檢查,還真的不會回應任何對應的欄位,

我們來看,真正欄位值為null時的asscii應該是什麼?

 

create table test1
as 
select * from dual;

alter table test1
add a varchar2(1 byte); 

insert into test1
select 'x',null from dual;

commit;

select dump(a) from test1;

-------------------------------------

Typ=1 Len=1: 49
NULL
 

從上面的測試我們知道,真正的NULL欄位dump出來的質應該是NULL,而不是0,

當你程式把null 的ascii值 0 給塞進資料庫裡就是一件,對資料庫來說,這個時候欄位有ascii 值,資料庫就不認為是NULL了。

 

update test1 set a=chr(0) where dummy='x';    --我們手動塞一個ascii 為0的值到資料庫中(ascii 0 : Null)

commit;

select dump(a),nvl(a,'is null'),a.* from test1 a;

-------------------------------------

Typ=1 Len=1: 49    1    X    1
Typ=1 Len=1: 0            x    
 

上面的測試很清楚知道,ascii 0 其實還是有字符的,只是這個字符代表的是null,但對資料庫的欄位來說,欄位不是null的,很繞口對吧?

 

那空白呢?

我們也來順便測試一下

 

insert into test1
select 'y',chr(32) from dual;     --我們塞一個ascii 32 來當成空白

insert into test1
select 'y',' ' from dual;              --我們塞一個空白字元進去

commit;

select dump(a),length(a),a.* from test1 a where dummy='y';
 

-------------------------------------

Typ=1 Len=1: 32    1    y     
Typ=1 Len=1: 32    1    y     
 

這邊實驗的結果,我們可以發現,輸入空白,ascii碼為 32,跟你使用chr(32)的方式是一樣的,

所以ascii空白對資料庫來說,就是空白。

 

 

arrow
arrow
    全站熱搜

    噗噗噗的潛水珽 發表在 痞客邦 留言(0) 人氣()