Oracle中'AA '和'AA'是否相等(正确否不确定)

 

今天在论坛看到一个比较有趣的问题:’AA ’和’AA’是否相等。其中第一个字符串中包含一个空格。


9| |&rJh3Wr0

有人认为二者不相等,也有人认为二者相等。其实无论哪种说法都是对的。

首先通过SQL证明二者不相等:

SQL> SELECT DECODE('AA ', 'AA', '=', '!=') FROM DUAL;

DEITPUB个人空间.]^)g%bP
--ITPUB个人空间U&_5^$w;R:d3p
!=

下面证明二者相等:

SQL> SELECT CASE WHEN 'AA ' = 'AA' THEN '=' ELSE '!=' END FROM DUAL;

CA
vH6KJ"DF&R0--
](l h`Wp l2Y;w0=

为什么DECODE和CASE得到的结果不一样呢,到底’AA ’和’AA’是否相等呢,这个要从ORACLE的数据类型说起。

Oracle表示字符串有两种常用类型,定长的CHAR类型和变长的VARCHAR2类型。

比较是否相等,首先要确定数据类型:

对于VARCHAR2类型,二者显然是不等的。一个长度是3,另一个长度是2。

而对于CHAR类型,二者确实是相等的,因此Oracle会自动用空格去补齐位数。所以说讨论’AA ’和’AA’是否相等,首先要确定数据类型。

下面说明DECODE和CASE为什么得到不同的结果。

首先明确一点:DECODE是函数,而CASE是Oracle提供的SQL语句。

SQL> SELECT DUMP('AA '), DUMP('AA') FROM DUAL;

DUMP('AA') DUMP('AA')ITPUB个人空间E-B5R`0A/ Q;i r6n;vg/{
---------------------- -------------------ITPUB个人空间xI_[n!w:R J.Y Z
Typ=96 Len=3: 65,65,32 Typ=96 Len=2: 65,65

Oracle会自动认为字符串常量为CHAR类型(type96为char类型)。因此,在CASE语句中,比较的是两个CHAR类型的字符串,因此得到相等的结果。

如果强制将其转化为VARCHAR2类型,则会得到不等的结果:

SQL> SELECT CASE WHEN CAST('AA ' AS VARCHAR2(3)) = CAST('AA' AS VARCHAR2(3))
d`!ncM6Qn,Im&Hc0 2 THEN '=' ELSE '!=' END FROM DUAL;

CAITPUB个人空间Nq$Oba"^mhBR;r
--ITPUB个人空间,qC{T'~!l"N)t
!=

既然默认是CHAR类型,为什么DECODE可以得到不等的结果呢:

SQL> DESC SYS.STANDARD

.

.

.

FUNCTION DECODE RETURNS NUMBERITPUB个人空间^dTjc
参数名称 类型 输入/输出默认值?ITPUB个人空间2q*N{%O)~
------------------------------ ----------------------- ------ --------ITPUB个人空间t+h#H!b!@)J$ul
EXPR NUMBER IN
Q,M4dEQ'la0 PAT NUMBER INITPUB个人空间0KV.?J8F
RES NUMBER IN
h h8Mp i8Ve0FUNCTION DECODE RETURNS VARCHAR2ITPUB个人空间 u^@^ q1t
参数名称 类型 输入/输出默认值?ITPUB个人空间7IqLi&_ J_
------------------------------ ----------------------- ------ --------
+bJ E!i%n8~0 EXPR NUMBER INITPUB个人空间3E6Lgn yzr
PAT NUMBER INITPUB个人空间1Xznqxz2C1dxx
RES VARCHAR2 IN
i)xX]9X'ur*T2q/E0FUNCTION DECODE RETURNS DATE
/L/TKa}}8gp3n1hB y0参数名称 类型 输入/输出默认值?ITPUB个人空间 _(R'e+Qf0L'{;~:u'lr
------------------------------ ----------------------- ------ --------ITPUB个人空间|3U+L0h&o:Ad$Xc0Cd O
EXPR NUMBER INITPUB个人空间/4bsC T6y cK2Uf
PAT NUMBER IN
?*?3lw ?@W-F0 RES DATE INITPUB个人空间G:c:YC%il:aMb?
FUNCTION DECODE RETURNS NUMBERITPUB个人空间.xt$]BU
参数名称 类型 输入/输出默认值?ITPUB个人空间2xW%i6T,x k"MD.@
------------------------------ ----------------------- ------ --------
,BsT0@&rl7a^M0 EXPR VARCHAR2 IN
5y#q:Ai)e An0 PAT VARCHAR2 IN
*kls gig0 RES NUMBER INITPUB个人空间9G'HW$fA Nh W
FUNCTION DECODE RETURNS VARCHAR2
'd3R5vx1n)H0q9O0参数名称 类型 输入/输出默认值?
%JE _8[qr0------------------------------ ----------------------- ------ --------
3[ Cg)?Z"B0 EXPR VARCHAR2 IN
;A:mz"jySBB:t0IZ0 PAT VARCHAR2 IN
}[!DbiSG0 RES VARCHAR2 INITPUB个人空间lB7SpX {7n.OJ
FUNCTION DECODE RETURNS DATEITPUB个人空间 VP5aU1Ce^*EZ[
参数名称 类型 输入/输出默认值?
N9M'B g#} l(y-~0------------------------------ ----------------------- ------ --------
fy#_E9B(O0 EXPR VARCHAR2 IN
:a(u NW&x!y%| b*D0 PAT VARCHAR2 INITPUB个人空间 y~$o~.?d"}$~*b4I7eD
RES DATE IN
&/CA&c`0FUNCTION DECODE RETURNS NUMBERITPUB个人空间1bNp `j
参数名称 类型 输入/输出默认值?ITPUB个人空间%oH9/Ma4k._(l.a
------------------------------ ----------------------- ------ --------ITPUB个人空间.i[*Kr/@)V:C.L
EXPR DATE IN
3Q#YloO?!A'xK0 PAT DATE INITPUB个人空间$wbl"JcBN
RES NUMBER IN
G1H lmOJ,y)E0FUNCTION DECODE RETURNS VARCHAR2ITPUB个人空间V)Vq`;/D
参数名称 类型 输入/输出默认值?
]+/h0o_ F8w0------------------------------ ----------------------- ------ --------
4^1T/lJ,t:fh;@0 EXPR DATE INITPUB个人空间!g:c C2]N"SAZ0e,O
PAT DATE IN
_0j6F]bu~uF~0 RES VARCHAR2 INITPUB个人空间,o'~ k,iL
FUNCTION DECODE RETURNS DATE
d4z H+D1vVA u0参数名称 类型 输入/输出默认值?
,U0ki `#iB0------------------------------ ----------------------- ------ --------
v7/:S2c3z0 EXPR DATE INITPUB个人空间 P cTr-yk!v.Q*rPP
PAT DATE INITPUB个人空间A.a5V0{+i?0qo
RES DATE IN
yq#j {PU$h&n!W1tf1j0FUNCTION DECODE RETURNS STANDARDITPUB个人空间&d_'`/w ZW0H }{%X
参数名称 类型 输入/输出默认值?
PF$VY%r3z0------------------------------ ----------------------- ------ --------ITPUB个人空间Q'K!EdBJ.C
EXPR STANDARD INITPUB个人空间&Pt+t9e-Dw"pR8[r
PAT STANDARD IN
2d+k({;uyDYW0 RES STANDARD INITPUB个人空间|"D"q t)M/e
FUNCTION DECODE RETURNS STANDARD
}'Wf/{$k*q0参数名称 类型 输入/输出默认值?
mH#l+z3n$/$ej;S7S4Yk0------------------------------ ----------------------- ------ --------ITPUB个人空间 ZY4bg:_ k
EXPR STANDARD INITPUB个人空间%c$vg7T!W}P L
PAT STANDARD INITPUB个人空间g/j`?t(E
RES STANDARD IN

.

.

.

通过查询标准包中DECODE函数的定义,发现DECODE函数的输入字符串类型统一为VARCHAR2,而不包含CHAR类型的重载。因此,在传递给DECODE函数前,两个CHAR类型已经转化为VARCHAR2类型,最终比较的是两个VARCHAR2类型,因此得到不等的结果。

类似的方法,如果将’AA’转化为CHAR(3)类型,那么DECODE函数也可以得到相等的结果:

SQL> SELECT DECODE('AA ', CAST('AA' AS CHAR(3)), '=', '!=') FROM DUAL;

DEITPUB个人空间:H/'i,h [t2Vq
--ITPUB个人空间+MH,w,xN#n8_4q
=

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值