SqlBulkCopy保证插入正确数据行而非全部失败
导入数据时使用SqlBulkCopy结合DataTable那个速度是飕飕的,快得不行,特别适用于excel批量导入MSSQLServer。但是有个问题就是SqlBulkCopy是批量导入,只要有一条数据不符合数据库字段的类型(如int类型的,没有设置为DBNull.Value而是空字符或者其他非数字内容,字符串长度大于数据库字段定义的长度),会导致整个表格导入失败。
那么如何用SqlBulkCopy导入数据正确的行,而不导入失败的行?那就是使用折半递归插入,代码如下
//以下代码来源:http://blog.csdn.net/yudehui/article/details/38641783 public void InsertSqlBulk(DataTable dt) { SqlBulkCopy sqlBulk = new SqlBulkCopy(FStrConnecttion); sqlBulk.DestinationTableName = "Price2"; try { sqlBulk.WriteToServer(dt); } catch (Exception e) {//如果出现异常,SqlBulkCopy 会使数据库回滚,所有Table中的记录都不会插入到数据库中,此时,把Table折半插入,先插入一半,再插入一半。如此递归,直到只有一行时,如果插入异常,则返回。 if (dt.Rows.Count == 1) return; int middle = dt.Rows.Count / 2; DataTable table = dt.Clone(); for (int i = 0; i < middle; i++) table.ImportRow(dt.Rows[i]); InsertSqlBulk(table); table.Clear(); for (int i = middle; i < dt.Rows.Count; i++) table.ImportRow(dt.Rows[i]); InsertSqlBulk(table); } finally { sqlBulk.Close(); } }
小提示:注意DataTable所有列必须和数据库表一致,包括列数量。有些时候excel值包含某些列的值,所以建立DataTable只建立有数据的列,然后sqlbulkcopy.ColumnMappings.Add只添加这几列是会报错的,我就这样弄过,整半天才知道DataTable少了列,导致隐射错误。
参考资料:http://bbs.csdn.net/topics/390430064
SqlBulkCopy不是根据表的ColumnName来匹配的,而是根据ColumnIndex匹配, 也就是说你的表 字段必须跟数据库的表字段完全一致(Index的排序要跟数据表的一样)。 就算你该字段不打算给他插入值,也要建个DataColumn。包括自增ID.不需要给他值就好了
最后附上用SqlBulkCopy批量插入数据遇到的错误(来源:http://www.cnblogs.com/wz327/archive/2011/07/05/2098356.html)
错误一:来自数据源的 String 类型的给定值不能转换为指定目标列的类型 nvarchar。
还有其他的错误如:AddTime不能为DBNull (这个应该是目标表中AddTime要求不许为null),哈哈,错误多了,都忘记了。。。
可能的原因有两种
- 可能是有"'"(单引号),替换成““”(双引号)。
- 可能是目标表字段的长度比要导入的数据长度小。
错误二:给定的 ColumnMapping 与源或目标中的任意列均不匹配。
可能的原因
1.源数据的字段名称和目标数据的字段名称不匹配(大小写敏感的,这个要加强注意啊!)
如:UserName 和 Username ,这样就不行
加支付宝好友偷能量挖...
原创文章,转载请注明出处:SqlBulkCopy保证插入正确数据行而非全部失败