szhswl
          宋針還的個(gè)人空間
                  在今天開(kāi)發(fā)過(guò)程中,發(fā)現(xiàn)了一查詢(xún)結(jié)果很怪異,一GOOGLE下才知道是ORACLE對(duì)CHAR類(lèi)型處理的問(wèn)題,在ORACLE中對(duì)CHAR的處理是自動(dòng)添加空格,比如char(8)存儲(chǔ)'2007-11',則在后面自動(dòng)添加空格,所以導(dǎo)致以下很多查詢(xún)怪異問(wèn)題(在表test中有字段month為char(8),存儲(chǔ)著'2007-11'一條數(shù)據(jù)):
                  select * from test where month='2007-11'     ---能查出該條數(shù)據(jù)
                  select * from test where month='2007-11    '    ---后面含N個(gè)空格,能查出該條數(shù)據(jù)
                  select * from test where month=to_char(to_date('200711','yyyy-mm'),'yyyy-mm')       ---不能查出該條數(shù)據(jù)
                  select * from test where trim(month)=to_char(to_date('200711','yyyy-mm'),'yyyy-mm')   ---能查出該條數(shù)據(jù)

          這里再比較一下char,varchar,varchar2的區(qū)別:
          1.CHAR的長(zhǎng)度是固定的,而VARCHAR2的長(zhǎng)度是可以變化的, 比如,存儲(chǔ)字符串“abc",對(duì)于CHAR (20),表示你存儲(chǔ)的字符將占20個(gè)字節(jié)(包括17個(gè)空字符),而同樣的VARCHAR2 (20)則只占用3個(gè)字節(jié)的長(zhǎng)度,20只是最大值,當(dāng)你存儲(chǔ)的字符小于20時(shí),按實(shí)際長(zhǎng)度存儲(chǔ)。
          2.CHAR的效率比VARCHAR2的效率稍高。
          3.目前VARCHAR是VARCHAR2的同義詞。工業(yè)標(biāo)準(zhǔn)的VARCHAR類(lèi)型可以存儲(chǔ)空字符串,但是oracle不這樣做,盡管它保留以后這樣做的權(quán)利。Oracle自己開(kāi)發(fā)了一個(gè)數(shù)據(jù)類(lèi)型VARCHAR2,這個(gè)類(lèi)型不是一個(gè)標(biāo)準(zhǔn)的VARCHAR,它將在數(shù)據(jù)庫(kù)中varchar列可以存儲(chǔ)空字符串的特性改為存儲(chǔ)NULL值。如果你想有向后兼容的能力,Oracle建議使用VARCHAR2而不是VARCHAR。 

          何時(shí)用char?何時(shí)用varchar2?
                     CHAR與VARCHAR2是一對(duì)矛盾的統(tǒng)一體,兩者是互補(bǔ)的關(guān)系.
          VARCHAR2比CHAR節(jié)省空間,在效率上比CHAR會(huì)稍微差一些,即要想獲得效率,就必須犧牲一定的空間,這也就是我們?cè)跀?shù)據(jù)庫(kù)設(shè)計(jì)上常說(shuō)的‘以空間換效率’。
             VARCHAR2雖然比CHAR節(jié)省空間,但是如果一個(gè)VARCHAR2列經(jīng)常被修改,而且每次被修改的數(shù)據(jù)的長(zhǎng)度不同,這會(huì)引起‘行遷移’(Row Migration)現(xiàn)象,而這造成多余的I/O,是數(shù)據(jù)庫(kù)設(shè)計(jì)和調(diào)整中要盡力避免的,在這種情況下用CHAR代替VARCHAR2會(huì)更好一些。

          個(gè)人意見(jiàn)是使用varchar2,因?yàn)橛胏har總要特別注意自動(dòng)添加空格的問(wèn)題,粗粗說(shuō)一下這個(gè)問(wèn)題,有什么錯(cuò)誤還請(qǐng)指教。


          ---------------------------------------------------------------------------------------------------------------------------------
          說(shuō)人之短,乃護(hù)己之短。夸己之長(zhǎng),乃忌人之長(zhǎng)。皆由存心不厚,識(shí)量太狹耳。能去此弊,可以進(jìn)德,可以遠(yuǎn)怨。
          http://www.aygfsteel.com/szhswl
          ------------------------------------------------------------------------------------------------------ ----------------- ---------
          posted on 2007-12-11 15:18 宋針還 閱讀(2190) 評(píng)論(3)  編輯  收藏

          FeedBack:
          # re: oracle的char類(lèi)型對(duì)空格的怪異處理
          2007-12-12 10:29 | jeasonzhao
          我覺(jué)得,為了安全起見(jiàn),還是實(shí)現(xiàn)varCHAR,因?yàn)樽罱K這個(gè)Trim的操作還是要做的,不管是客戶(hù)端還是SQL語(yǔ)句,都會(huì)帶來(lái)性能開(kāi)銷(xiāo),與其這樣,還不如從源頭上掐斷  回復(fù)  更多評(píng)論
            
          # re: oracle的char類(lèi)型對(duì)空格的怪異處理
          2008-01-08 12:25 | 肖遙
          日期用char存本來(lái)就是你的不對(duì)了  回復(fù)  更多評(píng)論
            
          # re: oracle的char類(lèi)型對(duì)空格的怪異處理
          2008-02-21 08:51 | yangzl
          樓上不要只盯住日期的問(wèn)題,其實(shí)varchar2和char的匹配確實(shí)存在問(wèn)題的  回復(fù)  更多評(píng)論
            

          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 锦州市| 沐川县| 当涂县| 舞阳县| 武平县| 全州县| 长顺县| 湘乡市| 杭锦后旗| 隆昌县| 韩城市| 深水埗区| 都安| 扶绥县| 怀来县| 榆树市| 四平市| 平山县| 武宁县| 肥西县| 高尔夫| 抚远县| 延边| 永州市| 绵阳市| 锡林浩特市| 汝阳县| 蒙阴县| 安远县| 当雄县| 高淳县| 墨脱县| 澎湖县| 南召县| 西宁市| 迁安市| 峨边| 临西县| 洪洞县| 江源县| 富裕县|