{"record":{"id":"16b51e997e4ad835","repo":"pentaho/pentaho-kettle","slug":"unable-to-prepare-statement-for-sql-statement","errorCode":null,"errorMessage":"Unable to prepare statement for SQL statement [","messagePattern":"Unable to prepare statement for SQL statement \\[","errorType":"exception","errorClass":"KettleDatabaseException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/trans/steps/delete/Delete.java","lineNumber":210,"sourceCode":"        sql += \" BETWEEN ? AND ? \";\n        data.deleteParameterRowMeta.addValueMeta( rowMeta.searchValueMeta( meta.getKeyFields()[i].getKeyStream() ) );\n        data.deleteParameterRowMeta.addValueMeta( rowMeta.searchValueMeta( meta.getKeyFields()[i].getKeyStream2() ) );\n      } else if ( \"IS NULL\".equalsIgnoreCase( meta.getKeyFields()[i].getKeyCondition() )\n              || \"IS NOT NULL\".equalsIgnoreCase( meta.getKeyFields()[i].getKeyCondition() ) ) {\n        sql += \" \" + meta.getKeyFields()[i].getKeyCondition() + \" \";\n      } else {\n        sql += \" \" + meta.getKeyFields()[i].getKeyCondition() + \" ? \";\n        data.deleteParameterRowMeta.addValueMeta( rowMeta.searchValueMeta( meta.getKeyFields()[i].getKeyStream() ) );\n      }\n    }\n\n    try {\n      if ( log.isDetailed() ) {\n        logDetailed( \"Setting delete preparedStatement to [\" + sql + \"]\" );\n      }\n      data.prepStatementDelete = data.db.getConnection().prepareStatement( databaseMeta.stripCR( sql ) );\n    } catch ( SQLException ex ) {\n      throw new KettleDatabaseException( \"Unable to prepare statement for SQL statement [\" + sql + \"]\", ex );\n    }\n  }\n\n  public boolean init( StepMetaInterface smi, StepDataInterface sdi ) {\n    meta = (DeleteMeta) smi;\n    data = (DeleteData) sdi;\n\n    if ( super.init( smi, sdi ) ) {\n        data.db.setCommitSize( meta.getCommitSize( this ) );\n        return true;\n    }\n    return false;\n  }\n\n  @Override\n  protected Class<?> getPKG() {\n    return PKG;\n  }","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/trans/steps/delete/Delete.java#L192-L228","documentation":"In Delete.prepareDelete, the generated DELETE SQL is handed to the JDBC connection via prepareStatement. If the driver throws a SQLException, it is wrapped in a KettleDatabaseException with the offending SQL text. The SQL string is logged, so the actual bad SQL is visible in the message.","triggerScenarios":"prepareDelete (called from processRow) executes data.db.getConnection().prepareStatement(stripCR(sql)) and the JDBC driver rejects the statement: bad table/field names, driver connectivity loss, or dialect-incompatible generated SQL.","commonSituations":"Wrong database connection selected in the step; table or schema name misspelled or missing; missing driver or wrong URL; database object renamed after the transformation was built; insufficient privileges on the table.","solutions":["Read the SQL shown in the error message and validate it directly against the target database (e.g. run it with a WHERE clause manually).","Check the Delete step's target table and connection settings; use 'Browse' to confirm the table exists on the selected connection.","Test the database connection (Test button) and confirm the JDBC driver is on the classpath.","Check DB user privileges to DELETE on the target table, and review the wrapped SQLException cause for the driver-level reason."],"exampleFix":"// before\n<connection>ProdDB_OLD</connection> <table>CUSTMR</table>\n// after\n<connection>ProdDB</connection> <table>CUSTOMERS</table> // names verified in DB","handlingStrategy":"try-catch","validationCode":"// Before running: verify table and connection\nassert connectionMeta.testConnectionSuccess();\nassert database.tableExists(targetSchema, targetTable);","typeGuard":null,"tryCatchPattern":"try { prepareDelete(sql); } catch (KettleDatabaseException e) {\n  Throwable cause = e.getCause();\n  log.error(\"SQL failed: {} cause: {}\", sql, cause == null ? \"none\" : cause.getMessage());\n}","preventionTips":["Test the DB connection in the step dialog before running.","Validate generated SQL against the target DB dialect.","Grant DELETE privileges to the runtime DB user.","Keep JDBC drivers up to date and on the classpath."],"tags":["jdbc","sql","delete-step","database"],"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"}