Java 如何使用JDBC从存储过程中获取*everything*
在使用JDBC处理SQL Server存储过程时,我偶尔会遇到两种形式的奇怪行为: 问题1:我在SQLServerManagementStudio SSMS中运行了一个存储过程,它返回一个结果集。然而,当我尝试 请尝试CallableStatement cs=conn.prepareCall{call dbo.Troublomesp}{ 结果集rs=cs.executeQuery; 我有个例外 com.microsoft.sqlserver.jdbc.SQLServerException:语句未返回结果集 问题2:我在SSMS中运行了一个存储过程,它会引发一个错误,但当我使用JDBC执行该存储过程时,不会引发异常Java 如何使用JDBC从存储过程中获取*everything*,java,sql-server,stored-procedures,jdbc,Java,Sql Server,Stored Procedures,Jdbc,在使用JDBC处理SQL Server存储过程时,我偶尔会遇到两种形式的奇怪行为: 问题1:我在SQLServerManagementStudio SSMS中运行了一个存储过程,它返回一个结果集。然而,当我尝试 请尝试CallableStatement cs=conn.prepareCall{call dbo.Troublomesp}{ 结果集rs=cs.executeQuery; 我有个例外 com.microsoft.sqlserver.jdbc.SQLServerException:语句未
为什么会出现这些问题以及如何避免这些问题?当我们在JDBC中执行存储过程时,我们会返回一系列零或多个结果。然后我们可以通过调用CallableStatementgetMoreResults按顺序处理这些结果。每个结果都可以包含 可以使用ResultSet对象检索的零行或多行数据, DML语句INSERT、update、DELETE的更新计数,我们可以使用CallableStatementgetUpdateCount或 引发SQLServerException的错误。 对于问题1,问题通常是存储过程不是以SET NOCOUNT ON开始,而是在执行SELECT以生成结果集之前执行DML语句。DML的更新计数作为第一个结果返回,并且数据行在调用getMoreResults之前一直停留在它后面 问题2本质上是同一个问题。存储过程在错误发生之前会生成一个结果,通常是SELECT,或者可能是更新计数。错误会在后续结果中返回,并且不会导致异常,直到我们使用getMoreResults检索它 在许多情况下,只需添加SET NOCOUNT ON(作为存储过程中的第一个可执行语句),就可以避免这个问题。然而,对存储过程的更改并不总是可能的,事实仍然是,为了从存储过程中获取所有内容,我们需要一直调用getMoreResults,直到,正如Javadoc所说s: 如果满足以下条件,则不会有更多结果: //stmt是一个语句对象 stmt.getMoreResults==false&&stmt.getUpdateCount==-1 这听起来很简单,但和往常一样,魔鬼在于细节,如下面的示例所示 将程序dbo.TroubleMesp更改为 开始 -注:无`设置不计数` 声明@tbl表id VARCHAR3主键; 删除表不存在; 插入@tbl id值“001”中; 从@tbl中选择id; 插入@tbl id值“001”;-重复键错误 在结果集中选择1/0;-error\u 在@tbl id值“101”中插入; 在@tbl id值“201”和“202”中插入; 从@tbl中选择id; 终止 …以下Java代码将返回所有内容 请尝试CallableStatement cs=conn.prepareCall{call dbo.Troublomesp}{ 布尔值resultSetAvailable=false; int numberOfResultsProcessed=0; 试一试{ resultSetAvailable=cs.execute; }捕获SQLServerException{ 执行时引发System.out.PrintFeException:%s%n%n,sse.getMessage; numberOfResultsProcessed++; } int updateCount=-2;//初始化为不可能的值 虽然是真的{ 布尔异常Occurred=true; 做{ 试一试{ 如果numberOfResultsProcessed>0{ resultSetAvailable=cs.getMoreResults; } exceptionOccurred=假; updateCount=cs.getUpdateCount; }捕获SQLServerException{ System.out.PrintFCCurrent结果是异常:%s%n%n,sse.getMessage; } numberOfResultsProcessed++; }发生例外时; 如果!resultSetAvailable&&updateCount==-1{ 中断;//我们结束了 } 如果结果可用{ System.out.printlnCurrent结果是一个ResultSet:; try ResultSet rs=cs.getResultSet{ 试一试{ 而rs.next{ System.out.printlnrs.getString1; } }捕获SQLServerException{ 处理结果集时System.out.PrintFeException:%s%n,sse.getMessage; } } }否则{ System.out.PrintFCCurrent结果是更新计数:%d%s受影响%n, 更新计数, updateCount==1?行为:行为; } System.out.println; } System.out.println[结果结束]; } …生成以下控制台输出: 执行时引发异常:无法删除表“不存在”,因为它不存在或您没有权限。 当前结果是更新计数:1行受影响 当前结果是一个结果集: 001 电流re sult是一个例外:违反主键约束“PK__31444EA__3213; E83F3335971A”。无法在对象“dbo@tbl”中插入重复的键。重复的键值为001。 当前结果是一个结果集: 处理结果集时出现异常:遇到被零除的错误。 当前结果是更新计数:1行受影响 当前结果是更新计数:2行受影响 当前结果是一个结果集: 001 101 201 202 [结果结束]
相关:而且解释很好。JDBC巫毒很臭。