需求:A库里有上万条记录,B库里也有上万条记录,我想将A库里的数据添加到B库里,满足:当A库里的一条记录与B库里的一条记录相同,则将B库里的数据更新成A库里相同主键的记录;如果A库里的一条记录在B库里找不到,则插入(这里的记录相同是表示主键值相同)。
public void BulkCopyDA(DataTable sourceDate)

...{

string connectionString = ConfigurationSettings.AppSettings["ConnectionStrings"];

SqlConnection destinationConnection = new SqlConnection(connectionString);

using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection))

...{

bulkCopy.NotifyAfter = sourceDate.Rows.Count;

bulkCopy.BulkCopyTimeout = 5000000;

bulkCopy.DestinationTableName = "dbo.PersonInfo";

destinationConnection.Open();
//添加映射我只列举了一个映射,如果两个表的字段对应不上必须要做映射,如果两个表完全相同不用映射
bulkCopy.ColumnMappings.Add("Person_ID", "Person_ID");

try

...{
bulkCopy.WriteToServer(sourceDate); //sourceDate是源数据表
}
catch (Exception ex)

...{
Console.WriteLine(ex.Message);
}
finally

...{
destinationConnection.Close();
}
}

}
//删除主键值方法
public void DeleteInfo(DataTable dt)

...{

string strPerson_ID = "";
if (dt != null)

...{
for (int i = 0; i < dt.Rows.Count; i++)

...{
strPerson_ID += dt.Rows[i]["Person_ID"].ToString() + "&";
}
try

...{
string storedProcName = "PersonInfo_BulkDelete";
string connectionString = ConfigurationSettings.AppSettings["ConnectionStrings"];
SqlConnection connect = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand(storedProcName, connect);
command.CommandType = CommandType.StoredProcedure;
connect.Open();

SqlParameter sqlparam = new SqlParameter("@Person_ID", SqlDbType.NVarChar);
sqlparam.Value = strPerson_ID;
command.Parameters.Add(sqlparam);
command.ExecuteNonQuery();
command.Dispose();
connect.Close();
}
catch (Exception e)

...{
Console.WriteLine(e.Message);
}
finally

...{
}
}
}
CREATE PROC [dbo].[PersonInfo_BulkDelete]
@Person_ID nvarchar(max)
as
begin
create table #t(ID int)
while charindex('$',@Person_ID,1)<>0
begin
INSERT INTO #t
select SUBSTRING(@Person_ID,0,charindex('$',@Person_ID,1))
SET @Person_ID = SUBSTRING(@Person_ID,charindex('$',@Person_ID,1)+1,LEN(@Person_ID))
end
delete from PersonInfo where Person_ID in (select Person_ID from #t)
drop table #t
end
今天遇到这个问题,第一个感觉想到的是要对每一条记录进行操作,就是先取出A库中的记录,然后访问B库进行操作,也就是说A库里有多少条记录就要访问多少次B库。我感觉这个方式不好,对库的操作次数太多,影响效率。像一个更好的办法解决它!
大家知道ADO.NET2.0提供一个新类“SqlBulkCopy”,这个类是用于批量插入,对于它的效率可以是分条插入记录的至少5倍(我测试的,可能不是很准确)。
我首先从这个类入手,但是这个类只能批量插入,不存在更新,所以对我们的需求还用一定差距,但是我们可以将B库里记录与A库里的记录主键相同的记录删除,然后再将A库里的记录批量插入到B库,但是当我们将B库里记录与A库里的记录主键相同的记录删除时,我们还是要对B库操作A库中记录数。如果我们将A库中的主键值拼成一个字符串做为参数,所以只需要对B库访问两次即可达到我们想要的结果。下面是我做的例子:
































































































