Oracle
 sql >> Base de données >  >> RDS >> Oracle

Question PreparedStatement en Java contre Oracle

Je suis un peu surpris de voir ce document. Il est vrai que vous ne pouvez pas définir un tableau/une collection comme suit (et ceci quelle que soit la base de données/le pilote JDBC utilisé) :

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

Mais la requête mentionnée dans le document devrait fonctionner. Je peux le dire par expérience avec au moins Oracle 10g XE en combinaison avec ojdbc14.jar . Je soupçonne que soit l'auteur du document a confondu les choses, soit il s'agit en fait d'une version différente (ancienne ?) de la base de données et/ou du pilote JDBC.

Ce qui suit devrait fonctionner quel que soit le pilote JDBC utilisé (bien que vous dépendiez de la base de données utilisée, du nombre d'éléments que la clause IN peut contenir, Oracle (oui, encore une fois) a une limite d'environ 1000 éléments) :

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]);
    }
}

Concernant le TIMESTAMP question, utilisez simplement PreparedStatement#setTimestamp() .