You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CSV导入SQL Server避免重复数据插入的技术问询

解决CSV导入SQL Server时重复插入旧数据的问题

我来帮你搞定这个重复插入的麻烦!你现在的逐行插入方式不仅效率低,还没法过滤重复数据,用「临时表+批量导入+去重插入」的方案正好解决这个问题,具体步骤和代码如下:

核心思路

  • 先用SqlBulkCopy把CSV数据批量导入到SQL Server的临时表(比逐行插入效率高太多,尤其面对15000+条数据时)
  • 再通过SQL语句从临时表往正式表Silver_Robot插入数据,同时用WHERE NOT EXISTS过滤掉已经存在的记录(需要先确定业务上的唯一标识字段)

具体实现步骤

1. 确定唯一标识字段

首先得明确哪些字段组合能唯一标识一条记录,比如Program_S+Start_Date_S+Start_Time_S?这一步是去重的关键,务必根据你的业务逻辑确认。下面的代码会基于这个组合示例。

2. 修改C#代码

替换原来的逐行插入逻辑,改成批量导入临时表+去重插入:

private void Save_Import_Data_SQL(DataTable importData)
{
    using (SqlConnection conn = new SqlConnection(myconnstring))
    {
        conn.Open();

        // 1. 创建会话级临时表(会话结束自动销毁)
        using (SqlCommand createTempTableCmd = new SqlCommand(@"
            CREATE TABLE #TempSilverRobot (
                Program NVARCHAR(255),
                [Group] NVARCHAR(255),
                Start_Date DATETIME,
                Start_Time DECIMAL(18,2),
                Pieces DECIMAL(18,2),
                Finish_Date DATETIME,
                Finish_Time DECIMAL(18,2),
                Average_Part_Cycle_Time DECIMAL(18,2),
                Mode NVARCHAR(50),
                Length DECIMAL(18,2)
            )", conn))
        {
            createTempTableCmd.ExecuteNonQuery();
        }

        // 2. 用SqlBulkCopy批量导入DataTable到临时表
        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn))
        {
            // 映射DataTable列与临时表列(列名一致可省略,但手动映射更稳妥)
            bulkCopy.ColumnMappings.Add("Program", "Program");
            bulkCopy.ColumnMappings.Add("Group", "Group");
            bulkCopy.ColumnMappings.Add("Start date", "Start_Date");
            bulkCopy.ColumnMappings.Add("Start time", "Start_Time");
            bulkCopy.ColumnMappings.Add("Pieces", "Pieces");
            bulkCopy.ColumnMappings.Add("Finish date", "Finish_Date");
            bulkCopy.ColumnMappings.Add("Finish time", "Finish_Time");
            bulkCopy.ColumnMappings.Add("Average part cycle time", "Average_Part_Cycle_Time");
            bulkCopy.ColumnMappings.Add("Mode", "Mode");
            bulkCopy.ColumnMappings.Add("Length_pa", "Length");

            bulkCopy.DestinationTableName = "#TempSilverRobot";
            bulkCopy.WriteToServer(importData);
        }

        // 3. 从临时表插入正式表,过滤重复项
        // 注意:把WHERE NOT EXISTS里的条件替换成你实际的唯一标识字段组合
        using (SqlCommand insertCmd = new SqlCommand(@"
            INSERT INTO Silver_Robot(
                Program_S, Grpup_S, Start_Date_S, Start_Time_S, Pieces_S,
                Finish_Date_S, Finish_Time_S, Average_Part_Cycle_Time_S, Mode_S, Length_S
            )
            SELECT 
                Program, [Group], Start_Date, Start_Time, Pieces,
                Finish_Date, Finish_Time, Average_Part_Cycle_Time, Mode, Length
            FROM #TempSilverRobot temp
            WHERE NOT EXISTS (
                SELECT 1 
                FROM Silver_Robot sr
                WHERE sr.Program_S = temp.Program 
                AND sr.Start_Date_S = temp.Start_Date 
                AND sr.Start_Time_S = temp.Start_Time
            )", conn))
        {
            int rowsInserted = insertCmd.ExecuteNonQuery();
            // 可选:打印插入行数用于调试
            Console.WriteLine($"成功插入{rowsInserted}条新数据");
        }

        // 临时表会在连接关闭后自动销毁,无需手动删除
    }
}

3. 优化点说明

  • 批量导入:SqlBulkCopy比逐行ExecuteNonQuery效率提升数倍,上万条数据的导入速度会明显变快。
  • 去重逻辑:WHERE NOT EXISTS会精准检查正式表中是否已有相同记录,仅插入全新数据。如果需要更新已有记录(比如数据有修改),可以用MERGE语句替代INSERT...SELECT。
  • 临时表:会话级临时表(#开头)仅在当前数据库连接中存在,连接关闭后自动清理,不会残留冗余数据。

注意事项

  • 务必确保唯一标识字段组合的准确性,否则会出现重复插入或漏插的问题。
  • 如果Silver_Robot表有主键或唯一约束,也可以借助约束特性配合IGNORE_DUP_KEY,但WHERE NOT EXISTS的方式更直观可控。

内容的提问来源于stack exchange,提问作者Dinu Kuruppu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:20:39