甲骨文JDBC和Oracle CHAR数据类型甲骨文JDBC和Oracle CHAR数据类型(Ora

2019-05-12 06:59发布

我有一个的Oracle JDBC驱动程序在处理一个棘手的问题, CHAR数据类型。 让我们以这个简单的表:

create table x (c char(4));
insert into x (c) values ('a');  -- inserts 'a   '

所以,当我的东西插入到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

这里,常数'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();

这是一种解决方法:

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();

编辑 :现在这些都是制约因素:

  • 上述解决办法是不是desireable,因为它同时修改的内容c? ,这让使用索引上的c挺难的。
  • 移动从柱CHARVARCHAR (它应该是,当然)是不可能的

编辑 :这些限制的原因是因为我但从开发商的角度问这个问题jOOQ ,数据库抽象库。 所以,我的要求是提供一个非常通用的解决方案,不打破jOOQ的客户端代码什么。 这就是为什么我不是一个真正的解决办法的大风扇。 这就是为什么我没有访问该CHAR列的声明。 但是,我希望能够处理这种情况。

你会怎么做呢? 什么是处理一个很好的做法CHAR数据类型时,我想忽略尾随空白?

Answer 1:

如果你想

stmt.setString(1, "a");    // This won't return any records

返回的记录,尝试

conn.prepareStatement("select * from x where c = cast(? as char(4))")


Answer 2:

我看不出有任何理由使用CHAR数据类型,即使它是Oracle CHAR(1)。 你可以改变数据类型呢?



Answer 3:

加里的解决方案效果很好。 这里有一个替代方案。

如果您使用的是Oracle JDBC驱动程序,调用prepareStatement()实际上将返回一个OraclePreparedStatement ,其中有一个setFixedCHAR()与空白自动垫的输入方法。

String sql = "select * from x where c = ?";
OraclePreparedStatement stmt = (OraclePreparedStatement) conn.prepareStatement(sql);
stmt.setFixedCHAR(1, "a");
...

显然,如果您使用的是Oracle驱动程序中投是唯一安全的。

唯一的原因,我会建议你使用了加里的回答是,你可以改变你列的大小,而不必修改您的JDBC代码。 司机垫空间的正确数量,而不开发商需要知道/管理列大小。



Answer 4:

我对这个漂亮的修复。 你必须添加一个属性而获得的数据库连接。

NLS_LANG=american_america.AL32UTF8

或在Java中的连接,你可以使用下面的代码:

java.util.Properties info = new java.util.Properties();
info.put ("user", user);
info.put ("password",password);
info.put("fixedString","TRUE");
info.put("NLS_LANG","american_america.AL32UTF8");
info.put("SetBigStringTryClob","TRUE");
String url="jdbc:oracle:thin:@"+serverName;
log.debug("url="+url);
log.debug("info="+info);
Class.forName("oracle.jdbc.OracleDriver");
conn  = DriverManager.getConnection(url,info);


Answer 5:

另一种方法是修改SQL作为

select * from x where NVL(TRIM(c),' ') = NVL(TRIM('a'),' ')


文章来源: Oracle JDBC and Oracle CHAR data type