从存储过程获取 return 值 - C#

Getting return value from stored procedure - C#

这是我的存储过程:

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

下面是我如何从 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();
            }

ogf 结果变量的值始终是 -1,但我看到 sql 语句效果很好。当我在 MSSQl Management Studio 中执行 sp 时,我看到 return 值为 1。为什么?我究竟做错了什么?我必须从存储过程中获取真实的 return 值。

谢谢,

ExecuteNonQuery returns 受影响的行数,但仅针对 3 种类型的操作:

For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command. 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. If a rollback occurs, the return value is also -1.

由于存储过程执行不是这些,所以您总是得到 -1。要获得存储过程的结果,我相信您需要调用 ExecuteScalar.

扩展 Andrei 所说的,您应该真正使用 OUTPUT 参数来查看受影响的行数,return 值仅用于查看操作的 success/failure:

带有输出参数的存储过程类似于....

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

你的 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);
}

您可以添加任意名称的参数和 ParameterDirection.ReturnValue 的方向,以从存储过程中获取 return 值。

这是名为 AdHoc 的数据库中的示例 PROC:

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

这里是一个 C# 片段,您可以在 LINQPad 中执行它来测试它:

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