C#中存储过程的返回值返回错误

时间:2010-11-24 22:36:27

标签: c# sql-server visual-studio sql-server-2005 tsql

我正在尝试按如下方式检索SQL Server 2005中存储过程的返回值:

        OleDbCommand comm = new OleDbCommand(process_name, connection);
        comm.CommandType = CommandType.StoredProcedure;

        for (int i = 0; i < process_parameters.Length; i++)
            comm.Parameters.AddWithValue(process_parameters[i].ParameterName, process_parameters[i].Value);

        //Add output param
        comm.Parameters.Add("@TestID", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;

        comm.ExecuteNonQuery();

但是,当调用ExecuteNonQuery()时,我得到一个 OleDbException 说:“过程或函数myStoredProcedure指定了太多参数。”我的存储过程从如下:

ALTER PROCEDURE [dbo].[spTabtempTestsINSERT]
(
            @Param1     char (64),
            @Param2     char (128),
            @Param3     char (64),
)
AS
BEGIN
    Declare     @TestID         int

以下列结尾:

    RETURN @TestID
END

声明返回值而不是作为参数传递这一事实是否与它有关?如果是这样,我怎样才能获得存储过程开始后声明的参数的返回值?谢谢你的帮助。

更新: 我已尝试过目前为止建议的更改,我添加了以下行:

            OleDbCommand comm = new OleDbCommand(process_name, connection);
            comm.CommandType = CommandType.StoredProcedure;

            for (int i = 0; i < process_parameters.Length; i++)
                comm.Parameters.AddWithValue(process_parameters[i].ParameterName, process_parameters[i].Value);

            var testID = (int)comm.ExecuteScalar();

现在执行ExecuteScalar()时,我得到 NullReferenceException 对象引用未设置为对象的实例

注意:我也尝试将其设置为整数int testID = (int)comm.ExecuteScalar();,但仍然会出现相同的错误。

6 个答案:

答案 0 :(得分:5)

更改

 comm.ExecuteNonQuery();

 int returnValue =  (int) comm.ExecuteScalar();

并删除:

  comm.Parameters.Add("@TestID", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;

答案 1 :(得分:0)

我认为ExecuteNonQuery()不会从SQL返回任何内容.....我在这里遗漏了什么吗?

答案 2 :(得分:0)

删除这些:

 //Add output param
        comm.Parameters.Add("@TestID", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;

        comm.ExecuteNonQuery();

并改为使用:var testID = (int) comm.ExecuteScalar();

答案 3 :(得分:0)

好的,我能够让它正常工作。我的问题是,我忽略了将任何参数声明为OUTPUT,我添加了一个额外的变量并将其设置为输出变量并让存储过程返回该变量。接下来我刚刚检查了输出参数,在调用存储过程后,从我的C#代码中,以下显示了更改:

ALTER PROCEDURE [dbo].[spTabtempTestsINSERT]
(
            @Param1     char (64),
            @Param2     char (128),
            @Param3     char (64),
            @ReturnValue int OUTPUT
)
AS
BEGIN
    Declare     @TestID         int

最后做一个简单的改变:

    SET @ReturnValue = @TestID
    RETURN @ReturnValue
END

最后,回到我的代码中:

        OleDbCommand comm = new OleDbCommand(process_name, connection);
        comm.CommandType = CommandType.StoredProcedure;

    for (int i = 0; i < process_parameters.Length; i++)
        comm.Parameters.AddWithValue(process_parameters[i].ParameterName, process_parameters[i].Value);

       //Add output param
        comm.Parameters.Add("@ReturnValue", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;

        comm.ExecuteNonQuery();
        Console.WriteLine("Stored Procedure returned a value of "+ comm.Parameters["@ReturnValue"].Value); //Success

谢谢大家的建议。欢迎提出任何替代方案或进一步的见解。

答案 4 :(得分:0)

回应接受的答案......

因为您在此处将参数Direction设置为ReturnValue

comm.Parameters.Add("@ReturnValue", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;

您的存储过程中根本不需要OUTPUT参数。您可以将其更改回:

ALTER PROCEDURE [dbo].[spTabtempTestsINSERT]
(
        @Param1     char (64),
        @Param2     char (128),
        @Param3     char (64),
)
AS
BEGIN
    Declare     @TestID         int

使用:

    RETURN @TestID
END

最后,它仍然可以像现在一样工作。

纯粹巧合,C#中的ReturnValue Parameter与您的OUTPUT参数具有相同的名称。 Direction参数有一个单独的参数OUTPUT

答案 5 :(得分:0)

我有同样的问题,问题是你必须声明返回参数第一个(在输入和输出之前),这样它的工作原理:

OleDbCommand comm = new OleDbCommand(process_name, connection);
comm.CommandType = CommandType.StoredProcedure;

//Add the return param first
comm.Parameters.Add("@TestID", OleDbType.Integer).Direction = ParameterDirection.ReturnValue;

for (int i = 0; i < process_parameters.Length; i++)
    comm.Parameters.AddWithValue(process_parameters[i].ParameterName, process_parameters[i].Value);

comm.ExecuteNonQuery();
Object return_value = comm.Parameters["@TestID"].Value;