Memra

Querying with PreparedStatement and ResultSet

Parameterised queries, iterating result rows, and the 1-indexed column trap.

Why PreparedStatement?

PreparedStatement compiles the SQL template once and lets you set ? placeholder values before each execution. This is both faster (the database re-uses the query plan) and safer (prevents SQL injection).

String sql = "SELECT id, name, salary FROM employees WHERE dept = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "Engineering");   // ? at position 1

ResultSet rs = ps.executeQuery();
while (rs.next()) {
    int    id     = rs.getInt("id");
    String name   = rs.getString("name");
    double salary = rs.getDouble(3);   // positional: column 3
    System.out.printf("%d  %-20s  %.2f%n", id, name, salary);
}

ResultSet iteration

A freshly returned ResultSet is positioned before the first row — there is no current row yet. You must call rs.next() to advance. The pattern is always:

while (rs.next()) {
    // now on a valid row
}

Reading values: use typed getters like getString, getInt, getDouble. You can address a column by its label name (rs.getString("name")) or by its 1-based position (rs.getString(1)). Position 1 is the *first* column, not zero.

Setter positioning

Likewise, ? placeholders in the SQL are numbered from 1:

ps.setString(1, value1);   // first ?
ps.setInt(2, value2);      // second ?

Attempting position 0 throws SQLException: parameter index out of range.

NORMAL ~/memra/learn/java-from-zero/querying-with-preparedstatement utf-8 LF