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

本文关键字:存储过程 返回值 调用 | 更新日期: 2023-09-27 17:58:17

我正试图从C#窗口应用程序中调用一个存储过程。存储过程正在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来检索返回值,结果相同。我错过了什么存储过程的返回值?如果需要更多信息,请告诉我。

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

您需要在命令中添加一个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;
}

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

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

如果您的存储过程中有一个返回值,请说"return 1",而不是使用输出参数。

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

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

我的机器上的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;

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

@结果int OUTPUT

和C#:

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

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

            r

Result.Direction=ParameterDirection.InputOutput;

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

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

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

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

或者,如果您使用的是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;
}

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

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