什么可能导致SQL Server JDBC错误'输出参数访问的参数号0'没有设置值?

时间:2009-05-13 15:25:04

标签: sql-server stored-procedures jdbc mssql-jdbc

我有一些访问SQL Server 2005的Java代码,如下所示:

CallableStatement cstmt = ...;
... // Set input parameters
cstmt.registerOutParameter(11, Types.INTEGER);
cstmt.execute();
int out = cstmt.getInt(11);

从最后一行抛出以下异常:

com.microsoft.sqlserver.jdbc.SQLServerException: The value is not set 
     for the parameter number 0.
   at com.microsoft.sqlserver.jdbc.SQLServerException.
     makeFromDriverError(Unknown Source)
   at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.
     skipOutParameters(Unknown Source)
   at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.
     getOutParameter(Unknown Source)
   at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.
     getterGetParam(Unknown Source)
   at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.
     getInt(Unknown Source)
   at org.jboss.resource.adapter.jdbc.WrappedCallableStatement.
     getInt(WrappedCallableStatement.java:192)

调用的存储过程如下所示:

CREATE PROCEDURE dbo.stored_proc ( -- 10 input parameters
                                 , @out_param INT OUTPUT) AS

-- Variable declarations 

SET @out_param = 0

-- Do processing...

SET @out_param = 1

由于输入参数在进入存储过程时设置为零,在什么情况下可以设置该值?或者我是否误解了错误消息?

此错误可通过以下方式重现:

  • SQL Server JDBC驱动程序1.2
  • SQL Server 2005(64位)Service Pack 2
  • SQL Server 2005(64位)Service Pack 3

更新:由于存储过程的-- Do processing...部分,它似乎正在发生。删除它可以消除错误。这里有太多的代码要重现,我想要的是一些可能导致缩小可能候选人的原因。

更新:将错误(例如除以零)注入存储过程-- Do processing...部分不会导致抛出此异常(相反,正如预期的那样,execute()调用失败并显示相应的错误消息。)

更新:反编译com.microsoft.sqlserver.jdbc.SQLServerCallableStatement类表明'参数编号0'是存储过程返回值

更新:我无法通过直接通过Management Studio调用存储过程来重现此问题。

更新:此错误的最终原因似乎是存储过程中的死锁。但是,通常死锁会导致execute()调用失败并且SQLException包装SQL Server错误代码1205 ...

5 个答案:

答案 0 :(得分:0)

关于参数,您只是声明它们还是将它们设置为默认值?尝试将它们设置为默认值null或其他值,并查看是否仍然出现错误。

如果您没有将参数设置为默认值并且在执行存储过程时没有向其传递值,则SQL Server不喜欢它。

答案 1 :(得分:0)

您是否正在注册输出参数?根据{{​​3}}“必须在执行存储过程之前注册所有OUT参数。”

答案 2 :(得分:0)

有几件事情浮现在脑海中:

  1. 你没有RETURN x(其中x是代表处理结果的INT,0 =成功,其他任何代表警告或错误)。
  2. 除输出参数外,您的客户端代码不会为返回值分配参数。
  3. 希望这有帮助,

    比尔

答案 3 :(得分:0)

  

反编译   com.microsoft.sqlserver.jdbc.SQLServerCallableStatement类建议   '参数号0'是存储过程返回值。

多数民众赞成。如果存储过程定义有11个输入/输出参数,则实际上需要在调用代码中定义12。参数0是返回码。

例如,对于带有一个输入和一个输出参数的SP,在SSMS中运行:

DECLARE @ReturnValue INT
DECLARE @P1 INT, @P2 INT

EXEC @ReturnValue= YourSP(@P1,@P2 OUTPUT)

你实际上有三个参数需要处理,而不是两个。

答案 4 :(得分:0)

如果有人在SQL Server 2008上仍然遇到此问题。

我在更新语句上遇到了同样的问题,试图为DateTime字段设置时间戳。违规字段位于where子句中,与报告的索引不同。