调用具有返回值的存储过程

Calling stored procedure with return value

提问人:Wesley 提问时间:6/2/2011 最后编辑:abatishchevWesley 更新时间:8/2/2022 访问量:317524

问:

我正在尝试从我的 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();

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

C# sql-server 存储过程 ado.net 返回值

评论


答:

191赞 Alex Aza 6/2/2011 #1

您需要在命令中添加一个 -direction 参数:ReturnValue

using (SqlConnection conn = new SqlConnection(getConnectionString()))
using (SqlCommand cmd = conn.CreateCommand())
{
    cmd.CommandText = parameterStatement.getQuery();
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("SeqName", "SeqNameValue");

    // @ReturnVal could be any name
    var returnParameter = cmd.Parameters.Add("@ReturnVal", SqlDbType.Int);
    returnParameter.Direction = ParameterDirection.ReturnValue;

    conn.Open();
    cmd.ExecuteNonQuery();
    var result = returnParameter.Value;
}

将参数的方向设置为指示将其声明为变量,并将存储过程的返回值分配给它 (),就像在 SQL 中编写它一样。ParameterDirection.ReturnValueSqlCommandexec @ReturnValue = spMyProcedure...

评论

3赞 muttley91 2/4/2014
是否还必须添加到存储过程?@ReturnVal
4赞 ufosnowcat 12/10/2014
不,您不必向 sp 添加(return 语句会触发填充标有 ReturnValue 的参数)
15赞 Clay 4/28/2016
顺便说一句,你给返回 val 参数起什么名字并不重要。
0赞 Oswaldo Zapata 8/24/2017
非常感谢,我一直在寻找一种正确获取返回值的方法,这真的对我有用。棒!
5赞 Dan Guzman 8/12/2018
存储过程返回值应仅用于指示成功(零)或失败/警告(非零),而不返回数据。为此目的使用参数或结果集。OUTPUT
2赞 Aravind 6/2/2011 #2

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

3赞 Justin Dearing 6/2/2011 #3

ExecuteScalar();将起作用,但输出参数将是一个更好的解决方案。

评论

8赞 Soori 3/7/2016
ExecuteScalar() 不起作用,除非您“选择”返回值。
1赞 Dunc 10/31/2013 #4

或者,如果您使用的是 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;
}
7赞 Gary 9/5/2014 #5

我知道这已经很老了,但我在谷歌上偶然发现了它。

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

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

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

评论

2赞 Michael 11/11/2014
嗨,加里。你碰巧有引文吗?
5赞 Judy007 8/20/2016
我不相信cmd实例会在SqlParameterCollection中具有以RETURN_VALUE命名的参数,除非它是显式添加的。因此,如果您正在考虑采用 Gary 的上述方法,请确保您已添加 cmd.Parameters.Add(new SqlParameter(“@RETURN_VALUE”, SqlDbType.Int));cmd.Parameters[“@RETURN_VALUE”].方向 = ParameterDirection.ReturnValue;但是,我确实相信您不必将@RETURN_VALUE添加到存储过程定义中。也许这就是加里的意思。
0赞 Mafu Josh 12/13/2022
我有一些运行 SqlCommandBuilder.DeriveParameters 的源代码,它似乎会自动创建它的第一个参数作为@RETURN_VALUE(除非我错过了导致这种情况发生的其他事情)。DeriveParameters 比手动创建参数慢。我使用一次并缓存结果。
-10赞 Rain 11/21/2014 #6

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

Connection.open();
String cmd="DBO.test"; //the command
Sqlcommand mycommand;
5赞 RaSor 11/7/2016 #7

我机器上的 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;
3赞 Paul 5/10/2017 #8

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

@Result int 输出

和 C#:

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

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

            r

结果.方向 = ParameterDirection.InputOutput;

评论

2赞 Dai 8/28/2020
顺便说一句,“输出参数”与存储过程返回值不是一回事。
3赞 Michael Borg 9/25/2020 #9

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

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