【问题标题】:Bulk insert into the SQL Server 2012 database - C#批量插入 SQL Server 2012 数据库 - C#
【发布时间】:2014-11-30 11:30:28
【问题描述】:

列表中有大约一百万条记录。并在列表中的 foreach 中查询数据库以获取基于 id 的修改日期。一旦我得到它,它会在条件下进行测试以插入或更新它..但是有没有办法将它作为批量(一次或批量)插入或更新..??

foreach (No_kemi no_list in newforSQL)
{
    DateTime eModifiedDate = no_list.ModifiedDate.Value;
    string Id = no_list.ID.ToString();

    String selectQuery = "SELECT ModifiedDate FROM NO_table WHERE ID = '" + Id + "'";
    DateTime? dbmoddate = null;

    using (SqlCommand selectCommand = new SqlCommand(selectQuery, connection))
    {
        // Use the above SqlCommand object to create a SqlDataReader object.
        using (SqlDataReader rdr = selectCommand.ExecuteReader())
        {
            while (rdr.Read())
            {
                dbmoddate = (DateTime)rdr["ModifiedDate"];
            }
        }
    }

    string eType = null;
    string SubGUID = null;
    string trimSubKey = no_list.SubscriberKey;

    try
    {
        if ((trimSubKey.Length > 3) && (trimSubKey != ""))
        {
            if (trimSubKey.Contains(","))
            {
                string[] values = trimSubKey.Split(',');

                SubGUID = values[0];
                eType = values[1];
            }
            else 
            { 
                SubGUID = trimSubKey; 
                eType = ""; 
            }
        }
        else 
        { 
             SubGUID = ""; 
             eType = ""; 
        }
    }
    catch (Exception ex)
    {
        logger.Error("Error : " + ex.Message );
    }

    if (dbmoddate == null)
    {
        DateTime no_listinsetdate = DateTime.Now;
        String insertQuery = "INSERT INTO NO_table (CreatedDate, ModifiedDate, ID, eType, SubGUID, DbDate) VALUES (@CreatedDate, @ModifiedDate, @ID, @eType, @SubGUID, @DbDate,)";

        using (SqlCommand insertCommand = new SqlCommand(insertQuery, connection))
        {
             insertCommand.Parameters.AddWithValue("@CreatedDate", no_list.CreatedDate);
             insertCommand.Parameters.AddWithValue("@ModifiedDate", no_list.ModifiedDate);
             insertCommand.Parameters.AddWithValue("@ID", no_list.ID);
             insertCommand.Parameters.AddWithValue("@eType", eType);
             insertCommand.Parameters.AddWithValue("@SubGUID", SubGUID);
             insertCommand.Parameters.AddWithValue("@DbDate", no_listinsetdate);

             insertCommand.ExecuteNonQuery(); // execute the query
         }
    }
    else if (eModifiedDate > dbmoddate)
    {
        DateTime no_listinsetdate = DateTime.Now;
        String updateQuery = "UPDATE  NO_table SET CreatedDate = @CreatedDate, ModifiedDate = @ModifiedDate, ID = @ID, eType = @eType, SubGUID = @SubGUID, DbDate = @DbDate WHERE ID = '" + Id + "'";

        using (SqlCommand updateCommand = new SqlCommand(updateQuery, connection))
        {
            updateCommand.Parameters.AddWithValue("@CreatedDate", no_list.CreatedDate);
            updateCommand.Parameters.AddWithValue("@ModifiedDate", no_list.ModifiedDate);
            updateCommand.Parameters.AddWithValue("@ID", no_list.ID);
            updateCommand.Parameters.AddWithValue("@eType", eType);
            updateCommand.Parameters.AddWithValue("@SubGUID", SubGUID);
            updateCommand.Parameters.AddWithValue("@DbDate", no_listinsetdate);

            updateCommand.ExecuteNonQuery(); // execute the query
        }
    }
}

任何加快进程的方法...完成操作需要很多时间...或者有时我会收到超时错误...

谢谢

【问题讨论】:

  • 你应该永远使用这样的东西:WHERE ID = '" + Id + "'"; - 像在其他任何地方一样使用参数

标签: c# database sql-server-2012


【解决方案1】:

这是一种在此处实际拥有编码解决方案的方法,但您应该能够根据一般建议自己创建一个:

如果您编写了一个执行此操作的 SQL 过程,您可能会节省大量的网络往返。进一步优化将导致此 SQL 过程采用批量记录而不是单个记录,因此您可以例如发送 1000 条记录,该过程将遍历它们,并为每条记录执行查询并生成更新/插入。这意味着结果不必在网络中来回传输,从而减少了流量并缩短了运行时间。

也许您的操作可以假设为单个 MERGE 命令,而不是查询和更新/插入。这取决于您的表结构、数据和意图。

Google 的条款:stored proceduretable typeMERGE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多