【问题标题】:How to use OUTPUT parameter in Stored Procedure如何在存储过程中使用 OUTPUT 参数
【发布时间】:2011-10-14 16:52:51
【问题描述】:

我是编写存储过程的新手。于是写了一个带输出参数的,想访问输出值,热做吧。

我的存储过程:

ALTER PROCEDURE selQuery
    (
        @id int, @code varchar(50) OUTPUT
    )
AS
    SELECT RecItemCode = @code, RecUsername from Receipt where RecTransaction = @id
    RETURN @code

如果尝试将“@code=RecItemCode”设置为:“将值分配给变量的 SELECT 语句不得与数据检索操作结合使用。”

我使用存储过程作为:

con.Open();
cmd.Parameters.AddWithValue("@id", textBox1.Text);
SqlParameter code = new SqlParameter("@code", SqlDbType.Int);
code.Direction = ParameterDirection.Output;
cmd.Parameters.Add(code);
SqlDataReader sdr = cmd.ExecuteReader();
MessageBox.Show(cmd.Parameters["@code"].Value.ToString()); // getting error
con.Close();

错误:“对象引用未设置为对象的实例。” 我想获取输出参数的值。如何获得?

谢谢。

【问题讨论】:

    标签: c# sql-server-2008 stored-procedures


    【解决方案1】:

    您需要解决一些问题才能使其正常工作

    1. 名字错了不是@ouput@code
    2. 您需要将参数方向设置为输出。
    3. 不要使用AddWithValue,因为它不应该只有你Add才有价值。
    4. 如果您不返回行,请使用 ExecuteNonQuery

    试试

    SqlParameter output = new SqlParameter("@code", SqlDbType.Int);
    output.Direction = ParameterDirection.Output;
    cmd.Parameters.Add(output);
    cmd.ExecuteNonQuery();
    MessageBox.Show(output.Value.ToString());
    

    【讨论】:

    • 很好,但是如何获取输出参数的值?? output.Value.ToString() 给出错误为“对象引用未设置为对象的实例。”
    • 不要说“你忘记了”,因为我没有忘记,其实我不知道 :-(
    • @rapsalands, 执行查询后,从参数中检索值。 cmd.ExecuteNonQuery(); int value = (int)output.Value;
    • 不知道为什么你得到一个空引用。也许你应该更新你的问题。
    • @rapsalands,您的 SP 看起来完全错误,暂时不要在意您的代码。一方面,我认为您的意思不是RecItemCode = @code,它试图将@code to RecItemCode 分配。你从来没有设置过@code。
    【解决方案2】:

    您的 SP 中的 SQL 错误。你可能想要

    Select @code = RecItemCode from Receipt where RecTransaction = @id
    

    在您的声明中,您没有设置@code,而是试图将其用于 RecItemCode 的值。当您尝试使用输出参数时,这将解释您的NullReferenceException,因为从未为其分配值并且您得到默认空值。

    另一个问题是你的 SQL 语句如果重写为

    Select @code = RecItemCode, RecUsername from Receipt where RecTransaction = @id
    

    它混合了变量赋值和数据检索。这突出了几点。如果除了数据的其他部分之外,您还需要驱动 @code 的数据,请忘记输出参数,只需选择数据即可。

    Select RecItemCode, RecUsername from Receipt where RecTransaction = @id
    

    如果您只需要代码,请使用我向您展示的第一条 SQL 语句。如果您实际上需要输出数据,请使用两个不同的语句

    Select @code = RecItemCode from Receipt where RecTransaction = @id
    Select RecItemCode, RecUsername from Receipt where RecTransaction = @id
    

    这应该将您的值分配给输出参数,并连续返回两列数据。然而,这让我觉得非常多余。

    如果您按照我在最顶部显示的方式编写您的 SP,只需调用 cmd.ExecuteNonQuery();,然后读取输出参数值。


    您的 SP 和代码的另一个问题。在您的 SP 中,您已将 @code 声明为 varchar。在您的代码中,您将参数类型指定为Int。更改您的 SP 或您的代码以使类型一致。


    另请注意:如果您所做的只是返回单个值,那么还有另一种完全不涉及输出参数的方法。你可以写

     Select RecItemCode from Receipt where RecTransaction = @id
    

    然后使用object obj = cmd.ExecuteScalar(); 得到结果,SP 或者你的代码中不需要输出参数。

    【讨论】:

    • 谢谢你和 +1。 '对象 obj = cmd.ExecuteScalar();'完美地工作。我能够在两行 c# 代码中完成我所需要的,第二行是 'myString = obj.ToString();'。
    【解决方案3】:

    您需要在代码中使用ParameterDirection.Output 枚举将输出参数定义为输出参数。有很多这样的例子,但这里有一个 MSDN

    【讨论】:

      【解决方案4】:
      SqlCommand yourCommand = new SqlCommand();
      yourCommand.Connection = yourSqlConn;
      yourCommand.Parameters.Add("@yourParam");
      yourCommand.Parameters["@yourParam"].Direction = ParameterDirection.Output;
      
      // execute your query successfully
      
      int yourResult = yourCommand.Parameters["@yourParam"].Value;
      

      【讨论】:

      • @rapsalands 你不能只执行代码。它不是一个独立的代码块。该错误表示您尚未实例化对象(即创建它的新实例)。这只是为了让您大致了解如何从存储过程的输出参数中获取值。
      • 其实我正在努力学习SP,以前从未这样做过。如果您能说出我的代码有什么问题,那就太好了。我的意思是我必须在哪里创建实例??
      【解决方案5】:

      您需要先关闭连接,然后才能使用输出参数。 像这样的

      con.Close();
      MessageBox.Show(cmd.Parameters["@code"].Value.ToString());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-13
        • 2017-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多