问题背景

一个旧应用,原先应用是用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. winform下mapxtreme2008 v7.0 生成release版提示找不到dll问题

    在winform下基于mapxtreme2008 v7.0 生成了一个地图软件,用debug方式运行无误,但改为release版时提示缺少一大堆dll,如: 无法从C:\Program Files ( ...

  2. predis如何实现phpredis的pconnect方法

    predis和phpredis都是redis的php客户端,区别可以看这里,这里不赘述. phpredis是php扩展,由C语言编写,诞生较早,很多PHPer都熟悉. predis是用PHP语言编写, ...

  3. partial函数-python学习

    一个函数可以有多个参数,而在有的情况下有的参数先得到,有的参数需要在后面的情景中才能知道,python 给我们提供了partial函数用于携带部分参数生成一个新函数. def add(a,b,c=2) ...

  4. MAC Python环境配置以及安装Pycharm 5.4.0

    安装XCODE 去APP STORE下载,然后安装.免费 终端执行 xcode-select --install 安装或更新命令行开发工具 安装Pycharm 下载软件 官网:https://www. ...

  5. app上传 需要的icon

    如果提交的ipa包中,未包含必要的Icon就会收到类似的通知,为什么偏偏是Icon-76呢? 因为我们开发的游戏,默认是支持iphone以及ipad的,根据官方提供的参考 Icon-76.png是必须 ...

  6. javascript学习代码--点击按钮显示内容

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. Keil 程序调试窗口

    上一讲中我们学习了几种常用的程序调试方法,这一讲中将介绍Keil提供各种窗口如输出窗口.观察窗口.存储器窗口.反汇编窗口.串行窗口等的用途,以及这些窗口的使用方法,并通过实例介绍这些窗口在调试中的使用 ...

  8. 编写优质无错C程序秘诀!《经验谈》

    这里我将陆续给大家载出我在以前学习和编写c代码时遇到的问题和解决方法.学习的心得,有些是经过查询一些曾经参加微软microsoft的开发小组的老程序员的书籍和资料后提供给大家! 首先,当发现错误时,要 ...

  9. Principles of Motion Sensing

    Principlesof Motion Sensing Various sensors capable of detecting motionin free space have been comme ...

  10. 在非UI线程中更改UI(Delphi使用隐藏窗口来处理,QT使用信号槽)

    在Delphi里我记得是使用TThread.Synchronize(TThreadMethod),原理是利用了一个隐藏窗口来处理. 在QT Debug模式一下,碰到了同样的问题,显示错误: canno ...