我正在使用Spring Framwork SimpleJdbcTemplate
从我的Java代码调用存储过程(SQL-Server)。
对于执行某些更新/插入的存储过程,我会调用simpleJdbcTemplate.update(...)
,对于仅选择的存储过程,我会调用simpleJdbcTemplate.query(...)
。两者都很好。
现在,我有一个存储过程首先执行一些更新并在最后运行select查询。
我想知道如何调用此存储过程?
我尝试了simpleJdbcTemplate.query(...)
并得到了错误代码0.我不确定我的存储过程中的更新是否存在问题。
更新 当我从java代码调用时,这是堆栈:
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
答案 0 :(得分:3)
只要SQL Server sproc实际上没有错误地工作并且返回数据,它也可能也不会导致它也执行更新(我确保sproc首先执行更新并以选择)。如果是这种情况,那么simpleJdbcTemplate.query(...) 应该做的伎俩。我不知道它是否正在检查rowcount,但你可以在你的sproc开头使用SET NOCOUNT ON / OFF语句来查看是否能让java调用满意。
答案 1 :(得分:1)
如果您的SQL由Statement
或其任何子类(即PreparedStatement
,CallableStatement
)执行,其中包含多个SQL语句(可以是INSERT / UPDATE / DELETE / SELECT),您应该在语句上使用execute()
方法来执行此类SQL,然后调用getMoreResults来浏览执行SQL中每个语句的响应。
E.g。
假设你的SQL里面有以下语句:
UPDATE ....
SELECT ....
然后您的代码将如下所示:
// 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();
顺便说一下,即使文档说调用getMoreResults()
关闭了先前打开的ResultSet对象,它似乎依赖于驱动程序,并且可以安全地显式关闭这些ResultSet以避免资源泄漏。
// JDK 7 provides try-with-resources that takes care of closing the resources.
try (ResultSet rs = stmt.getResultSet()) {
}
答案 2 :(得分:0)
[...]同时选择和更新
SQL2005 +: 您可以使用OUTPUT clause执行UPDATE语句并返回(在同一语句中)受影响的行:
UPDATE dbo.TargetTable
SET TargetColumn = NewValue
OUTPUT inserted.ID, inserted.TargetColumn, deleted.TargetColumn /*INTO table1 | @table2 | #table3*/
-- ^ new value ^ old value
WHERE ...