pentaho/pentaho-kettle · error · KettleDatabaseException
Unable to prepare statement for SQL statement [
Error message
Unable to prepare statement for SQL statement [
What it means
setLookup failed to prepare the JDBC PreparedStatement used for the lookup (SELECT ... WHERE key fields) against the target table. SQLExceptions from connection.prepareStatement are wrapped in a KettleDatabaseException including the SQL text.
Solutions
- Click SQL on the step to see/execute the generated SQL; create the missing table or fix column names.
- Verify Schema/Table names and key column names in the step settings.
- Test the database connection (wrong host/db/driver produces prepare failures).
- Check the wrapped SQLException cause in the log for the real database error (permissions, syntax, missing object).
Example fix
// before: table name typo causes prepare failure
meta.setTableName("custmor");
// after
meta.setTableName("customer"); // existing table in schema Defensive patterns
Strategy: try-catch
Validate before calling
// before running, ensure the lookup table exists
Database db = new Database(transMeta, meta.getDatabaseMeta());
db.connect();
if (!db.checkTableExists(schema, table))
throw new IllegalStateException("Lookup table missing: " + table); Type guard
null
Try / catch
try { trans.execute(...); } catch (KettleDatabaseException e) {
if (e.getMessage().startsWith("Unable to prepare statement")) {
Throwable sqlEx = e.getCause(); // inspect real SQLException
}
throw e;
} Prevention
- Run the step dialog's SQL button to create/verify tables before production runs.
- Test the database connection with the exact credentials used at runtime.
- Avoid reserved words as column names or ensure proper quoting.
- Pin and test the correct JDBC driver version.
When it happens
Trigger: Invalid SQL generated from step metadata (bad table/column names, wrong quoting), or the JDBC driver/database cannot prepare the statement (missing table, permission denied, unsupported syntax, bad connection).
Common situations: Target table doesn't exist yet; reserved word used as a column without quoting; wrong schema name; wrong or outdated JDBC driver; connection pointing to the wrong database.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- : Unable to set Internet address value on prepared…
- Couldn't prepare statement:
- Error evaluating Internet address value metadata
- Error updating batch
- GPBulkLoaderMeta.Exception.ErrorGettingFields
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/1aa65358825d9303.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/trans/steps/insertupdate/InsertUpdate.java:392
data.lookupParameterRowMeta.addValueMeta(
rowMeta.searchValueMeta( meta.getKeyFields()[ i ].getKeyStream() ).clone() );
} else {
sql += " " + meta.getKeyFields()[ i ].getKeyCondition() + " ? ";
data.lookupParameterRowMeta.addValueMeta(
rowMeta.searchValueMeta( meta.getKeyFields()[ i ].getKeyStream() ) );
}
}
sql += " ) ) ";
}
try {
if ( log.isDetailed() ) {
logDetailed( "Setting preparedStatement to [" + sql + "]" );
}
data.prepStatementLookup = data.db.getConnection().prepareStatement( databaseMeta.stripCR( sql ) );
} catch ( SQLException ex ) {
throw new KettleDatabaseException( "Unable to prepare statement for SQL statement [" + sql + "]", ex );
}
}
// Lookup certain fields in a table
public void prepareUpdate( RowMetaInterface rowMeta ) throws KettleDatabaseException {
DatabaseMeta databaseMeta = meta.getDatabaseMeta();
data.updateParameterRowMeta = new RowMeta();
String sql = "UPDATE " + data.schemaTable + Const.CR;
sql += "SET ";
boolean comma = false;
for ( int i = 0; i < meta.getUpdateFields().length; i++ ) {
if ( meta.getUpdateFields()[ i ].getUpdate().booleanValue() ) {
if ( comma ) {
sql += ", ";
} else {View on GitHub (pinned to f3058517a1)