SqlServer使用SqlBulkCopy批量新增和更新数据,快速高效

本文介绍如何使用C#的SqlBulkCopy类进行批量新增和更新数据,实现对SqlServer数据库的快速高效操作。MSCL工具类库提供强大的数据库操作支持,包括数据库连接、Lambda表达式支持,简化开发流程,提升编程效率。
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Collections;
using System.Reflection;
using System.Configuration;

namespace Magic.Tool
{
    /// <summary>
    /// sqlserver数据库批量新增修改类
    /// </summary>
    public static class SqlBulkHelper
    {
        #region 数据库连接字符串
        /// <summary>
        /// 数据库连接字符串
        /// </summary>
        public static readonly string ConnString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
        #endregion

        #region SqlBulkCopy方式批量新增数据
        /// <summary>
        /// SqlBulkCopy方式批量新增数据
        /// </summary>
        /// <typeparam name="T">对象</typeparam>
        /// <param name="modelList">实体类集合</param>
        /// <param name="destinationTableName">目标表明</param>
        /// <param name="removeColumns">移除的字段列集合</param>
        /// <param name="bulkCopyTimeout">超时时间</param>
        public static void BulkCopy<T>(List<T> modelList, string destinationTableName, List<string> removeColumns = null, int? bulkCopyTimeout = null)
        {
            if (string.IsNullOrEmpty(destinationTableName))
            {
                destinationTableName = typeof(T).Name;
            }
            var dt = ContainHelper.ListToTable(modelList);
            if (removeColumns != null && removeColumns.Count > 0)
            {
         
<think>好的,我现在需要帮助用户解决如何在SQL Server中实现批量插入数据的问题。用户之前已经询问过这个问题,并得到了详细的回答,现在他们再次提问,可能是在确认或者需要更多的信息。首先,我要回顾之前的对话,确保这次回答一致且更全面。 用户提供的引用中有几个关键点:BULK INSERT、SqlBulkCopy、INSERT INTO SELECT、存储过程,以及处理重复数据的方法。这些在之前的回答中已经涵盖,但用户可能希望得到更详细的步骤或者更多的示例。 我需要检查是否有遗漏的方法,比如使用表值参数或者OPENROWSET,这些在之前的回答中没有提到,但可能对用户有帮助。同时,用户提到在mybatis中遇到语法错误,这可能是因为SQL Server的批量插入语法与其他数据库不同,需要强调这一点。 用户的需求可能是希望高效地插入大量数据,同时避免重复处理性能问题。根据引用中的信息,SqlBulkCopy在.NET环境中非常高效,而BULK INSERT适合从文件导入。INSERT INTO SELECT适用于表间迁移,存储过程适合生成测试数据。 用户可能还需要知道如何优化批量插入的性能,比如禁用索引、使用事务、调整恢复模式等,这些已经在之前的回答中提到,但需要再次强调。 此外,用户的问题可能涉及到实际应用中的具体问题,比如如何处理重复数据,引用[4]中的CHECKSUM方法可以在这里再次提及,作为解决方案的一部分。 需要确保回答结构清晰,分点列出不同的方法,并给出示例代码,同时注明引用来源。还要注意用户提到的mybatis中的语法错误,可能需要说明SQL Server与其他数据库批量插入语法上的差异,避免用户再次踩坑。 最后,生成的相关问题需要针对用户可能遇到的后续问题,比如如何选择不同数据量的方法,处理重复数据,以及性能优化等。这些问题需要与之前的回答保持一致,并覆盖用户可能关心的方面。 总结下来,回答需要覆盖多种方法,提供代码示例,引用相关来源,并给出优化建议,同时解答用户可能隐藏的疑问,如语法差异性能处理。</think>在 SQL Server 中实现批量插入数据有以下五种常用方法,根据数据来源场景选择最合适的方案: --- ### 一、SqlBulkCopy(.NET 应用程序首选) ```csharp public static void BulkInsert(DataTable data) { using (SqlConnection conn = new SqlConnection("连接字符串")) { conn.Open(); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn)) { bulkCopy.DestinationTableName = "目标表"; bulkCopy.BatchSize = 5000; // 推荐每批5000-10000条 bulkCopy.ColumnMappings.Add("源列1", "目标列1"); bulkCopy.ColumnMappings.Add("源列2", "目标列2"); bulkCopy.WriteToServer(data); } } } ``` **特点**: - 比逐条 INSERT 快 10-100 倍[^1] - 支持列映射批量大小控制 - 需注意 DataTable 的列顺序与目标表一致 --- ### 二、BULK INSERT 语句(服务器文件导入) ```sql BULK INSERT 订单表 FROM 'D:\orders.csv' WITH ( FIELDTERMINATOR = '|', -- CSV分隔符 ROWTERMINATOR = '\n', CODEPAGE = '65001', -- UTF-8编码支持 TABLOCK, ERRORFILE = 'D:\error_log.txt' ); ``` **特点**: - 直接操作服务器本地文件 - 支持 CSV/TXT 格式,最快可达每秒 10 万条[^2] - 需要文件访问权限 --- ### 三、INSERT INTO SELECT(表间数据迁移) ```sql INSERT INTO 产品表 (产品名称, 价格) SELECT SUBSTRING(临时表.产品描述, 1, 50), -- 数据转换示例 临时表.成本价 * 1.2 -- 计算字段示例 FROM 临时表 WHERE NOT EXISTS ( SELECT 1 FROM 产品表 WHERE 产品表.产品编号 = 临时表.产品ID ); ``` **特点**: - 支持复杂查询去重逻辑 - 可利用 WHERE 条件过滤数据[^3] - 适合数据库内部数据迁移 --- ### 四、表值参数(存储过程批量处理) ```sql CREATE TYPE dbo.EmployeeType AS TABLE ( Name NVARCHAR(50), Salary DECIMAL(18,2) ); CREATE PROCEDURE InsertEmployees @Employees dbo.EmployeeType READONLY AS BEGIN INSERT INTO 员工表 (姓名, 工资) SELECT Name, Salary FROM @Employees WHERE Salary > 3000; -- 数据过滤示例 END ``` **特点**: - 支持 .NET 中的 DataTable 直接传递 - 可配合存储过程实现业务逻辑 - 适合中等数据量(万级)传输 --- ### 五、生成测试数据(WHILE 循环) ```sql DECLARE @i INT = 1; WHILE @i <= 100000 BEGIN INSERT INTO 日志表 (时间戳, 操作内容) VALUES ( DATEADD(MINUTE, @i, '2024-01-01'), '操作' + CAST(@i AS VARCHAR) ) SET @i += 1000; -- 步长优化 END ``` **优化技巧**: - 每 1000 条提交一次事务 - 禁用索引可提速 50%[^4] - 使用计算字段替代字符串拼接 --- ### 性能优化关键点 1. **事务控制**: ```sql BEGIN TRANSACTION -- 批量操作 COMMIT TRANSACTION -- 建议每1-10万条提交一次 ``` 2. **索引管理**: ```sql ALTER INDEX ALL ON 目标表 DISABLE; -- 执行批量插入 ALTER INDEX ALL ON 目标表 REBUILD; ``` 3. **日志优化**: ```sql ALTER DATABASE 当前库 SET RECOVERY SIMPLE; -- 批量操作 ALTER DATABASE 当前库 SET RECOVERY FULL; ``` --- ### 常见问题解决方案 **Q:如何避免插入重复数据?** ```sql INSERT INTO 主表 (字段1, 字段2) SELECT 字段A, 字段B FROM 来源表 S WHERE NOT EXISTS ( SELECT 1 FROM 主表 WHERE 主表.唯一字段 = S.唯一字段 ); ``` **Q:批量插入时数据类型不匹配?** - 使用 CONVERT/CAST 函数转换 - 添加 TRY...CATCH 块捕获错误[^5] ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

smartsmile2012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值