在Oracle數(shù)據(jù)庫中單引號是用來字符串引用的,不管是數(shù)字還是時間赎懦,當(dāng)你用單引號引用起來之后鞍帝,數(shù)據(jù)庫就會將其當(dāng)成字符串來對待。
如下兩句SQL:
select from users where age > 30
select from users where age > '30'
其中age字段是varchar格式舷暮,全部都是數(shù)字态罪,不要問我既然都是數(shù)字的為什么不用num類型。
當(dāng)兩個語句執(zhí)行的時候脚牍,發(fā)現(xiàn)第一個語句能準(zhǔn)確的篩選出我們想要的結(jié)果向臀,第二個語句雖然也可以執(zhí)行,但篩選出來的結(jié)果中age比30小的也出現(xiàn)了诸狭。
這時候我們疑問就來了券膀,按理來說君纫,第二個應(yīng)該才是正確的寫法,為什么第二個反而得不到我們想要的結(jié)果芹彬,第一個卻可以呢蓄髓?
第一個問題:
select from users where age > '30'
當(dāng)30加上單引號,其實(shí)就變成了兩個字符串之間比較大小了舒帮。
假如有一條age的值為4会喝,當(dāng)數(shù)據(jù)庫將'4'和'30'來比較大小的時候,第一步會用空格補(bǔ)全位數(shù)玩郊,實(shí)際比較的是'4'和’30’肢执,然后從左至右依次比較ascii碼大小,4的ascii碼是52译红,3的ascii碼是51预茄,所以’4’就比’30’大了,也就出現(xiàn)在我們的篩選結(jié)果中了
如果比較的是’3’和’30’侦厚,同樣的也會先去補(bǔ)全位數(shù)耻陕,第一位都是3然后比較第二位,第二位空格的ascii碼32刨沦,0的ascii碼是48诗宣,因此’3’就比’30’小了,好像沒毛病想诅,不過我們得明白其中的道理召庞。
梳理下規(guī)則
1.用空格補(bǔ)全字符長度短的一方;
2.從左至右依次比較ascii碼的大小
第二個問題:
第二個問題涉及到了數(shù)據(jù)隱式轉(zhuǎn)換侧蘸。
在oracle中裁眯,如果不同的數(shù)據(jù)類型之間關(guān)聯(lián),如果不顯式轉(zhuǎn)換數(shù)據(jù)讳癌,則它會根據(jù)以下規(guī)則對數(shù)據(jù)進(jìn)行隱式轉(zhuǎn)換穿稳。
什么意思呢,我們看上面的例子晌坤,age為varchar類型時逢艘,18為num類型,當(dāng)我們執(zhí)行select * from users where age > 30
的時候骤菠,oracle會把a(bǔ)ge的數(shù)據(jù)類型隱式轉(zhuǎn)換為num型它改,上面的語句其實(shí)等同于select * from users where to_number(age) > 30
數(shù)字類型比較大小,當(dāng)然就沒問題了商乎,所以篩選出的結(jié)果就是我們期望看到的了央拖;
當(dāng)然如果age字段里面有不能to_number的值,例如里面有一條記錄age是’十八’,那么上面的語句就會報(bào)錯了鲜戒。