问题背景

一个旧应用,原先应用是用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。须要看看有没有官方的解释了

OCCI处理CHAR类型字符串变量的不同的更多相关文章

  1. C中变量名通过宏定义转换成char*类型字符串

    #include <iostream> #include <stdlib.h> #define name_to_str(name)(#name) int main() { in ...

  2. c++中char类型字符串拼接以及int类型转换为char类型 && 创建文件夹

    如下所示: #include <iostream> #include <windows.h> #include <cstring> using namespace ...

  3. 对char类型的理解以及对补码的理解分析

    今天遇到这样一个小程序,觉得当中有些问题很容易让人忽略的! 这个程序代码如下: 程序的结果为: 我想很多像我一样的小白可能才开始是想不明白为什么最后的结果是255吧!首先,我们得知道 strlen() ...

  4. C++ char 类型:字符型和最小的整型

    C++ 中没有 byte,Java 中有 byte. 但是 C++ 有 char,char 是可用来放整数的最小字节类型. #include <iostream> int main() { ...

  5. C# - char类型的一些介绍

    Char C#里面的char,其实就是System.Char类型的别名,它代表一个Unicode字符(是这样吗?),占用两个字节. 例如:char c = ‘A’; char占用两个字节,也就是16位 ...

  6. C++中char类型的溢出问题

    C++中什么经常会运用到char类型,也会将char类型作为循环语句的循环条件,但往往这里最容易出现错误,容易出现溢出,进入死循环.这里我们就来简单介绍下为什么会出现这种情况. 首先,了解下char类 ...

  7. python元组类型的变量以及字符串类型的变量作为参数进行传值

    今天做selenium元素对象剥离时(我把元素对象都放到了元组类型的变量中,格式:user = (“id”,“X-Auto-2”)),遇到一个元组变量,以及str字符串变量一起作为参数传值的问题,发现 ...

  8. 字符、字符串和文本的处理之Char类型

    .Net Framework中处理字符和字符串的主要有以下这么几个类: (1).System.Char类 一基础字符串处理类 (2).System.String类 一处理不可变的字符串(一经创建,字符 ...

  9. 字符串类型的变量,也要进行alloc内存分配之后才能用

    nss_upperName =[[NSStringalloc]initWithString:labTopTitle.text]; nss_upperName =labTopTitle.text; // ...

随机推荐

  1. etTimeout与setInterval方法的区别

    etTimeout与setInterval方法的区别 setTimeout()用于设定在指定的时间之后执行对应的函数或代码.,在全局作用域下执行 setTimeout(code,time[,args… ...

  2. quick-x 触摸事件的新方法

    --[[ local function onTouch(event, x, y) print(event, x, y) if event == "began" then retur ...

  3. python中的buildin函数详解(第一篇)

    这会是很长的一个帖子,因为我打算从python最基础的东西开始,尝试去完全的掌握它,buildin中有一些常用的函数比如 abs, open, setattr, getattr, 大家都很了解他们的用 ...

  4. Android Learning:数据存储方案归纳与总结

    前言 最近在学习<第一行android代码>和<疯狂android讲义>,我的感触是Android应用的本质其实就是数据的处理,包括数据的接收,存储,处理以及显示,我想针对这几 ...

  5. 浅析Linux操作系统工作的基础

    环境:lubuntu 13.04   kernel 3.9.7 作者:SA12226265 katao 简介: 本文根据 Linux™ 系统工作基础的分析,对存储程序计算机.堆栈(函数调用堆栈)机制和 ...

  6. Java获取本机MAC地址

    为什么写这个呢?因为前几天看见网上有采用windows命令获取局域网和广域网MAC,查了查可以直接用JDK的方法. MAC可用于局域网验证,提高安全性. import java.net.InetAdd ...

  7. NEURAL NETWORKS, PART 3: THE NETWORK

    NEURAL NETWORKS, PART 3: THE NETWORK We have learned about individual neurons in the previous sectio ...

  8. Java语言基础(三) Java注释

    Java注释 Java提供了三种注释的方式: ①单行注释:// ②多行注释:/*  ...  */ ③归档(JavaDoc)注释: /** * 作者:heyiyong * 时间:2013年11月27日 ...

  9. 优雅的让Fragment监听返回键

    转载请注明出处:http://write.blog.csdn.net/postedit/40507387 Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.假设Fragm ...

  10. Node.js权威指南 (3) - Node.js基础知识

    3.1 Node.js中的控制台 / 19 3.1.1 console.log方法 / 19 3.1.2 console.error方法 / 20 3.1.3 console.dir方法 / 21 3 ...