Oracle
 sql >> Database >  >> RDS >> Oracle

Domanda PreparedStatement in Java contro Oracle

Sono un po' sorpreso di vedere questo documento. È vero che non puoi impostare un array/raccolta come segue (e questo indipendentemente dal database/driver JDBC utilizzato):

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

Ma la query menzionata nel documento dovrebbe funzionare. Posso dirlo dall'esperienza con almeno Oracle 10g XE in combinazione con ojdbc14.jar . Sospetto che l'autore del documento abbia confuso le cose o si tratti in realtà di una versione diversa (precedente?) del driver DB e/o JDBC.

Quanto segue dovrebbe funzionare indipendentemente dal driver JDBC utilizzato (sebbene tu dipenda dal DB utilizzato quanti elementi può contenere la clausola IN, Oracle (sì, di nuovo) ha un limite di circa 1000 elementi):

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

Per quanto riguarda il TIMESTAMP domanda, usa semplicemente PreparedStatement#setTimestamp() .