java如何使用JDBC从存储过程中获取*everything*
在使用JDBC处理SQL Server存储过程时,我偶尔会遇到两种形式的奇怪行为:
问题1:我在SQLServerManagementStudio(SSMS)中运行了一个存储过程,它返回一个结果集。然而,当我尝试
try (CallableStatement cs = conn.prepareCall("{call dbo.TroublesomeSP}")) {
ResultSet rs = cs.executeQuery();
我有个例外
com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not return a result set.
问题2:我在SSMS中运行了一个存储过程,它会引发一个错误,但是当我使用JDBC来.execute
存储过程时,不会引发异常
为什么会出现这些问题?我如何避免这些问题
# 1 楼答案
当我们在JDBC中执行一个存储过程时,我们会返回一系列零或更多的“结果”。然后我们可以通过调用
CallableStatement#getMoreResults()
顺序处理这些“结果”。每个“结果”可以包含ResultSet
对象检索的零行或多行数据CallableStatement#getUpdateCount()
检索,或者对于“问题1”,问题通常是存储过程不是以
SET NOCOUNT ON;
开头,而是在执行SELECT以生成结果集之前执行DML语句。DML的更新计数作为第一个“结果”返回,数据行“卡在后面”,直到我们调用getMoreResults
“问题2”本质上是同一个问题。在错误发生之前,存储过程会生成一个“结果”(通常是SELECT,也可能是update count)。该错误会在后续的“结果”中返回,并且不会导致异常,直到我们使用
getMoreResults
来“检索”它在许多情况下,只需在存储过程中添加,直到,正如Javadoc所说:
SET NOCOUNT ON;
作为第一个可执行语句,就可以避免这个问题。然而,对存储过程的更改并不总是可能的,事实仍然是,为了从存储过程中获取所有信息,我们需要继续调用^{这听起来很简单,但像往常一样,“魔鬼在细节中”,如下例所示。对于SQL Server存储过程
。。。下面的Java代码将返回所有内容
。。。生成以下控制台输出: