【问题标题】:Getting return value from stored procedure - C#从存储过程中获取返回值 - C#
【发布时间】:2015-08-17 15:19:27
【问题描述】:

这是我的存储过程:

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

谢谢,

【问题讨论】:

  • ConfigurationManager.AppSettings["Connection"]) 是一个良好且正确的连接字符串吗?
  • 您考虑过使用OUTPUT 参数吗? SP 的返回值旨在成为完成状态。
  • 使用int result = (int)cmd.ExecuteScalar();,它应该可以工作。 ExecuteNonQuery 不会返回一些东西。
  • 尝试使用输出参数:stackoverflow.com/a/10908586/673707

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


【解决方案1】:

扩展安德烈所说的你应该真正使用 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);
}

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      你可以添加一个你想给它的任何名字的参数和一个 ParameterDirection.ReturnValue 的方向来从你的存储过程中获取返回值。

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

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

      这是一个 C# sn-p,您可以在 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();
      }
      

      【讨论】:

        猜你喜欢
        • 2010-10-16
        • 2013-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多