Reputation: 86687
I'm using Spring
with PreparedStatement
, and want to prepare the sql to use a function of the db. But the following does not work:
String sql = "SELECT somefunct(?,?)";
When I run it with the preparedstatement, I get:
org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [SELECT somefunct(?,?)]; Batch-Eintrag 0 SELECT somefunct('XX','XX') wurde abgebrochen. Rufen Sie 'getNextException' auf, um die Ursache zu erfahren.; nested exception is java.sql.BatchUpdateException: Batch-Eintrag 0 SELECT somefunct('XX','XX') wurde abgebrochen. Rufen Sie 'getNextException' auf, um die Ursache zu erfahren.
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:102)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:660)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:673)
at org.springframework.batch.item.database.JdbcBatchItemWriter.write(JdbcBatchItemWriter.java:185)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.writeItems(SimpleChunkProcessor.java:175)
at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.scan(FaultTolerantChunkProcessor.java:578)
at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.access$900(FaultTolerantChunkProcessor.java:50)
at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$5.recover(FaultTolerantChunkProcessor.java:410)
at org.springframework.retry.support.RetryTemplate.handleRetryExhausted(RetryTemplate.java:458)
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:320)
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:193)
at org.springframework.batch.core.step.item.BatchRetryTemplate.execute(BatchRetryTemplate.java:217)
at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor.write(FaultTolerantChunkProcessor.java:420)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:199)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:75)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:198)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)
at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:386)
at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:304)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:128)
at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:677)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:695)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:961)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:950)
Caused by: java.sql.BatchUpdateException: Batch-Eintrag 0 SELECT somefunct('X','test') wurde abgebrochen. Rufen Sie 'getNextException' auf, um die Ursache zu erfahren.
at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2743)
at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleResultRows(AbstractJdbc2Statement.java:2692)
at org.postgresql.core.v3.QueryExecutorImpl$1.handleResultRows(QueryExecutorImpl.java:439)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1853)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:405)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2892)
at org.springframework.batch.item.database.JdbcBatchItemWriter$1.doInPreparedStatement(JdbcBatchItemWriter.java:192)
at org.springframework.batch.item.database.JdbcBatchItemWriter$1.doInPreparedStatement(JdbcBatchItemWriter.java:185)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:644)
... 40 more
Upvotes: 0
Views: 7008
Reputation: 9500
As you are using Spring and as such have access to Spring JDBC, you can use the class StoredProcedure
as described in their documentation. We have used a similar approach to test the generation function of our oracle full-text.
public class SomeFunct extends StoredProcedure {
private static final String SQL = "somefunct";
public SomeFunct(DataSource dataSource) {
setDataSource(dataSource);
setFunction(true);
setSql(SQL);
declareParameter(new SqlParameter("input", Types.VARCHAR));
declareParameter(new SqlParameter("input-2", Types.VARCHAR));
compile();
}
public String execute(String input, String input2) {
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("input", input);
parameters.put("input-2", input2);
Map<String, Object> results = execute(parameters);
// if the name of the result is not known,
// you may iterate over the entries of the map
String result = (String) results.get("name-of-result");
return result;
}
}
Upvotes: 0
Reputation: 584
This may help:
String callSQL = "{ ? = call db_function(?) }";
CallableStatement statement = pConnection.prepareCall(callSQL);
statement.registerOutParameter(1, Types.VARCHAR);
statement.setString(2, param);
statement.execute();
String result = statement.getString(1);
Where pConnection
is java.sql.Connection
.
Upvotes: 2