【问题标题】:Calling stored procedure with return value调用带有返回值的存储过程
【发布时间】:2023-12-15 09:27:02
【问题描述】:

我正在尝试从我的 C# Windows 应用程序中调用存储过程。存储过程在 SQL Server 2008 的本地实例上运行。我可以调用存储过程,但无法从存储过程中检索返回值。这个存储过程应该返回序列中的下一个数字。我在网上做了研究,我看到的所有网站都指出这个解决方案是有效的。

存储过程代码:

ALTER procedure [dbo].[usp_GetNewSeqVal]
      @SeqName nvarchar(255)
as
begin
      declare @NewSeqVal int
      set NOCOUNT ON
      update AllSequences
      set @NewSeqVal = CurrVal = CurrVal+Incr
      where SeqName = @SeqName

      if @@rowcount = 0 begin
print 'Sequence does not exist'
            return
      end

      return @NewSeqVal
end

调用存储过程的代码:

SqlConnection conn = new SqlConnection(getConnectionString());
conn.Open();

SqlCommand cmd = new SqlCommand(parameterStatement.getQuery(), conn);
cmd.CommandType = CommandType.StoredProcedure;

SqlParameter param = new SqlParameter();

param = cmd.Parameters.Add("@SeqName", SqlDbType.NVarChar);
param.Direction = ParameterDirection.Input;
param.Value = "SeqName";

SqlDataReader reader = cmd.ExecuteReader();

我也尝试使用DataSet 来检索具有相同结果的返回值。我想得到什么 我的存储过程的返回值?如果需要更多信息,请告诉我。

【问题讨论】:

    标签: c# sql-server stored-procedures ado.net return-value


    【解决方案1】:

    您需要在命令中添加返回参数:

    using (SqlConnection conn = new SqlConnection(getConnectionString()))
    using (SqlCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = parameterStatement.getQuery();
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.AddWithValue("SeqName", "SeqNameValue");
    
        var returnParameter = cmd.Parameters.Add("@ReturnVal", SqlDbType.Int);
        returnParameter.Direction = ParameterDirection.ReturnValue;
    
        conn.Open();
        cmd.ExecuteNonQuery();
        var result = returnParameter.Value;
    }
    

    【讨论】:

    • 您是否也必须将@ReturnVal 添加到存储过程中?
    • 不,你不必添加到sp(return语句触发填充带有ReturnValue标记的参数)
    • 不管你如何命名 return val 参数,顺便说一句。
    • 非常感谢,我正在寻找一种正确获取返回值的方法,这对我来说真的很管用。太棒了!
    • 存储过程返回值应该只用于指示成功(零)或失败/警告(非零),而不是返回数据。为此目的使用OUTPUT 参数或结果集。
    【解决方案2】:

    我知道这是旧的,但我偶然发现它与谷歌。

    如果您的存储过程中有返回值,请说“返回 1” - 不使用输出参数。

    您可以执行以下操作 - “@RETURN_VALUE”会以静默方式添加到每个命令对象。无需明确添加

        cmd.ExecuteNonQuery();
        rtn = (int)cmd.Parameters["@RETURN_VALUE"].Value;
    

    【讨论】:

    • 嗨,加里。你碰巧有引用吗?
    • 我不相信 cmd 实例在 SqlParameterCollection 中会有一个名为 RETURN_VALUE 的参数,除非它被显式添加。因此,如果您正在考虑采用 Gary 上述方法,请确保您已添加 cmd.Parameters.Add(new SqlParameter("@RETURN_VALUE", SqlDbType.Int)); cmd.Parameters["@RETURN_VALUE"].Direction = ParameterDirection.ReturnValue;但是,我相信您不必将 @RETURN_VALUE 添加到存储过程定义中。也许这就是加里的意思。
    【解决方案3】:

    我机器上的 EnterpriseLibrary 版本有其他参数。 这是有效的:

            SqlParameter retval = new SqlParameter("@ReturnValue", System.Data.SqlDbType.Int);
            retval.Direction = System.Data.ParameterDirection.ReturnValue;
            cmd.Parameters.Add(retval);
            db.ExecuteNonQuery(cmd);
            object o = cmd.Parameters["@ReturnValue"].Value;
    

    【讨论】:

      【解决方案4】:

      我遇到了类似的问题,SP 调用返回了一个错误,即未包含预期的参数。我的代码如下。
      存储过程:

      @Result int 输出

      和 C#:

                  SqlParameter result = cmd.Parameters.Add(new SqlParameter("@Result", DbType.Int32));
                  result.Direction = ParameterDirection.ReturnValue;
      

      在故障排除中,我意识到存储过程实际上是在寻找“InputOutput”的方向,因此以下更改解决了问题。

                  r
      

      Result.Direction = ParameterDirection.InputOutput;

      【讨论】:

      • “输出参数”与存储过程返回值不同,顺便说一句。
      【解决方案5】:

      ExecuteScalar(); 可以,但输出参数将是更好的解决方案。

      【讨论】:

      • ExecuteScalar() 不起作用,除非您“选择”返回值。
      【解决方案6】:

      您可以尝试使用输出参数。 http://msdn.microsoft.com/en-us/library/ms378108.aspx

      【讨论】:

        【解决方案7】:

        这是一个从过程中返回单个值的非常简短的示例:

        SQL:

        CREATE PROCEDURE [dbo].[MakeDouble] @InpVal int AS BEGIN 
        SELECT @InpVal * 2; RETURN 0; 
        END
        

        C#-代码:

        int inpVal = 11;
        string retVal = "?";
        using (var sqlCon = new SqlConnection(
            "Data Source = . ; Initial Catalog = SampleDb; Integrated Security = True;"))
        {
            sqlCon.Open();
            retVal = new SqlCommand("Exec dbo.MakeDouble " + inpVal + ";", 
                sqlCon).ExecuteScalar().ToString();
            sqlCon.Close();
        }
        Debug.Print(inpVal + " * 2 = " + retVal); 
        //> 11 * 2 = 22
        

        【讨论】:

          【解决方案8】:

          或者,如果您使用的是 EnterpriseLibrary 而不是标准的 ADO.NET...

          Database db = DatabaseFactory.CreateDatabase();
          using (DbCommand cmd = db.GetStoredProcCommand("usp_GetNewSeqVal"))
          {
              db.AddInParameter(cmd, "SeqName", DbType.String, "SeqNameValue");
              db.AddParameter(cmd, "RetVal", DbType.Int32, ParameterDirection.ReturnValue, null, DataRowVersion.Default, null);
          
              db.ExecuteNonQuery(cmd);
          
              var result = (int)cmd.Parameters["RetVal"].Value;
          }
          

          【讨论】:

            【解决方案9】:

            我看到另一个已关闭。所以基本上这是我的代码的粗略。我认为您缺少字符串 cmd 注释。例如,如果我的存储过程是调用:DBO.Test。我需要写 cmd="DBO.test"。然后执行命令类型等于存储过程,等等等等

            Connection.open();
            String cmd="DBO.test"; //the command
            Sqlcommand mycommand;
            

            【讨论】: