我有一个进程,它接受一个列表并使用SQL批量复制将其插入到数据库中,因为这个列表的大小有多大.它工作正常,检查约束和所有这些都是完美的.问题是,如果我有10,000条记录,其中一条记录有错误,我仍然要提交其他9,999条记录.有没有办法做到这一点,除了在SQL批量复制或一次插入一个之前手动检查每个约束?看起来单调乏味而且速度慢.谢谢.
var copy = new SqlBulkCopy(ConfigurationManager.ConnectionStrings["constr"].ConnectionString, SqlBulkCopyOptions.CheckConstraints)
{
DestinationTableName = obj.TableName
};
var table = new DataTable();
copy.WriteToServer(table);
最佳答案 如果没有将
batch size设置为1(这会破坏批量复制的目的)或者在复制之前预先检查数据,则围绕此问题的正常方法是复制到具有与目标表相同的模式的临时表,但是没有约束,删除会违反插入约束的行,然后从临时表中执行正常插入到您的实时表中.
const string _createTableString = "Create table #temp (/* SNIP */)";
const string _insertTableString = @"
declare @sql nvarchar(2000)
set @sql = N'INSERT INTO ' + QUOTENAME(@tableName) + N' SELECT * from #temp'
exec sp_executesql @sql";
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["constr"].ConnectionString))
{
connection.Open();
using (var command = new SqlCommand(_createTableString, connection))
{
command.ExecuteNonQuery();
}
using (var copy = new SqlBulkCopy(connection))
{
copy.DestinationTableName = "#temp";
copy.WriteToServer(table);
}
using (var command = new SqlCommand(_insertTableString, connection))
{
command.Parameters.AddWithValue("@tableName", obj.TableName)
command.ExecuteNonQuery();
}
}
请注意使用QUOTENAME以确保没有SQL注入可以通过传递给obj.TableName的表的名称潜入.