【问题标题】:when using ExecuteScalar it writes 2 Records instead of one使用 ExecuteScalar 时,它写入 2 条记录而不是 1 条
【发布时间】:2014-09-01 15:13:17
【问题描述】:

我需要知道已将哪个订单号写入数据库。为此,我使用 SQL 表达式 EXECUTESCOLAR

我调试了程序并监控了数据库。当我执行第二个命令时,该记录被写入数据库一次,它第二次写入相同的记录。你能帮我弄清楚我需要改变什么,这样它就不会写 2 条记录并且我会取回我的订单号吗?

这是我的代码:

public static int CreateDocumentNumber(string userId, string todaysDate, decimal docprice, decimal docpaid, int packageId, int orderstatus)
{
    int orderId = 0;   //return value order Id

    //create order 
    string connectionString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
    string insertSql = "INSERT INTO [dbo].[LD_Orders](TD_OrdUserID, TD_OrdDate, TD_OrdCost, TD_OrdPaid, TD_OrdPackage, TD_OrdStatus)" +
        " VALUES (@UserId, @Date, @Cost, @Paid, @Package, @Status);SELECT SCOPE_IDENTITY()";

    using (SqlConnection myConnection = new SqlConnection(connectionString))
    {
        myConnection.Open();
        SqlCommand myCommand = new SqlCommand(insertSql, myConnection);
        myCommand.Parameters.Add("@UserId", SqlDbType.VarChar).Value = userId;
        myCommand.Parameters.Add("@Date", SqlDbType.Date).Value = todaysDate;
        myCommand.Parameters.Add("@Cost", SqlDbType.Decimal).Value = docprice;
        myCommand.Parameters.Add("@Paid", SqlDbType.Decimal).Value = docpaid;
        myCommand.Parameters.Add("@Package", SqlDbType.Int).Value = packageId;
        myCommand.Parameters.Add("@Status", SqlDbType.Int).Value = orderstatus;
        myCommand.ExecuteNonQuery();  <---- FIRST RECORD WRITTEN

        // time to collect the last order id
        orderId = Convert.ToInt32(myCommand.ExecuteScalar());   <---- SECOND RECORD WRITTEN

        myConnection.Close();
    }
    return orderId;
}

【问题讨论】:

  • 每个Execute*调用都会触发一个insert语句,所以这个函数不需要两个
  • 谢谢 Zruty,所以我只删除了我的第一个 excecuteNonQuery,然后一切都会好起来的
  • 那么请把下面的答案标记为正确
  • 这可能是重复的,因为我觉得 Rene 的要求在这里存在。 stackoverflow.com/questions/14246744/…
  • 您执行了两次INSERT - 那么为什么插入两行会让您感到惊讶?!?!?!?!

标签: c# sql executescalar scope-identity


【解决方案1】:

如果您删除 myCommand.ExecuteNonQuery(); 行,您的代码应该可以工作

ExecuteNonQuery()ExecuteScalar() 都将命令发送到 SQL 服务器,唯一的区别是它们如何处理结果。基本上,您正在执行两个不需要的 INSERT 语句。

另一方面,现在很少有理由进行核心 ADO.NET 编码。如果您使用 ORM(例如 Entity Framework 或我个人最喜欢的 Dapper.NET),通常可以节省大量时间。

以下是使用 Dapper 重写整个函数的方法:

public static int CreateDocumentNumber(string userId, string todaysDate, decimal docprice, decimal docpaid, int packageId, int orderstatus)
{
    //create order 
    string connectionString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
    string insertSql = "INSERT INTO [dbo].[LD_Orders](TD_OrdUserID, TD_OrdDate, TD_OrdCost, TD_OrdPaid, TD_OrdPackage, TD_OrdStatus)" +
        " VALUES (@UserId, @Date, @Cost, @Paid, @Package, @Status);SELECT SCOPE_IDENTITY()";

    using (SqlConnection myConnection = new SqlConnection(connectionString))
    {
        myConnection.Open();
        int orderId = myConnection.Query<int>(
            insertSql,
            new {
                   UserId = userId,
                   Date = todaysDate,
                   Cost = docprice,
                   Paid = docpaid,
                   Package = packageId,
                   Status = orderstatus
                }).Single();
    }
    return orderId;
}

【讨论】:

  • 感谢反馈和 dapper.net 的建议。谢谢你。我通过删除线对其进行了测试,效果很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
相关资源
最近更新 更多