Question

I am using Spring Framwork, SimpleJdbcTemplate, to call a stored procedure (SQL-Server) from my Java code.

For the stored procedures that do some update/insert, I do call simpleJdbcTemplate.update(...) and for the ones with select only, I call simpleJdbcTemplate.query(...). Both works fine.

Now, I have a stored procedure that do some updates first and run a select query at the end.

I was wondering how can I call this stored procedure?

I have tried the simpleJdbcTemplate.query(...) and got error code 0. I am not sure if having the update in my stored procedure is the problem or not.

UPDATE Here is the stack when I am calling from java code:

PreparedStatementCallback; uncategorized SQLException for SQL [EXEC NotificationAlertHourlyReport ?, ?, ?, ?];
SQL state [null]; error code [0]; 
The statement did not return a result set.; nested exception is 
com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not return a result set.
org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; 
uncategorized SQLException for SQL [EXEC NotificationAlertHourlyReport ?, ?, ?, ?]; 
SQL state [null]; error code [0]; The statement did not return a result set.;
nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not return a result set.
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslat
or.translate(AbstractFallbackSQLExceptionTranslator.java:83)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslat
or.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslat
or.translate(AbstractFallbackSQLExceptionTranslator.java:80)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:602)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:636)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:665)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:673)
        at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:713)
        at org.springframework.jdbc.core.simple.SimpleJdbcTemplate.query(SimpleJdbcTemplate.java:200)
        at com.test.MYCLASS.myMethod(Unknown Source)
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The statement did no
t return a result set.
        at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(S
QLServerException.java:171)
        at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePrep
aredStatement(SQLServerPreparedStatement.java:394)
        at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecC
md.doExecute(SQLServerPreparedStatement.java:340)
        at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:4575)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLSe
rverConnection.java:1400)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLSer
verStatement.java:179)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLS
erverStatement.java:154)
        at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(
SQLServerPreparedStatement.java:283)
        at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewPr
oxyPreparedStatement.java:76)
        at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(Jd
bcTemplate.java:643)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:
586)
        ... 13 more
Was it helpful?

Solution

So long as the SQL Server sproc actually works without error and returns data, it should be of no consequence that it might also perform an update as well (I'd make sure that the sproc did its update first and ended with the select). If this is the case then simpleJdbcTemplate.query(...) should do the trick. I don't know if it's checking the rowcount or not, but you might play with the SET NOCOUNT ON / OFF statement at the beginning of your sproc to see if that makes the java call happy.

OTHER TIPS

In case your SQL executed by a Statement or any of its subclasses (viz. PreparedStatement, CallableStatement) has multiple SQL statements inside it (can be INSERT/UPDATE/DELETE/SELECT), you should use the execute() method on the statement to execute such SQL, then call getMoreResults to browse through the responses for executing each of the statements in the SQL.

E.g.

Let's say your SQL has the following statements inside it:

UPDATE ....
SELECT ....

Then your code would appear like this:

// Create statement or prepare the call.
boolean result = stmt.execute();
// result will be false here indicating that the first result is an update count.
int updateCount = stmt.getUpdateCount();
result = stmt.getMoreResults();
// result will be true here indicating that the next result is a ResultSet.
ResultSet rs = stmt.getResultSet();

BTW, even though the documentation says that the call to getMoreResults() closes the previously opened ResultSet objects, it appears to be driver dependent and is safe to close those ResultSets explicitly to avoid resource leaks.

// JDK 7 provides try-with-resources that takes care of closing the resources.
try (ResultSet rs = stmt.getResultSet()) {

}

[...] do both select and update

SQL2005+: You can use OUTPUT clause to execute UPDATE statement and to return (within the same statement) affected rows:

UPDATE dbo.TargetTable
SET TargetColumn = NewValue
OUTPUT inserted.ID, inserted.TargetColumn, deleted.TargetColumn /*INTO table1 | @table2 | #table3*/
--                      ^ new value           ^ old value     
WHERE ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top