问题背景

一个旧应用,原先应用是用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. js 之 json

    /*JSON语法数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组 JSON 数据的书写格式是:名称/值对名称/值对包括字段名称(在双引号中),后面写一个冒号,然后是值;如"myw ...

  2. linux下date命令实现时间戳与日期的转换

    1.查看指定时间的时间戳    查看当前时间  #date +%s    查看指定时间  #date -d 2008-01-01 +%s   1199116800  #date -d 20080101 ...

  3. 原生js实现吸顶导航和回到顶部特效

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Coursera《machine learning》--(2)单变量线性回归(Linear Regression with One Variable)

    本笔记为Coursera在线课程<Machine Learning>中的单变量线性回归章节的笔记. 2.1 模型表示 参考视频: 2 - 1 - Model Representation ...

  5. Java反射的理解

    反射的作用:   1.运行时检查类的结构 2.运行时更改类的字段值 3.调用类的方法   准备知识:   Class类:虚拟机为每一个对象保存的一份对象所属类的清单: static Class for ...

  6. Android ListView列表控件的简单使用

    ListView 列表是我们经常会使用的控件, 如果想要自定义里面的显示的话是挺麻烦的, 需要新建XML.Class SimpleAdapter这两个文件, 较为麻烦. 如果我们只是想显示两.三行文字 ...

  7. 从1500万用户巅峰跌落的app,血泪回顾图片社交那些坑

    饭桌君说 第八届小饭桌创业课堂来了一位特殊的分享嘉宾,他曾经参与了一款当时极具风头的图片社交app的创始团队,靠谱团队,用户量急速上升到1500万,公司获得A轮……一切看上去都那么美好. 可是,由于各 ...

  8. Reporting Services 钻取报表、子报表

    一.钻取报表 1.概念 钻取报表是指用户通过单击其他报表中的链接打开的报表.钻取报表通常包含某原始汇总报表中所包含的某项的详细信息. 例如,在此图中,销售额汇总报表列出了销售订单和总额.当用户单击该汇 ...

  9. h.264 scanning process for transform coefficients

    宏块在经过变换.量化后,得到大小为4x4或者8x8的矩阵,矩阵中的数据被称为transform coefficient levels.这些level在后面会被用于熵编码,因此我们需要把矩阵按照一定顺序 ...

  10. lc面试准备:Candy

    1 题目 There are N children standing in a line. Each child is assigned a rating value. You are giving ...