我试图通过使用临时表和MERGE
命令在SQL Server 2008数据库中执行批量“upsert”。首先,我将列表对象中的所有数据加载到DataTable
。然后,我在SQL数据库中创建一个临时表,加载该表中的数据,然后在临时表和目标表上调用MERGE
。
我正在使用ExecuteNonQuery()
对象的SqlCommand
方法来调用MERGE
。问题是,这只会告诉我添加的记录总数,但不会指定哪些记录。
是否有方法或技术可以我以编程方式确定在交易过程中哪些记录错误?以下是我正在使用的方法。
private static string insertCommand =
"INSERT (ChannelCode, DrmTerrDesc, IndDistrnId, StateCode, ZipCode, EndDate, EffectiveDate, LastUpdateId, LastUpdateDate, ErrorCodes, Status) " +
"VALUES(Source.ChannelCode, Source.DrmTerrDesc, Source.IndDistrnId, Source.StateCode, Source.ZipCode, Source.EndDate, Source.EffectiveDate, Source.LastUpdateId, Source.LastUpdateDate, Source.ErrorCOdes, Source.Status)";
private static string updateCommand = "UPDATE SET Target.ChannelCode = Source.ChannelCode, Target.DrmTerrDesc = Source.DrmTerrDesc, Target.IndDistrnId = Source.IndDistrnId," +
"Target.StateCode = Source.StateCode, Target.ZipCode = Source.ZipCode, Target.EndDate = Source.EndDate, Target.EffectiveDate = Source.EffectiveDate," +
"Target.LastUpdateId = Source.LastUpdateId, Target.LastUpdateDate = Source.LastUpdateDate, Target.ErrorCodes = Source.ErrorCodes," +
"Target.Status = Source.Status ";
public static void Update(List<ZipCodeTerritory> updates, Dictionary<ZipCodeTerritory, string> errorList)
{
try
{
//Load updates into datatable
DataTable table = LoadData(updates, true);
//Script to create temp table
string tmpTable = "CREATE TABLE [dbo].[ZipCodeTerritoryTemp]( " +
"[ChannelCode] [char](1) NOT NULL, " +
"[DrmTerrDesc] [nvarchar](30) NOT NULL, " +
"[IndDistrnId] [char](3) NULL, " +
"[StateCode] [char](3) NOT NULL, " +
"[ZipCode] [char](9) NULL, " +
"[EndDate] [date] NOT NULL, " +
"[EffectiveDate] [date] NOT NULL, " +
"[LastUpdateId] [char](8) NULL, " +
"[LastUpdateDate] [date] NULL, " +
"[Id] [int] NULL, " +
"[ErrorCodes] [varchar](255) NULL, " +
"[Status] [char](1) NULL)";
using (SqlConnection connection = new SqlConnection(connString))
{
connection.Open();
//Create temp table
SqlCommand cmd = new SqlCommand(tmpTable, connection);
cmd.ExecuteNonQuery();
try
{
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
{
//Write to temp table
bulkCopy.DestinationTableName = "ZipCodeTerritoryTemp";
bulkCopy.WriteToServer(table);
//Merge changes in temp table with ZipCodeTerritory
string mergeSql = "merge ZipCodeTerritory as Target " +
"using ZipCodeTerritoryTemp as Source " +
"on " +
"Target.Id = Source.Id " +
"when matched then " +
updateCommand +
"when not matched then " +
insertCommand + ";";
cmd.CommandText = mergeSql;
int results = cmd.ExecuteNonQuery();
}
}
catch (Exception)
{
throw;
}
finally
{
//Drop temp table
SqlCommand final = new SqlCommand("DROP TABLE [dbo].[ZipCodeTerritoryTemp]", connection);
final.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
string msg = ex.Message;
}
}