apache/shardingsphere · error · SQLFeatureNotSupportedException

executeUpdate with SQL for PreparedStatement

Error message

executeUpdate with SQL for PreparedStatement

What it means

SQLFeatureNotSupportedException('executeUpdate with SQL for PreparedStatement') thrown by AbstractUnsupportedOperationPreparedStatement.executeUpdate(String) (and identically by its int/int[]/String[] overloads). JDBC forbids supplying SQL to a PreparedStatement's execute methods; ShardingSphere makes the overrides final and only implements no-arg executeUpdate() (ShardingSpherePreparedStatement:206) since routing requires the bound values.

Source

Thrown at jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationPreparedStatement.java:94

    
    @Override
    public final void setRowId(final int parameterIndex, final RowId x) throws SQLException {
        throw new SQLFeatureNotSupportedException("setRowId");
    }
    
    @Override
    public final void setRef(final int parameterIndex, final Ref x) throws SQLException {
        throw new SQLFeatureNotSupportedException("setRef");
    }
    
    @Override
    public final ResultSet executeQuery(final String sql) throws SQLException {
        throw new SQLFeatureNotSupportedException("executeQuery with SQL for PreparedStatement");
    }
    
    @Override
    public final int executeUpdate(final String sql) throws SQLException {
        throw new SQLFeatureNotSupportedException("executeUpdate with SQL for PreparedStatement");
    }
    
    @Override
    public final int executeUpdate(final String sql, final int autoGeneratedKeys) throws SQLException {
        throw new SQLFeatureNotSupportedException("executeUpdate with SQL for PreparedStatement");
    }
    
    @Override
    public final int executeUpdate(final String sql, final int[] columnIndexes) throws SQLException {
        throw new SQLFeatureNotSupportedException("executeUpdate with SQL for PreparedStatement");
    }
    
    @Override
    public final int executeUpdate(final String sql, final String[] columnNames) throws SQLException {
        throw new SQLFeatureNotSupportedException("executeUpdate with SQL for PreparedStatement");
    }
    
    @Override

View on GitHub (pinned to e952770a21)

Solutions

  1. Use ps.executeUpdate() after setXXX; declare generated-key return in conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) and read ps.getGeneratedKeys().
  2. For raw dynamic SQL, use Statement.executeUpdate(sql[, autoGeneratedKeys]) from conn.createStatement().
  3. Split generic helpers into Statement and PreparedStatement branches so the sql argument is never passed to the latter.

Example fix

// before
int n = ps.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);

// after
PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ps.setInt(1, id);
int n = ps.executeUpdate();
try (ResultSet keys = ps.getGeneratedKeys()) { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Declare generated keys at prepare time; execute with no args
PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
// then ps.executeUpdate() and ps.getGeneratedKeys()

Type guard

static int update(final Statement stmt, final String sql) throws SQLException {
    return (stmt instanceof PreparedStatement) ? ((PreparedStatement) stmt).executeUpdate() : stmt.executeUpdate(sql);
}

Prevention

When it happens

Trigger: ps.executeUpdate(sql) — or executeUpdate(sql, Statement.RETURN_GENERATED_KEYS) — on a ShardingSphere PreparedStatement; typical of generic write helpers and of code that needs generated keys and reaches for the Statement-style overload.

Common situations: Central DAO save()/update() methods shared by Statement and PreparedStatement paths; code requesting RETURN_GENERATED_KEYS via executeUpdate(sql, int); Statement examples reused on a PreparedStatement.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/9bbff11c8ecb022e. Report an issue: GitHub.