oracle中的char和j,oracle中char与varchar2的区别
1.
CHAR的長度是固定的,而VARCHAR2的長度是可以變化的, 比如,存儲字符串“abc",對于CHAR
(20),表示你存儲的字符將占20個字節(包括17個空字符),在數據庫中它是以空格占位的,而同樣的VARCHAR2
(20)則只占用3個字節的長度,20只是最大值,當你存儲的字符小于20時,按實際長度存儲。
2.CHAR的效率比VARCHAR2的效率稍高。看來cscm_number應該設成
char(19)
3.目前VARCHAR是VARCHAR2的同義詞。工業標準的VARCHAR類型可以存儲空字符串,但是Oracle不這樣做,盡管它保留以后這樣做的權利。Oracle自己開發了一個數據類型VARCHAR2,這個類型不是一個標準的VARCHAR,它將在數據庫中varchar列可以存儲空字符串的特性改為存儲NULL值。假如你想有向后兼容的能力,Oracle建議使用VARCHAR2而不是VARCHAR。
何時該用CHAR,何時該用varchar2?
CHAR與VARCHAR2是一對矛盾的統一體,兩者是互補的關系.
VARCHAR2比CHAR節省空間,在效率上比CHAR會稍微差一些,即要想獲得效率,就必須犧牲一定的空間,這也就是我們在數據庫設計上常說的‘以空間換效率’。
VARCHAR2雖然比CHAR節省空間,但是假如一個VARCHAR2列經常被修改,而且每次被修改的數據的長度不同,這會引起‘行遷移’(Row
Migration)現象,而這造成多余的I/O,是數據庫設計和調整中要盡力避免的,在這種情況下用CHAR代替VARCHAR2會更好一些。
----以上內容由?華夏名網?搜集整理,如轉載請注明原文出處,并保留這一部分內容。
關于char和varchar2的比較的問題
關于char和varchar2的比較
char類型與char型或字符常量的比較,在比較時使用補齊空格的方式進行比較。varchar2類型與varchar2類型,char型和字符常量的比較,在比較時不補充空格,直接比較。create table tt(A1 CHAR(2) , A2 VARCHAR2(2)) ;
INSERT INTO TT VALUES('A','A') ;
insert into tt values('A','A ') ;
COMMIT ;
--CHAR型與字符常量的比較,字符常量作為char型處理
--與'A'比較,返回2行,也就是在比較時自動將常量'A'右補齊空格后比較
select * from tt where a1='A' ;
A1 A2
-- --
A?A
A?A
--與'A '比較,返回2行,也就是在比較時自動將常量'A'右補齊空格后比較
select * from tt where a1='A ' ;
A1 A2
-- --
A?A
A?A
--VARCHAR2與常量的比較,字符常量作為varchar2型處理--與'A'比較,返回1行,也就是在比較時對'A'不做處理,直接比較
select?* from TT WHERE A2='A';
A1 A2
-- --
A?A
--與'A '比較,返回1行,也就是在比較時對'A'不做處理,直接比較
select?* from TT WHERE A2='A ';
A1 A2
-- --
A?A
--當CHAR類型和VARCHAR2類型比較時,比較時對字段值是不作處理,直接比較的--讓A1和A2直接比較,此時是直接比較,有一條記錄的A1和A2相同
select * from tt where a1=a2 ;
A1 A2
-- --
A?A
但是當和decode函數配合使用時,出現不同的情況
使用A1字段
select?decode(a1,'A','AAAA','BBBB') FROM TT
;
DECODE(A1,'A','AAAA','BBBB')
----------------------------
BBBB
BBBB
雖然A1字段為char(2),但是比較時并沒有將常量'A'補空格再與字段A1做比較,而是直接進行比較,也就是將兩個比較字段按照varchar2類型處理的因此比較時認為字段A1不等于常量'A',出現兩條結果為'BBB'的記錄。
進一步驗證,
select?decode(a1,'A?','AAAA','BBBB') FROM TT ; --此處是兩個空格
DECODE(A1,'A','AAAA','BBBB')
----------------------------
BBBB
BBBB
還是返回兩條'BBB'的記錄,說明比較的不是按照char型的比較規則處理的。
使用A2字段
select?decode(a2,'A','AAAA','BBBB') FROM TT
;
DECODE(A2,'A','AAAA','BBBB')
----------------------------
AAAA
BBBB
此時是正常的VARCHAR2類型之間的比較,第一條記錄的A2字段等于'A',返回'AAA',第二行記錄的A2字段為’A
',比較時不等,返回'BBB'
當使用case表達式處理A1字段時,出現了與decode函數不同的處理結果
使用字段A1
select?case a1 when 'A' then 'AAA' else 'BBB' end
from tt ;
CASEA1WHEN'A'THEN'AAA'ELSE'BBB
------------------------------
AAA
AAA
在使用case語句中使用A1字段與常量'A'比較時,兩個比較值按照char型的比較規則處理,在右補空格之后進行比較,因此返回兩條記錄
進一步驗證,如下,
select?case a1 when
'A?' then 'AAA' else 'BBB' end
from tt ;
CASEA1WHEN'A'THEN'AAA'ELSE'BBB
------------------------------
AAA
AAA
此時將常量改為'A?',比較時仍視為char類型之間的比較,將字段A1補齊空格后與常量比較。
使用A2字段
select?case a2 when 'A' then 'AAA' else 'BBB' end
from tt ;
CASEA2WHEN'A'THEN'AAA'ELSE'BBB
------------------------------
AAA
BBB
此時是正常的VARCHAR2類型之間的比較,第一條記錄的A2字段等于'A',返回'AAA',第二行記錄的A2字段為’A
',比較時不等,返回'BBB'
總結,
在使用decode函數對char字段做比較時,需要注意即使比較的兩個字段都是char類型,但是decode函數是將其轉化varchar2類型
進行處理,不遵循char型的比較規則
===============================評論1============================
這幾天頻繁遇到char型數據比較的問題,總結如下:
對于char數據,在集合操作中,按照char的實際數據進行比較,而不是按照char型數據的比較規則進行的。
下面是一個簡單例子
create table t1(name char(10)) ;
create table t2(name char(20)) ;
begin
for i in 1..5 loop
insert into t1 values(to_char(i)) ;
insert into t1 values(to_char(i)) ;
end loop ;
commit;
end ;
select name from t1 minus select name from t2 ;
NAME
--------------------
1
2
3
4
5
如果按照char型的比較規則,則不應該有返回值。
select anem from t1 intersect select name from t2 ;
NAME
--------------------
無返回值,也說明集合操作時比較沒有按照char型的比較規則。
===============================評論2============================
對于decode和case對于char類型的差別,原因是由于case是表達式,而decode是函數。
函數中輸入參數和返回值一般都定義為varchar2類型。
多謝指點,一時沒有想到這里,看了一下decode函數的定義,如你所述,在使用decode的函數對char型數據進行類型轉換。
下面是decode的函數的參數定義。
SQL> desc
sys.standard.decode
Parameter
Type?Mode Default?
--------- ----------------------- ---- --------
(RESULT)?NUMBER?EXPR?NUMBER?IN?PAT?NUMBER?IN?RES?NUMBER?IN(RESULT)?VARCHAR2?EXPR?NUMBER?IN?PAT?NUMBER?IN?RES?VARCHAR2?IN?(RESULT)?DATE?EXPR?NUMBER?IN?PAT?NUMBER?IN?RES?DATE?IN(RESULT)?NUMBER?EXPR?VARCHAR2?IN?PAT?VARCHAR2?IN?RES?NUMBER?IN(RESULT)?VARCHAR2
EXPR?VARCHAR2?IN
PAT?VARCHAR2?IN?RES?VARCHAR2?IN?(RESULT)?DATE?EXPR?VARCHAR2?IN?PAT?VARCHAR2?IN?RES?DATE?IN(RESULT)?NUMBER?EXPR?DATE?IN?PAT?DATE?IN?RES?NUMBER?IN?(RESULT)?VARCHAR2?EXPR
總結
以上是生活随笔為你收集整理的oracle中的char和j,oracle中char与varchar2的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 唯一约束作用,想问下在表上
- 下一篇: soapui oracle groovy