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

时间:2015-08-17 15:19:28

标签: c# sql-server tsql stored-procedures ado.net

这是我的存储过程:

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时,我看到返回值为 1 。为什么?我究竟做错了什么?我必须从存储过程中获取真正的返回值。

谢谢,

3 个答案:

答案 0 :(得分:3)

扩展Andrei所说的你应该使用OUTPUT参数来查看受影响的行数,返回值仅用于查看操作的成功/失败:

带有输出参数的存储过程看起来像......

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

答案 1 :(得分:2)

ExecuteNonQuery返回受影响的行数,但仅适用于3种类型的操作:

  

对于UPDATE,INSERT和DELETE语句,返回值是受命令影响的行数。当插入或更新的表上存在触发器时,返回值包括插入或更新操作影响的行数以及受触发器或触发器影响的行数。对于所有其他类型的语句,返回值为-1。如果发生回滚,则返回值也为-1。

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

答案 2 :(得分:0)

您可以添加一个参数,其中包含您想要的名称和一个DirectionDirection.ReturnValue的方向,以从您的存储过程中获取返回值。

以下是名为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();
}