我有几个表格,其中包含我从c#填充的主键约束。
在不违反主键的情况下插入行的最快方法是什么?
逐个执行语句和批处理是否会增加显着的开销?
如果我需要根据条件更新某些行,我会更好地使用存储过程并逐点调用它或使用合并吗?
1
foreach(var point in points)
{
...
sqlCommand.ExecuteNonQuery(@"
BEGIN TRY
INSERT INTO POINTS ...
END TRY
BEGIN CATCH
IF ERROR_NUMBER() <> 2627
BEGIN
THROW
END
END CATCH", con)
}
2
foreach(var point in points)
{
...
sqlCommand.ExecuteNonQuery(@"
IF NOT EXISTS (Select 1 from POINTS where ...)
INSERT INTO POINTS ...", con)
}
3
StringBuilder sb = new StringBuilder();
sb.AppendLine("BEGIN TRAN");
foreach(var point in points)
{
sb.AppendLine("IF NOT EXISTS (Select 1 from POINTS where ...) INSERT INTO POINTS ...")
}
sb.AppendLine("COMMIT TRAN");
sqlCommand.ExecuteNonQuery(sb.ToString());
4
StringBuilder sb = new StringBuilder();
sb.AppendLine(@"
BEGIN TRAN
DECLARE @POINTS TABLE (
...
)
");
foreach(var point in points)
{
sb.AppendLine("INSERT INTO @POINTS ...")
}
sb.AppendLine(@"
MERGE POINTS as T
USING @POINTS as S
ON T.KEY=S.KEY
WHEN OT MATCHED THEN
INSERT ...
");
sb.AppendLine("COMMIT TRAN");
sqlCommand.ExecuteNonQuery(sb.ToString());
答案 0 :(得分:7)
如果您的积分很大,请考虑先使用SqlBulkCopy将其插入临时表(例如#NEW_POINTS
)。这样你就可以避免每个点运行一个单独的INSERT语句。
然后,运行单个MERGE或INSERT / UPDATE的组合将数据移动到实际的POINTS表中。