OCCI处理CHAR类型字符串变量的不同

简介:

问题背景

一个旧应用,原先应用是用proc写的,9i的库,如今应用须要改为使用OCCI,当中有一段查询逻辑:select ... where upper(state)=upper(:1)。

(此处请不要纠结于where条件中state字段使用了upper函数,由于此表数据量非常小,且其历史比較悠久,未建索引。

)

相应表中定义的state字段类型是char(3),但此处查询条件变量的值可能是两位,比如'NY'。


现象

1. 使用sqlplus运行select ... where upper(state)=upper(:1)能够正常显示。

2. 使用sql developer运行select ... where upper(state)=upper(:1)能够正常显示。

3. 使用proc运行,能够正常显示。

4. 使用OCCI方式。运行,显示为空


解决

对于使用OCCI的方式。将其改写为:

1. select ... where trim(upper(state)) = trim(upper(:1));

2. select ... where upper(state) = upper(rpad(:1, 3, ' '));


原理判断

1. 首先char和varchar2类型的最大差别,就是char是定长类型,varchar2是不定长类型。网上包含官方文档有非常多介绍了,用样例简单讲,就是:

create table test(

a char(25),

b varchar2(25)

);

insert into test values('a', b');

a字段存储的是“a+24个空格”。b字段存储的就是“b”。

能够从select a, length(a), b, length(b) from test;进一步验证。

即char会占用最大的存储空间,varchar2则仅仅会存储实际占用的空间。

2. 从http://www.itpub.net/thread-1014651-1-1.html帖子能够看出,和这个问题同样。判断是OCCI的bug导致。

尽管翻了OCCI的文档。并未找到对这个问题的解释。但从Oracle官方文档对填补空格比較字符串的语义说明,能够看出一些端倪:
Blank-Padded Comparison Semantics
If the two values have different lengths, then Oracle first adds blanks to the end of the shorter one so their lengths are equal. Oracle then compares the values character by character up to the first character that differs. The value with the greater character in the first differing position is considered greater.
If two values have no differing characters, then they are considered equal. This rule means that two values are equal if they differ only in the number of trailing blanks. Oracle uses blank-padded comparison semantics only when both values in the comparison are either expressions of datatype CHAR, NCHAR, text literals, or values returned by the USER function.

Nonpadded Comparison Semantics
Oracle compares two values character by character up to the first character that differs. The value with the greater character in that position is considered greater. If two values of different length are identical up to the end of the shorter one, then the longer value is considered greater. If two values of equal length have no differing characters, then the values are considered equal. Oracle uses nonpadded comparison semantics whenever one or both values in the comparison have the datatype VARCHAR2 or NVARCHAR2.

即对于CHAR、NCHAR类型的字符串比較。Oracle首先会自己主动补齐空格,然后再一个字符一个字符地比較,不会由于空格数不同觉得两者不同。且这个过程应该不是简单的trim()操作,由于假设字段有索引仍会使用。

对于VARCHAR2、NVARCHAR2类型的字符串比較,因为其不会自己主动存储空格,假设有空格,则也是作为有意义的存储,因此不存在上述问题。

综上所述。对于CHAR类型。不应该由于补空格位数的问题,作为比較的根据。除非使用的where a = trim('a'),人为对值进行处理,因此有理由怀疑OCCI对CHAR类型字符串的比較。至少和其它终端查询的逻辑不同。至于是不是bug。须要看看有没有官方的解释了




本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5313981.html,如需转载请自行联系原作者

相关文章
|
2月前
|
存储 C语言
使用 sizeof 操作符计算int, float, double 和 char四种变量字节大小
【10月更文挑战第13天】使用 sizeof 操作符计算int, float, double 和 char四种变量字节大小。
104 1
|
3月前
|
存储 Java Windows
java基础(9)数据类型中的char类型以及涉及到的转义字符
Java中的char类型可以存储一个中文字符,因为它占用两个字节。转义字符允许在代码中使用特殊字符,例如`\n`表示换行,`\t`表示制表符,`\\`表示反斜杠,`\'`表示单引号,`\"`表示双引号。可以使用`\u`后跟Unicode编码来表示特定的字符。
70 2
java基础(9)数据类型中的char类型以及涉及到的转义字符
|
2月前
|
SQL 存储 关系型数据库
SQL判断CHAR类型字段不为空的方法与技巧
在SQL查询中,判断一个CHAR类型字段是否不为空是一个常见的需求
|
4月前
|
存储 自然语言处理 编译器
C语言中的char类型
C语言中的char类型
303 1
|
7月前
|
存储 关系型数据库 MySQL
MySQL字段的字符类型该如何选择?千万数据下varchar和char性能竟然相差30%🚀
本篇文章来讨论MySQL字段的字符类型选择并深入实践char与varchar类型的区别以及在千万数据下的性能测试
MySQL字段的字符类型该如何选择?千万数据下varchar和char性能竟然相差30%🚀
new String()定义字符串为空,char[] chs = {‘a‘,‘b‘,‘c‘} String s2 = new String(chs) 输出abc,byte定99为a
new String()定义字符串为空,char[] chs = {‘a‘,‘b‘,‘c‘} String s2 = new String(chs) 输出abc,byte定99为a
|
6月前
详细解读C++char类型函数
详细解读C++char类型函数
62 0
|
6月前
|
C++
E0144 “const char *“ 类型的值不能用于初始化 “char *“ 类型的实体
E0144 “const char *“ 类型的值不能用于初始化 “char *“ 类型的实体
114 0
|
存储 关系型数据库 MySQL
面试时被这样一个问:”存储MD5值应该用VARCHAR还是用CHAR?
一个5年工作经验的小伙伴,在面试的时候被这样一个问题。说”存储MD5值应该用VARCHAR还是用CHAR“,他一时间不只如何选择,感觉用VARCHAR也可以,用CHAR也行。希望我来帮忙分析一下。
122 0
|
4月前
|
存储 数据管理 数据库