sql >> Base de Datos >  >> RDS >> Oracle

Pregunta PreparedStatement en Java contra Oracle

Estoy un poco sorprendido de ver este documento. Es cierto que no puede establecer una matriz/colección de la siguiente manera (y esto es independientemente de la base de datos/controlador JDBC utilizado):

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

Pero la consulta mencionada en el documento debería funcionar. Puedo decir esto por experiencia con al menos Oracle 10g XE en combinación con ojdbc14.jar . Sospecho que el autor del documento confundió las cosas, o en realidad se trata de una versión diferente (¿más antigua?) del controlador DB y/o JDBC.

Lo siguiente debería funcionar independientemente del controlador JDBC utilizado (aunque depende de la base de datos utilizada para saber cuántos elementos puede contener la cláusula IN, Oracle (sí, de nuevo) tiene un límite de alrededor de 1000 elementos):

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

Con respecto al TIMESTAMP pregunta, simplemente use PreparedStatement#setTimestamp() .