Oracle 10和JDBC:如何使CHAR在比较时忽略尾随空格?

时间:2009-03-02 17:39:29

标签: oracle jdbc char

我有一个

的查询
  

......在哪里PRT_STATUS ='ONT'......

prt_status字段定义为CHAR(5)。所以它总是用空格填充。查询不匹配任何结果。要使此查询起作用,我必须

  

... WHERE 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'是一个文字,因此使用填充方式进行比较。

4 个答案:

答案 0 :(得分:8)

请注意Oracle compares CHAR values using blank-padded comparison semantics.

来自Datatype Comparison Rules

  

Oracle使用空白填充比较   语义只有当两个值都在   比较是表达的   数据类型CHAR,NCHAR,文本文字,   或者USER返回的值   功能

在您的示例中,'ONT'是作为绑定参数传递的,还是以文本方式内置到查询中,如图所示?如果是绑定参数,则确保将其绑定为类型CHAR。否则,请验证使用的客户端库版本,因为Oracle的旧版本(例如v6)将具有CHAR的不同比较语义。

答案 1 :(得分:1)

如果您无法更改数据库表,则可以修改查询。

RTRIM的一些替代方案:

  

..在哪里PRT_STATUS喜欢'ONT%'......

     

.. WHERE PRT_STATUS ='ONT'... - T

后面有2个空格      

.. WHERE PRT_STATUS = rpad('ONT',5,'')......

答案 2 :(得分:0)

我会在db中将CHAR(5)列更改为varchar2(5)。

答案 3 :(得分:0)

您可以在查询中使用强制转换操作:

... WHERE PRT_STATUS=cast('ONT' as char(5))

或者以更通用的JDBC方式:

... WHERE PRT_STATUS=cast(? as char(5))

然后在您的JDBC代码中使用statement.setString(1, "ONT");