我有一个查询
......在哪里PRT_STATUS ='ONT'......
prt_status字段定义为CHAR(5).所以它总是用空格填充.查询不匹配任何结果.要使此查询起作用,我必须这样做
......在哪里rtrim(PRT_STATUS)='ONT'
哪个确实有效.
那很烦人.
同时,我有几个纯java DBMS客户端(Oracle SQLDeveloper和AquaStudio)对第一个查询没有问题,它们返回正确的结果.TOAD也没有问题.
我认为他们只是简单地将连接置于某种兼容模式(例如ANSI),因此Oracle知道CHAR(5)需要与后续字符进行比较.
如何使用我在应用程序中获得的Connection对象?
更新我无法更改数据库架构.
解决方案确实是Oracle将字段与传入参数进行比较的方式.
完成绑定后,字符串将通过PreparedStatement.setString()传递,它将类型设置为VARCHAR,因此Oracle使用未填充的比较 - 并且失败.
我尝试使用setObject(n,str,Types.CHAR).失败.反编译显示Oracle忽略CHAR并再次将其作为VARCHAR传递.
最终有效的变体是
setObject(n,str,OracleTypes.FIXED_CHAR);
它使代码不可移植.
UI客户端因其他原因而成功 - 它们使用字符文字,而不是绑定.当我键入PRT_STATUS ='ONT'时,'ONT'是一个文字,因此使用填充方式进行比较.
请注意,Oracle CHAR
使用空白填充比较语义来比较值.
从数据类型比较规则,
仅当比较中的两个值都是数据类型CHAR,NCHAR,文本文字或USER函数返回的值的表达式时,Oracle才使用空白填充比较语义.
在您的示例中,是'ONT'
作为绑定参数传递的,还是以文本方式内置到查询中,如图所示?如果是绑定参数,则确保将其绑定为类型CHAR
.否则,请验证使用的客户端库版本,因为Oracle的旧版本(例如v6)将具有不同的比较语义CHAR
.