近来有一个项目Feature需要有批量写入数据的场景,正巧整理资料发现自己以前也类似实现的项目,在重构的同时把相关资料做了一个简单的梳理,方便大家参考。
- 循环写入(简单粗暴,毕业设计就这样干的)(不推荐)
- Bulk Copy写入(>1000K 记录一次性写入推荐)
- 表值参数方式写入(mssql 2008新特性)(强烈推荐)
在SQL Server 2008未提供表值参数之前,需要将多行数据传递到存储过程或参数化sql命令我们一般会采用以下几个方法:
- 使用一系列单参数来表示多个数据列和行中的值。但使用这个方法会受所允许参数数量限制。Sql server 程序最多可以有2100个参数。服务器必须将这些参数进行再组织成临时表或表变量再进行后续处理。
- 将多个数据增加分隔字符串或序列化为xml字符串,然后将这些字符回传服务器。服务器根据解析字符串与xml进行处理。
- 将多条写入语句包装在一个单条语句当中。这种方式同sqldataadapter当中的update方法的实现逻辑,可以标识批次处理的个数。不过就算按照包装多个语句进行批次提交,每个语句仍然会分别在服务器上执行。(只是节约了请求的次数而已)
- 使用BCP实用工具或SqlBulkCopy对象将很多行数据加载到表中。尽管这荐技术非常有效,但不支持服务器处理,除非将数据加载到临时表或表变量中。
方案一
作为早期学习时出镜率最高的的实现方法我在这里就不特别说明了,在这里直接上码及测试数据:
public static void NormalInsertDate(DataTable dt) { using (var sqlConn = new SqlConnection(_testDataConnectionString)) { var sql = "INSERT INTO Student(Name,Age) VALUES(@Name,@Age)"; using (var cmd = new SqlCommand(sql, sqlConn)) { sqlConn.Open(); cmd.Parameters.Add("@Name", SqlDbType.NVarChar, 50); cmd.Parameters.Add("@Age", SqlDbType.Int); for (int i = 0; i < dt.Rows.Count; i++) { cmd.Parameters["@Name"].Value = dt.Rows[i]["Name"]; cmd.Parameters["@Age"].Value = dt.Rows[i]["Age"]; cmd.ExecuteNonQuery(); } } } }