很多开发者有时候会遇到Oracle数据库中创建的字符串两端具有不对称不等式的疑惑:’就像’ABC’ 并非’CBA’,比较运算将它们分别作为不同值处理,这是为什么?
要弄清楚这一现象,我们首先要知道一下Oracle数据库的字符集模型。Oracle的字符集模型在1999年的第六版中正式出现,它是建立在Unicode字符集上的,Unicode字符集使用十六进制编码,可以覆盖几乎所有文字系统,不管语言或字母顺序。由于Unicode字符集存在一些宽字节和窄字节的概念,在Oracle中使用char、varchar2两种不同类型的字符串来存储文本,char是固定长度的宽字节,而varchar2是可变长度的窄字节。
在Oracle中,如果同时使用char和varchar2类型的字符串进行比较,sql引擎会自动对比较对象做转换:如果一个字符串是char类型的,另一个字符串是varchar2类型,sql引擎会先把varchar2类型的字符串转换为char类型。
举例子来说,如果我们使用以下sql语句:
select * from Employees where name = ‘ABC’;
其中name的类型为char,而这里的‘ABC’是varchar2类型的。由于Sql引擎会自动把varchar2类型转换为char类型,所以它会先把’ABC’转换为’ABC^@'(其中^@ 为一个特殊字符),而name所存储的实际上是’ABC^@’,这会造成name != ‘ABC’的不等式疑惑。
要解决这一不等式疑惑,可以在查询语句中显式地为varchar2类型转换为char类型:
select * from Employees where name = to_char(‘ABC’);
与此所对应的,如果使用varchar2类型查询char类型字段,可以使用to_varchar2函数进行转换:
select * from Employees where name = to_varchar2(‘ABC^@’);
通过以上的讲解,我们可以看出,Oracle数据库中比较字符串的不等式疑惑,其实仅仅是由于char、varchar类型不一致造成的,要解除这一不等式疑惑,可以显式地对字符串进行类型转换即可。