简体   繁体   English

从存储过程获取返回值-C#

[英]Getting return value from stored procedure - C#

Here is my stored procedure: 这是我的存储过程:

ALTER proc [Core].[up_ExternalTradeInsert]
@ExecID char(16),
@SecondaryExecID char(16),
@SecurityID int,
@SecurityIDSource int,
@LastQty int,
@LastPx decimal(12, 6),
@TransactTime datetime2(3),
@Side bit, --0 Sell 1-Buy
@OrderID char(16),
@ClOrdID char(20),
@Account int,
@SenderId int
as
begin
set nocount on

insert Core.ExternalTrade(ExecID, SecondaryExecID, SecurityID, SecurityIDSource, LastQty, LastPx, TransactTime, Side, OrderID, ClOrdID, Account)
values (@ExecID, @SecondaryExecID, @SecurityID, @SecurityIDSource, @LastQty, @LastPx, @TransactTime, @Side, @OrderID, @ClOrdID, @Account)

return @@rowcount
end

And here is how I call the sp from c#: 这就是我从c#调用sp的方式:

using (SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["Connection"]))
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand("Core.up_ExternalTradeInsert", conn);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(new SqlParameter("@ExecID", execID));
                cmd.Parameters.Add(new SqlParameter("@SecondaryExecID", secondaryExecID));
                cmd.Parameters.Add(new SqlParameter("@SecurityID", securityID));
                cmd.Parameters.Add(new SqlParameter("@SecurityIDSource", securityIDSource));
                cmd.Parameters.Add(new SqlParameter("@LastQty", lastQty));
                cmd.Parameters.Add(new SqlParameter("@LastPx", lastPx));
                cmd.Parameters.Add(new SqlParameter("@TransactTime", transactTime));
                cmd.Parameters.Add(new SqlParameter("@Side", side));
                cmd.Parameters.Add(new SqlParameter("@OrderID", orderID));
                cmd.Parameters.Add(new SqlParameter("@ClOrdID", clOrdID));
                cmd.Parameters.Add(new SqlParameter("@Account", account));
                cmd.Parameters.Add(new SqlParameter("@SenderId", senderId));

                int result = cmd.ExecuteNonQuery();//.ExecuteNonQuery();
            }

The value ogf result variable is always -1 , but I see that sql statement works great. 值ogf结果变量始终为-1 ,但我看到sql语句的效果很好。 When I execute the sp in MSSQl Management Studio, I see the return value as 1 . 当我在MSSQl Management Studio中执行sp时,我看到返回值为1 Why? 为什么? What am I doing wrong? 我究竟做错了什么? I have to get the true return value from the the stored procedure. 我必须从存储过程中获取真实的返回值。

Thanks, 谢谢,

Expanding on what Andrei has said you should really use an OUTPUT parameter to see the number of rows affected, return value is only used to see the success/failure of the operation: 扩展Andrei所说的,您应该真正使用OUTPUT参数来查看受影响的行数,返回值仅用于查看操作的成功/失败:

A stored procedure with an output parameter would look something like.... 具有输出参数的存储过程看起来像...。

ALTER proc [Core].[up_ExternalTradeInsert]
@ExecID char(16),
@SecondaryExecID char(16),
@SecurityID int,
@SecurityIDSource int,
@LastQty int,
@LastPx decimal(12, 6),
@TransactTime datetime2(3),
@Side bit, --0 Sell 1-Buy
@OrderID char(16),
@ClOrdID char(20),
@Account int,
@SenderId int,
@RowCount INT OUTPUT
as
begin
set nocount on

insert Core.ExternalTrade(ExecID, SecondaryExecID, SecurityID, SecurityIDSource, LastQty, LastPx, TransactTime, Side, OrderID, ClOrdID, Account)
values (@ExecID, @SecondaryExecID, @SecurityID, @SecurityIDSource, @LastQty, @LastPx, @TransactTime, @Side, @OrderID, @ClOrdID, @Account)

  SET @RowCount =  @@rowcount;
end

And you C# code would look something like..... 而且您的C#代码看起来像.....

using (SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["Connection"]))
{
    conn.Open();
    SqlCommand cmd = new SqlCommand("Core.up_ExternalTradeInsert", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("@RowCount", SqlDbType.Int).Direction = ParameterDirection.Output;
    cmd.Parameters.Add(new SqlParameter("@ExecID", execID));
    cmd.Parameters.Add(new SqlParameter("@SecondaryExecID", secondaryExecID));
    cmd.Parameters.Add(new SqlParameter("@SecurityID", securityID));
    cmd.Parameters.Add(new SqlParameter("@SecurityIDSource", securityIDSource));
    cmd.Parameters.Add(new SqlParameter("@LastQty", lastQty));
    cmd.Parameters.Add(new SqlParameter("@LastPx", lastPx));
    cmd.Parameters.Add(new SqlParameter("@TransactTime", transactTime));
    cmd.Parameters.Add(new SqlParameter("@Side", side));
    cmd.Parameters.Add(new SqlParameter("@OrderID", orderID));
    cmd.Parameters.Add(new SqlParameter("@ClOrdID", clOrdID));
    cmd.Parameters.Add(new SqlParameter("@Account", account));
    cmd.Parameters.Add(new SqlParameter("@SenderId", senderId));

    cmd.ExecuteNonQuery();//.ExecuteNonQuery();
    int RowsAffected = Convert.ToInt32(cmd.Parameters["@RowCount"].Value);
}

ExecuteNonQuery returns number of rows affected, but only for 3 types of operations: ExecuteNonQuery返回受影响的行数,但仅适用于3种类型的操作:

For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command. 对于UPDATE,INSERT和DELETE语句,返回值是该命令影响的行数。 When a trigger exists on a table being inserted or updated, the return value includes the number of rows affected by both the insert or update operation and the number of rows affected by the trigger or triggers. 当要插入或更新的表上存在触发器时,返回值包括受插入或更新操作影响的行数以及受一个或多个触发器影响的行数。 For all other types of statements, the return value is -1. 对于所有其他类型的语句,返回值为-1。 If a rollback occurs, the return value is also -1. 如果发生回滚,则返回值也为-1。

Since stored procedure execution is neither of these, you are always getting -1. 由于存储过程执行都不是全部,因此您总是得到-1。 To get the result of your stored procedure, I believe you need to call ExecuteScalar . 为了获得存储过程的结果,我相信您需要调用ExecuteScalar

You can add a parameter with whatever name you want to give it and a Direction of ParameterDirection.ReturnValue to get the return value from your stored procedure. 您可以添加一个您想给它命名的参数以及一个ParameterDirection.ReturnValue的Direction来从存储过程中获取返回值。

Here is a sample PROC in a database named AdHoc: 这是名为AdHoc的数据库中的示例PROC:

CREATE PROCEDURE [dbo].[TestProc] 
    @InputParam int
AS
BEGIN
    return @InputParam * 2
END

And here is a C# snippet that you can execute in LINQPad to test it: 这是一个您可以在LINQPad中执行的C#代码片段以对其进行测试:

using (var conn = new SqlConnection(@"Data Source=(local);Initial Catalog=AdHoc;Integrated Security=SSPI")) {
    conn.Open();

    var cmd = new SqlCommand("TestProc", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("@InputParam", 21);
    cmd.Parameters.Add("@RetVal", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;

    cmd.Parameters.Dump();

    cmd.ExecuteNonQuery();

    cmd.Parameters.Dump();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM