pentaho/pentaho-kettle · error · KettleDatabaseException
Unable to prepare database procedure call
Error message
Unable to prepare database procedure call
What it means
This KettleDatabaseException is thrown by Database.prepareSQL() when the JDBC PreparedStatement used for a stored-procedure (CallableStatement-style) call cannot be created. It wraps the underlying SQLException from the JDBC driver, so the real cause (bad SQL, unknown procedure, driver issue) is in the chained exception.
Solutions
- Read the chained SQLException cause in the stack trace for the driver's actual message
- Verify the procedure name, schema, and parameter count/types match the database catalog
- Grant EXECUTE privilege on the procedure to the connecting user
- Test the exact {call ...} statement in a SQL client with the same user
Example fix
// before
String sql = "call proc_a(?)";
database.prepareSQL(sql, arguments);
// after
String sql = "{call dbo.proc_a(?)}"; // correct schema + JDBC call syntax, params verified against catalog
database.prepareSQL(sql, arguments); Defensive patterns
Strategy: try-catch
Validate before calling
// before calling prepareSQL, verify the procedure exists (via DB catalog or information_schema)
if ( !procedureExists(connection, schema, procName) ) {
throw new IllegalArgumentException("Procedure not found: " + schema + "." + procName);
} Try / catch
try {
database.prepareSQL(sql, arguments);
} catch ( KettleDatabaseException e ) {
logError("Procedure call preparation failed: " + e.getCause(), e); // inspect chained SQLException
throw e;
} Prevention
- Validate procedure names and signatures against the DB catalog at design time
- Use canonical JDBC {call ...} syntax
- Grant EXECUTE to the integration user
- Test procedure calls with the same JDBC driver version used in production
When it happens
Trigger: Calling Database.prepareSQL() with isFunction=true / procedure-call arguments where connection.prepareCall() (or prepareStatement) throws a SQLException - e.g. the procedure name is misspelled, the schema is wrong, argument placeholders don't match the procedure signature, or the database user lacks EXECUTE permission.
Common situations: Typos in stored-procedure names in transformation DB-lookup/procedure steps; calling a procedure on a schema that isn't in the user's search path; JDBC driver quirks with callable statement syntax ({call ...}); missing execute grants after migrating databases.
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
- An error occurred executing SQL:
- Couldn't execute SQL:
- Couldn't find any rows because of an error :
- Couldn't get a result because of an error :
- Couldn't prepare statement:
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/e12f9be773d9d291.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/database/Database.java:3336
case ValueMetaInterface.TYPE_INTEGER:
cstmt.registerOutParameter( i + pos, java.sql.Types.BIGINT );
break;
case ValueMetaInterface.TYPE_STRING:
cstmt.registerOutParameter( i + pos, java.sql.Types.VARCHAR );
break;
case ValueMetaInterface.TYPE_DATE:
cstmt.registerOutParameter( i + pos, java.sql.Types.TIMESTAMP );
break;
case ValueMetaInterface.TYPE_BOOLEAN:
cstmt.registerOutParameter( i + pos, java.sql.Types.BOOLEAN );
break;
default:
break;
}
}
}
} catch ( SQLException ex ) {
throw new KettleDatabaseException( "Unable to prepare database procedure call", ex );
}
} finally {
log.snap( Metrics.METRIC_DATABASE_PREPARE_DBPROC_STOP, databaseMeta.getName() );
}
}
public Object[] getLookup() throws KettleDatabaseException {
return getLookup( prepStatementLookup, false );
}
public Object[] getLookup( boolean failOnMultipleResults ) throws KettleDatabaseException {
return getLookup( failOnMultipleResults, false );
}
public Object[] getLookup( boolean failOnMultipleResults, boolean lazyConversion ) throws KettleDatabaseException {
return getLookup( prepStatementLookup, failOnMultipleResults, lazyConversion );
}View on GitHub (pinned to f3058517a1)