使用返回值调用存储过程

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

存储过程代码:

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检索具有相同结果的返回值。我错过了什么 存储过程的返回值是多少? 如果需要更多信息,请告诉我。

297559 次浏览

You need to add a ReturnValue-direction parameter to the command:

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;
}

Setting the parameter's direction to ParameterDirection.ReturnValue instructs the SqlCommand to declare it as a variable and assign the stored procedure's return value to it (exec @ReturnValue = spMyProcedure...), exactly like you would write it in SQL.

You can try using an output parameter. http://msdn.microsoft.com/en-us/library/ms378108.aspx

ExecuteScalar(); will work, but an output parameter would be a superior solution.

Or if you're using EnterpriseLibrary rather than standard 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;
}

I know this is old, but i stumbled on it with Google.

If you have a return value in your stored procedure say "Return 1" - not using output parameters.

You can do the following - "@RETURN_VALUE" is silently added to every command object. NO NEED TO EXPLICITLY ADD

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

I see the other one is closed. So basically here's the rough of my code. I think you are missing the string cmd comment. For example if my store procedure is call:DBO.Test. I would need to write cmd="DBO.test". Then do command type equal to store procedure, and blah blah blah

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

The version of EnterpriseLibrary on my machine had other parameters. This was working:

        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;

I had a similar problem with the SP call returning an error that an expected parameter was not included. My code was as follows.
Stored Procedure:

@Result int OUTPUT

And C#:

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

In troubleshooting, I realized that the stored procedure was ACTUALLY looking for a direction of "InputOutput" so the following change fixed the problem.

            r

Result.Direction = ParameterDirection.InputOutput;

This is a very short sample of returning a single value from a procedure:

SQL:

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

C#-code:

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