sql >> Databáze >  >> RDS >> Oracle

Otázka PreparedStatement v Javě proti Oracle

Jsem trochu překvapen, když vidím tento dokument. Je pravda, že nemůžete nastavit pole/kolekci následujícím způsobem (a to bez ohledu na použitou databázi / ovladač JDBC):

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

Ale dotaz uvedený v dokumentu by měl fungovat. Mohu to říci ze zkušenosti s alespoň Oracle 10g XE v kombinaci s ojdbc14.jar . Mám podezření, že buď autor dokumentu něco popletl, nebo se ve skutečnosti týká jiné (starší?) verze ovladače DB a/nebo JDBC.

Následující by mělo fungovat bez ohledu na použitý ovladač JDBC (ačkoli jste závislí na použité DB, kolik položek může klauzule IN obsahovat, Oracle (ano, opět) má limit přibližně 1000 položek):

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

S ohledem na TIMESTAMP otázku, stačí použít PreparedStatement#setTimestamp() .



  1. Jak používat Oracle Associative Array v dotazu SQL

  2. Logcat říká neplatný sloupec data1

  3. Porovnání výkonu a cen PostgreSQL DigitalOcean – ScaleGrid vs. DigitalOcean Managed Databases

  4. Ormlite nebo sqlite Který z nich je dobrý pro Android?