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

  1. Read the chained SQLException cause in the stack trace for the driver's actual message
  2. Verify the procedure name, schema, and parameter count/types match the database catalog
  3. Grant EXECUTE privilege on the procedure to the connecting user
  4. 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

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


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)