我有一些访问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
由于输入参数在进入存储过程时设置为零,在什么情况下可以不设置该值?还是我误解了错误信息?
此错误可通过以下方式重现:
更新:由于存储过程的-- Do processing...
部分,它似乎正在发生。删除它可以消除错误。这里有太多的代码需要重现,我想要的是一些可能导致缩小可能候选人的原因。
更新:将错误(例如除以零)注入存储过程的-- Do processing...
部分不会导致抛出此异常(相反,正如预期的那样,execute()
调用失败并显示相应的错误消息)。
更新:反编译com.microsoft.sqlserver.jdbc.SQLServerCallableStatement类建议'参数号0'是存储过程返回值。
更新:我无法通过Management Studio直接调用存储过程来重现此问题。
更新:此错误的最终原因似乎是存储过程中的死锁。但是,通常,死锁导致execute()
调用失败,并且SQLException
包装SQL Server错误代码1205 ...
在您的参数上,您只是声明它们还是将它们设置为默认值?尝试将它们设置为默认值null或其他东西,看看你是否仍然得到错误。
如果您没有将参数设置为默认值并且在执行存储过程时未向其传递值,则SQL Server不喜欢它。
你在注册输出参数吗?根据docs“必须在执行存储过程之前注册所有OUT参数。”
有几件事情浮现在脑海中:
希望这可以帮助,
法案
反编译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)
你实际上有三个参数要处理,而不是两个。
如果有人仍然在SQL Server 2008上遇到此问题。
尝试为DateTime字段设置时间戳时,我在更新语句上遇到了同样的问题。违规字段位于where子句中,与报告的索引不同。