apache/shardingsphere · error · BatchParametersRequiredException

Statement used in batch must have parameters

Error message

Statement used in batch must have parameters

What it means

BatchParametersRequiredException ('Statement used in batch must have parameters') thrown when the BLR (binary literal representation) sent with CREATE BATCH parses to zero fields. Firebird batches only make sense for parameterized statements; a BLR describing no parameter slots means the client is trying to batch a statement with no placeholders.

Source

Thrown at proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/batch/FirebirdBatchCreateCommandExecutor.java:86

    private final FirebirdBatchCreateCommandPacket packet;
    
    private final ConnectionSession connectionSession;
    
    @Override
    public Collection<DatabasePacket> execute() throws SQLException {
        int connectionId = connectionSession.getConnectionId();
        int statementId = packet.getStatementHandle();
        if (null == connectionSession.getServerPreparedStatementRegistry().getPreparedStatement(statementId)) {
            throw new InvalidStatementHandleException(statementId);
        }
        if (null != FirebirdBatchRegistry.getInstance().getBatchStatement(connectionId, statementId)) {
            throw new BatchAlreadyOpenedException(statementId);
        }
        ByteBuf batchBlr = packet.getBatchBlr();
        int blrLength = batchBlr.readableBytes();
        FirebirdParseBatchBlr messageFormat = FirebirdParseBatchBlr.parse(batchBlr, blrLength);
        if (messageFormat.getFields().isEmpty()) {
            throw new BatchParametersRequiredException(statementId);
        }
        if (packet.getBatchMessageLength() != messageFormat.getMessageLength()) {
            throw new InvalidBatchMessageFormatException(
                    String.format("invalid message length: computed %d from BLR but client sent %d", messageFormat.getMessageLength(), packet.getBatchMessageLength()));
        }
        ByteBuf batchParametersBuffer = packet.getBatchParametersBuffer();
        BatchParameters batchParameters = BatchParameters.parse(batchParametersBuffer);
        FirebirdBatchRegistry.getInstance().registerBatchStatement(connectionId, statementId,
                new FirebirdBatchStatement(statementId, messageFormat.getFields(), batchParameters.getBufferSize(), batchParameters.isRecordCounts(), batchParameters.isMultiError()));
        return Collections.singleton(new FirebirdGenericResponsePacket().setHandle(statementId));
    }
    
    @Getter
    @RequiredArgsConstructor
    static final class BatchParameters {
        
        private final int version;
        

View on GitHub (pinned to e952770a21)

Solutions

  1. Only use batch API for statements that actually contain parameter markers ('?'); execute non-parameterized statements directly.
  2. If the statement should have parameters, verify the BLR sent in CREATE BATCH is the describe-bind BLR returned for the current prepared statement, not a stale one.
  3. Re-prepare the statement after changing its SQL so handle and BLR stay consistent.

Example fix

-- before: batched statement with no parameters
INSERT INTO t SELECT * FROM src

-- after: parameterized statement suitable for batching
INSERT INTO t (a, b) VALUES (?, ?)
Defensive patterns

Strategy: validation

Validate before calling

// Only batch SQL that contains parameter markers
if (!sql.contains("?")) { executeDirect(sql); } else { prepareAndBatch(sql); }

Try / catch

catch (SQLException e) {
    if (e.getMessage().contains("must have parameters")) { executeDirect(sql); } else throw e;
}

Prevention

When it happens

Trigger: FirebirdParseBatchBlr.parse(batchBlr, blrLength) returns a messageFormat whose getFields() is empty; typically because the prepared SQL has no '?' parameters and the client still built a batch BLR for it.

Common situations: client prepares a plain SELECT/DDL with no bind parameters and calls addBatch/executeBatch; generated code always wraps statements in batch API regardless of parameter presence; mismatch between the prepared statement's BLR and the batch BLR after re-preparing different SQL under the same handle.

Related errors


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