打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
yangtingkun : Oracle中‘AA ‘和‘AA‘是否相等

===========================================================
作者: yangtingkun(http://yangtingkun.itpub.net)
发表于: 2006.05.12 00:28
分类: ORACLE
出处: http://yangtingkun.itpub.net/post/468/89983
---------------------------------------------------------------

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


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

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

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

DE
--
!=

下面证明二者相等:

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

CA
--
=

为什么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‘)
---------------------- -------------------
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))
2 THEN ‘=‘ ELSE ‘!=‘ END FROM DUAL;

CA
--
!=

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

SQL> DESC SYS.STANDARD

.

.

.

FUNCTION DECODE RETURNS NUMBER
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
EXPR NUMBER IN
PAT NUMBER IN
RES NUMBER IN
FUNCTION DECODE RETURNS VARCHAR2
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
EXPR NUMBER IN
PAT NUMBER IN
RES VARCHAR2 IN
FUNCTION DECODE RETURNS DATE
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
EXPR NUMBER IN
PAT NUMBER IN
RES DATE IN
FUNCTION DECODE RETURNS NUMBER
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
EXPR VARCHAR2 IN
PAT VARCHAR2 IN
RES NUMBER IN
FUNCTION DECODE RETURNS VARCHAR2
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
EXPR VARCHAR2 IN
PAT VARCHAR2 IN
RES VARCHAR2 IN
FUNCTION DECODE RETURNS DATE
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
EXPR VARCHAR2 IN
PAT VARCHAR2 IN
RES DATE IN
FUNCTION DECODE RETURNS NUMBER
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
EXPR DATE IN
PAT DATE IN
RES NUMBER IN
FUNCTION DECODE RETURNS VARCHAR2
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
EXPR DATE IN
PAT DATE IN
RES VARCHAR2 IN
FUNCTION DECODE RETURNS DATE
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
EXPR DATE IN
PAT DATE IN
RES DATE IN
FUNCTION DECODE RETURNS STANDARD
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
EXPR STANDARD IN
PAT STANDARD IN
RES STANDARD IN
FUNCTION DECODE RETURNS STANDARD
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
EXPR STANDARD IN
PAT STANDARD IN
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;

DE
--
=

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
oracle数据库中varchar2陷阱
Oracle笔记(九) 表的创建及管理
[MySQL]关于MySQL表设计应该注意的问题
ORACLE中的各种数据类型详细的介绍
稳!从Oracle迁移到PG该注意的要点都讲透了
数据库迁移 总结
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服