prestodb/presto · error · SQLException
Batch prepared statement must be executed using executeBatch
Error message
Batch prepared statement must be executed using executeBatch method
What it means
requireNonBatchStatement() guards every single-execution entry point (executeQuery, executeUpdate, executeLargeUpdate, execute). If addBatch() has been called (isBatch is true), the accumulated batch must be run with executeBatch(); mixing single-shot execution with a pending batch is rejected to avoid silently dropping the queued batch rows.
Source
Thrown at presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoPreparedStatement.java:821
private static List<String> toValues(Map<Integer, String> parameters)
throws SQLException
{
ImmutableList.Builder<String> values = ImmutableList.builder();
for (int index = 0; index < parameters.size(); index++) {
if (!parameters.containsKey(index)) {
throw new SQLException("No value specified for parameter " + (index + 1));
}
values.add(parameters.get(index));
}
return values.build();
}
private void requireNonBatchStatement()
throws SQLException
{
if (isBatch) {
throw new SQLException("Batch prepared statement must be executed using executeBatch method");
}
}
private static String getExecuteSql(String statementName, List<String> values)
{
StringBuilder sql = new StringBuilder();
sql.append("EXECUTE ").append(statementName);
if (!values.isEmpty()) {
sql.append(" USING ");
Joiner.on(", ").appendTo(sql, values);
}
return sql.toString();
}
private static String formatLiteral(String type, String x)
{
return type + " " + formatStringLiteral(x);
}View on GitHub (pinned to 55bb57d202)
Solutions
- Call executeBatch() (and process its results) instead of execute/executeUpdate when batching
- Call clearBatch() to discard a pending batch before switching to single-statement execution
- Restructure code so a given statement instance is used either for batches or single execution, not both
- Reuse a fresh PreparedStatement (or clearBatch) when falling back from a failed batch to per-row execution
Example fix
// before ps.setInt(1, 1); ps.addBatch(); int n = ps.executeUpdate(); // throws // after ps.setInt(1, 1); ps.addBatch(); int[] counts = ps.executeBatch();
Defensive patterns
Strategy: validation
Validate before calling
if (hasPendingBatch) {
ps.executeBatch(); // or ps.clearBatch() before single execution
} else {
ps.executeUpdate();
} Try / catch
catch (SQLException e) {
if (e.getMessage().contains("must be executed using executeBatch")) {
ps.clearBatch(); // discard pending batch, then retry as single statement
}
throw e;
} Prevention
- Track batch state: once addBatch() is called, only executeBatch() is valid
- Call clearBatch() to reset a statement after an abandoned batch
- Use separate statement instances for batch vs single-row workloads
When it happens
Trigger: Calling executeQuery/executeUpdate/execute on a PreparedStatement after at least one addBatch() call, without calling executeBatch() (or clearBatch()) first.
Common situations: Code paths that sometimes batch and sometimes execute directly; retry/error-handling logic that abandons a batch halfway and re-executes as a single statement; reused statement objects where a previous operation left a pending batch.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/d4052a3842352fa6.
Report an issue: GitHub.