{"record":{"id":"477619890bed8c56","repo":"pentaho/pentaho-kettle","slug":"unable-to-prepare-statement-for-update-sql","errorCode":null,"errorMessage":"Unable to prepare statement for update [\" + sql + \"]","messagePattern":"Unable to prepare statement for update \\[\" \\+ sql \\+ \"\\]","errorType":"exception","errorClass":"KettleDatabaseException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/database/Database.java","lineNumber":3123,"sourceCode":"        } else {\n          sql.append( \" \" ).append( condition[ i ] ).append( \" ? \" );\n        }\n      }\n\n      if ( orderby != null && orderby.length() != 0 ) {\n        sql.append( \" ORDER BY \" ).append( orderby );\n      }\n\n      try {\n        if ( log.isDetailed() ) {\n          log.logDetailed( \"Setting preparedStatement to [\" + sql + \"]\" );\n        }\n        prepStatementLookup = connection.prepareStatement( databaseMeta.stripCR( sql.toString() ) );\n        if ( !checkForMultipleResults && databaseMeta.supportsSetMaxRows() ) {\n          prepStatementLookup.setMaxRows( 1 ); // alywas get only 1 line back!\n        }\n      } catch ( SQLException ex ) {\n        throw new KettleDatabaseException( \"Unable to prepare statement for update [\" + sql + \"]\", ex );\n      }\n    } finally {\n      log.snap( Metrics.METRIC_DATABASE_SET_LOOKUP_STOP, databaseMeta.getName() );\n    }\n  }\n\n  public boolean prepareUpdate( String table, String[] codes, String[] condition, String[] sets ) {\n    return prepareUpdate( null, table, codes, condition, sets );\n  }\n\n  // Lookup certain fields in a table\n  public boolean prepareUpdate( String schemaName, String tableName, String[] codes, String[] condition,\n                                String[] sets ) {\n    try {\n      log.snap( Metrics.METRIC_DATABASE_PREPARE_UPDATE_START, databaseMeta.getName() );\n\n      StringBuilder sql = new StringBuilder( 128 );\n","sourceCodeStart":3105,"sourceCodeEnd":3141,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/database/Database.java#L3105-L3141","documentation":"KettleDatabaseException thrown by Database.setLookup when connection.prepareStatement(sql) fails while preparing the lookup statement for update/lookup. The generated lookup SQL is included in the message; the underlying SQLException is the cause.","triggerScenarios":"prepareStatement() rejects the generated lookup SQL: syntax error in the dialect's key-lookup clause, table/column doesn't exist, schema mismatch, closed connection, or missing table when using setLookup + setValuesLookup/getLookup.","commonSituations":"Lookup/update step pointed at a wrong or renamed table; case-sensitivity or schema qualification issues; driver rejects dialect-generated SQL (quote/identifier differences); connection already terminated.","solutions":["Verify the target table and key columns exist and are accessible with the current connection","Print the lookup SQL (in the exception message) and test it directly in the database","Check schema/catalog qualification and identifier quoting settings in the DatabaseMeta","Validate the connection (ping) and re-connect before preparing the statement"],"exampleFix":"// before\ndb.setLookup(tablename, keys, condition, extraCondition);\ndb.getLookup(...);\n// after\nif (db.checkTableExists(tablename)) {\n  db.setLookup(tablename, keys, condition, extraCondition);\n  db.getLookup(...);\n} else {\n  throw new KettleException(\"Lookup table missing: \" + tablename);\n}","handlingStrategy":"try-catch","validationCode":"if (!db.checkTableExists(tablename)) {\n  throw new KettleException(\"Lookup table missing: \" + tablename);\n}","typeGuard":"null","tryCatchPattern":"try {\n  db.setLookup(tablename, keys, condition, extraCondition);\n} catch (KettleDatabaseException e) {\n  logError(\"Lookup SQL failed: \" + e.getMessage()); // SQL is embedded in message\n  throw e;\n}","preventionTips":["Verify lookup tables and key columns exist before preparing","Test the generated SQL (in the exception message) directly in the DB","Match identifier quoting/case settings to the target database","Ping/reconnect before long-running transformation steps"],"tags":["jdbc","prepared-statement","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"}