Oracle JDBC和Oracle CHAR数据类型

Luk*_*der 14 oracle types jdbc char prepared-statement

我对Oracle JDBC驱动程序处理CHAR数据类型有一个棘手的问题.我们来看看这个简单的表:

create table x (c char(4));
insert into x (c) values ('a');  -- inserts 'a   '
Run Code Online (Sandbox Code Playgroud)

所以当我插入一些东西时CHAR(4),字符串总是用空格填充.当我执行这样的查询时也会这样做:

select * from x where c = 'a';    -- selects 1 record
select * from x where c = 'a ';   -- selects 1 record
select * from x where c = 'a   '; -- selects 1 record
Run Code Online (Sandbox Code Playgroud)

这里,常量'a'也用空格填充.这就是记录总是返回的原因.当使用JDBC执行这些查询时,这也PreparedStatement适用.现在最棘手的是当我想使用绑定变量时:

PreparedStatement stmt = 
  conn.prepareStatement("select * from x where c = ?");
stmt.setString(1, "a");    // This won't return any records
stmt.setString(1, "a   "); // This will return a record
stmt.executeQuery();
Run Code Online (Sandbox Code Playgroud)

这是一种解决方法:

PreparedStatement stmt = 
  conn.prepareStatement("select * from x where trim(c) = trim(?)");
stmt.setString(1, "a");    // This will return a record
stmt.setString(1, "a   "); // This will return a record
stmt.executeQuery();
Run Code Online (Sandbox Code Playgroud)

编辑:现在这些是约束:

  • 上面的解决方法是不可取的,因为它修改了和的内容,c并且?它使得使用索引c非常困难.
  • 从移动列CHARVARCHAR(它应该是,当然)是不可能的

编辑:这些限制的原因是因为我从jOOQ的开发人员的角度提出这个问题,jOOQ是一个数据库抽象库.所以我的要求是提供一个非常通用的解决方案,它不会破坏jOOQ客户端代码中的任何内容.这就是为什么我不是真正的解决方法的忠实粉丝.这就是为什么我无法访问该CHAR专栏的声明.但是,我仍然希望能够处理这种情况.

你会做什么呢?CHAR当我想忽略尾随空格时,处理数据类型的好习惯是什么?

Gar*_*ers 11

如果你想

stmt.setString(1, "a");    // This won't return any records
Run Code Online (Sandbox Code Playgroud)

要记录,请尝试

conn.prepareStatement("select * from x where c = cast(? as char(4))")
Run Code Online (Sandbox Code Playgroud)

  • PS.我讨厌CHAR作为数据类型. (5认同)