2010-03-24 62 views
1

为了安全和性能的原因,我正在修改一些使用preparedStatement而不是普通Statement的代码。Java中针对Oracle的PreparedStatement问题

我们的应用程序目前正在将信息存储到嵌入式德比数据库中,但我们即将转向Oracle。

我发现两件事情,我需要对Oracle和预处理语句您的帮助家伙:

1 - 我发现this document说,甲骨文没有处理绑定参数为IN子句,所以我们不能提供查询如下:

Select pokemon from pokemonTable where capacity in (?,?,?,?) 

这是真的吗?有什么解决方法吗? ...为什么?

2-我们有一些类型为TIMESTAMP的字段。因此,根据我们的实际声明,查询如下所示:

Select raichu from pokemonTable where evolution = TO_TIMESTAMP('2500-12-31 00:00:00.000', 'YYYY-MM-DD HH24:MI:SS.FF') 

准备好的声明应该做什么?我应该加入参数数组: 2500-12-31或TO_TIMESTAMP('2500-12-31 00:00:00.000','YYYY-MM-DD HH24:MI:SS.FF')?

感谢您的帮助,我希望我的问题很明确!

Regards,

回答

1

我有点惊讶地看到这个文件。这是事实,就像跟着你不能设置一个数组/集合(这是无论使用的数据库/ JDBC驱动程序):

String sql = "SELECT col FROM tbl WHERE id IN (?)"; 
statement = connection.prepareStatement(sql); 
statement.setArray(1, arrayOfValues); // Fail. 

但是,文件中提到的查询应该工作。至少在Oracle 10g XE和ojdbc14.jar的组合中,我可以从经验中得知这一点。我怀疑这个文档的作者是不是混淆了事情,或者它实际上涉及DB和/或JDBC驱动程序的不同(更旧的版本)版本。

无论使用什么JDBC驱动程序(虽然您依赖数据库使用了IN子句可以包含多少项目,Oracle(有,再次)具有大约1000个项目的限制),下列内容应该可以工作:

private static final String SQL_FIND = "SELECT id, name, value FROM data WHERE id IN (%s)"; 

public List<Data> find(Set<Long> ids) throws SQLException { 
    Connection connection = null; 
    PreparedStatement statement = null; 
    ResultSet resultSet = null; 
    List<Data> list = new ArrayList<Data>(); 
    String sql = String.format(SQL_FIND, preparePlaceHolders(ids.size())); 

    try{ 
     connection = database.getConnection(); 
     statement = connection.prepareStatement(sql); 
     setValues(statement, ids.toArray()); 
     resultSet = statement.executeQuery(); 
     while (resultSet.next()) { 
      Data data = new Data(); 
      data.setId(resultSet.getLong("id")); 
      data.setName(resultSet.getString("name")); 
      data.setValue(resultSet.getInt("value")); 
      list.add(data); 
     } 
    } finally { 
     close(connection, statement, resultSet); 
    } 

    return list; 
} 

public static String preparePlaceHolders(int length) { 
    StringBuilder builder = new StringBuilder(); 
    for (int i = 0; i < length;) { 
     builder.append("?"); 
     if (++i < length) { 
      builder.append(","); 
     } 
    } 
    return builder.toString(); 
} 

public static void setValues(PreparedStatement preparedStatement, Object... values) throws SQLException { 
    for (int i = 0; i < values.length; i++) { 
     preparedStatement.setObject(i + 1, values[i]); 
    } 
} 

关于TIMESTAMP问题,只需使用PreparedStatement#setTimestamp()即可。

+0

'String sql =“SELECT col FROM tbl WHERE ID MEMBER OF?”;'如果[你通过一个集合](https://stackoverflow.com/a/34699771/1509264)将工作。 – MT0 2018-01-14 13:16:37