{"record":{"id":"e12f9be773d9d291","repo":"pentaho/pentaho-kettle","slug":"unable-to-prepare-database-procedure-call","errorCode":null,"errorMessage":"Unable to prepare database procedure call","messagePattern":"Unable to prepare database procedure call","errorType":"exception","errorClass":"KettleDatabaseException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/database/Database.java","lineNumber":3336,"sourceCode":"              case ValueMetaInterface.TYPE_INTEGER:\n                cstmt.registerOutParameter( i + pos, java.sql.Types.BIGINT );\n                break;\n              case ValueMetaInterface.TYPE_STRING:\n                cstmt.registerOutParameter( i + pos, java.sql.Types.VARCHAR );\n                break;\n              case ValueMetaInterface.TYPE_DATE:\n                cstmt.registerOutParameter( i + pos, java.sql.Types.TIMESTAMP );\n                break;\n              case ValueMetaInterface.TYPE_BOOLEAN:\n                cstmt.registerOutParameter( i + pos, java.sql.Types.BOOLEAN );\n                break;\n              default:\n                break;\n            }\n          }\n        }\n      } catch ( SQLException ex ) {\n        throw new KettleDatabaseException( \"Unable to prepare database procedure call\", ex );\n      }\n    } finally {\n      log.snap( Metrics.METRIC_DATABASE_PREPARE_DBPROC_STOP, databaseMeta.getName() );\n    }\n\n  }\n\n  public Object[] getLookup() throws KettleDatabaseException {\n    return getLookup( prepStatementLookup, false );\n  }\n\n  public Object[] getLookup( boolean failOnMultipleResults ) throws KettleDatabaseException {\n    return getLookup( failOnMultipleResults, false );\n  }\n\n  public Object[] getLookup( boolean failOnMultipleResults, boolean lazyConversion ) throws KettleDatabaseException {\n    return getLookup( prepStatementLookup, failOnMultipleResults, lazyConversion );\n  }","sourceCodeStart":3318,"sourceCodeEnd":3354,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/database/Database.java#L3318-L3354","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nString sql = \"call proc_a(?)\";\ndatabase.prepareSQL(sql, arguments);\n// after\nString sql = \"{call dbo.proc_a(?)}\"; // correct schema + JDBC call syntax, params verified against catalog\ndatabase.prepareSQL(sql, arguments);","handlingStrategy":"try-catch","validationCode":"// before calling prepareSQL, verify the procedure exists (via DB catalog or information_schema)\nif ( !procedureExists(connection, schema, procName) ) {\n  throw new IllegalArgumentException(\"Procedure not found: \" + schema + \".\" + procName);\n}","typeGuard":null,"tryCatchPattern":"try {\n  database.prepareSQL(sql, arguments);\n} catch ( KettleDatabaseException e ) {\n  logError(\"Procedure call preparation failed: \" + e.getCause(), e); // inspect chained SQLException\n  throw e;\n}","preventionTips":["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"],"tags":["jdbc","database","stored-procedure","sql"],"backgroundTag":"sql-query-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}