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。须要看看有没有官方的解释了。
OCCI处理CHAR类型字符串变量的不同的更多相关文章
- C中变量名通过宏定义转换成char*类型字符串
#include <iostream> #include <stdlib.h> #define name_to_str(name)(#name) int main() { in ...
- c++中char类型字符串拼接以及int类型转换为char类型 && 创建文件夹
如下所示: #include <iostream> #include <windows.h> #include <cstring> using namespace ...
- 对char类型的理解以及对补码的理解分析
今天遇到这样一个小程序,觉得当中有些问题很容易让人忽略的! 这个程序代码如下: 程序的结果为: 我想很多像我一样的小白可能才开始是想不明白为什么最后的结果是255吧!首先,我们得知道 strlen() ...
- C++ char 类型:字符型和最小的整型
C++ 中没有 byte,Java 中有 byte. 但是 C++ 有 char,char 是可用来放整数的最小字节类型. #include <iostream> int main() { ...
- C# - char类型的一些介绍
Char C#里面的char,其实就是System.Char类型的别名,它代表一个Unicode字符(是这样吗?),占用两个字节. 例如:char c = ‘A’; char占用两个字节,也就是16位 ...
- C++中char类型的溢出问题
C++中什么经常会运用到char类型,也会将char类型作为循环语句的循环条件,但往往这里最容易出现错误,容易出现溢出,进入死循环.这里我们就来简单介绍下为什么会出现这种情况. 首先,了解下char类 ...
- python元组类型的变量以及字符串类型的变量作为参数进行传值
今天做selenium元素对象剥离时(我把元素对象都放到了元组类型的变量中,格式:user = (“id”,“X-Auto-2”)),遇到一个元组变量,以及str字符串变量一起作为参数传值的问题,发现 ...
- 字符、字符串和文本的处理之Char类型
.Net Framework中处理字符和字符串的主要有以下这么几个类: (1).System.Char类 一基础字符串处理类 (2).System.String类 一处理不可变的字符串(一经创建,字符 ...
- 字符串类型的变量,也要进行alloc内存分配之后才能用
nss_upperName =[[NSStringalloc]initWithString:labTopTitle.text]; nss_upperName =labTopTitle.text; // ...
随机推荐
- transcode_step()在转码过程中对pts、dts、duration的处理
对pts.dts.duration的处理主要集中在两大函数里面 1.process_input()读入数据并处理,放到滤镜里面 2.reap_filters()从滤镜读出数据,处理后写入文件 proc ...
- Axure RP的版本控制
首先介绍一下Axure RP,Axure的发音是Ask-Sure,RP是Rapid Prototype的缩写,写到这里你知道了这是一款原型绘画工具.本节主要介绍Axure RP的版本管理也即Axure ...
- go 语言与循环
package main import "fmt" type Employee struct{name string; age int} func displayName(e *E ...
- bzoj 3594: [Scoi2014]方伯伯的玉米田 dp树状数组优化
3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 314 Solved: 132[Submit][Sta ...
- [BZOJ 2440] [中山市选2011] 完全平方数 【二分 + 莫比乌斯函数】
题目链接:BZOJ - 2440 题目分析 首先,通过打表之类的方法可以知道,答案不会超过 2 * k . 那么我们使用二分,对于一个二分的值 x ,求出 [1, x] 之间的可以送出的数有多少个. ...
- 如何使用 Laravel Facades ?
Facade 布局是在面向对象编程中经常使用的一种软件设计布局方式.Facade 实际上是一种包括复杂函数库的类,提供了更加简洁易读的接口.Facade 布局还能为一组结构复杂.设计简陋的 API 提 ...
- Android 设置隐式意图
AndroidManifest.xml对于被调用的activity: <activity android:name="com.wuyou.twoactivity.OtherActivi ...
- 如何测试 Android 中的定时事件
测试定时事件不太容易,比如要测试 AlarmManager 中定时明天4点的一个事件,你总不能等到明天4点再看看吧. Roman Nurik 提供了两个用来测试定时事件的命令:adb shell du ...
- Java System类看到的一点小记
System类 位置java.lang包中 是final类,不能被继承,不能被修改 ,不能被实例化 private System(){}私有的构造函数,不允许被其他对象进行实例化 public fin ...
- Android实用代码七段(一)
前言 这里积累了一些不常见确又很实用的代码,每收集7条更新一次,希望能对大家有用. 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnblogs.com 农民伯伯: htt ...