如何使用SqlBulkCopy.WriteToServer将行大容量插入SQL Server,仅当不存在时



我们使用SqlBulkCopy.WriteToServer批量插入SQL Server,效果非常好。但是,当记录已经存在时,它将失败。我们需要的是";忽略";那些已经存在的行,并插入不存在的行。

SqlException:违反PRIMARY KEY约束"PK__Pharmacy__3214EC072C1E8537"。无法在对象"dbo.Pharmacy"中插入重复的密钥。重复的密钥值为(797cba76-8bbd-4dbd-a360-4f8e8a6ef85b(

如果行不存在,我们如何使用SqlBulkCopy.WriteToServer插入行而不中断或失败。

try
{
// Write from the source to the destination.
bulkCopy.WriteToServer(dt);
}
catch (Exception ex)
{
throw new Exception($"BulkInject error in {dt.TableName}", ex);
}

更新:值得一提的是,这在大多数情况下都能很好地工作,98%的时间都能正常进行批量插入。只有2%的时间,某些行已经存在,这将导致大容量插入失败。

我们需要什么:我们需要";忽略";那些行如果存在

我们所做的:将源数据库的数据传输到目标数据库。这不是完全转移。我们传输源数据的子集。dest数据库不为空。它已经包含数据。所以更新不是一个选项。如果不存在,我们需要插入。

大约有30个表是我们从源数据库大容量插入到目的数据库的。因此,我们有一个通用函数,可以进行字段映射、大容量插入等……它与处理所有这些表的函数相同。

同样,我们需要的是:我们正在使用SqlBulkCopy.WriteToServer,我们需要忽略";行(如果存在(。感谢

SqlBulkCopy作为名称建议用于复制(插入(大容量记录,不能执行更新操作。因此,表值参数应运而生,它允许我们使用DataTable将多个记录传递给存储过程,在存储过程中我们可以进行处理。。。

SQLServer2008(或更高版本(提出了一个名为MERGE的漂亮函数,它允许在表中不存在记录时执行INSERT操作,在表中存在记录时进行UPDATE操作。

您可以在SQL Server 中创建用户定义的表类型

最后,创建了以下类似类型的存储过程,它将接受整个DataTable作为参数,然后将所有不存在于表中的记录插入到表中,并且将更新已经存在的记录。

CREATE PROCEDURE [dbo].[Update_Pharmacy]
@tblCustomers CustomerType READONLY
AS
BEGIN
SET NOCOUNT ON;

MERGE INTO Customers c1
USING @tblCustomers c2
ON c1.CustomerId=c2.Id
WHEN MATCHED THEN
UPDATE SET c1.Name = c2.Name
,c1.Country = c2.Country
WHEN NOT MATCHED THEN
INSERT VALUES(c2.Id, c2.Name, c2.Country);
END

性能将不如Bulk Copy Utity,但不知何故,它是我在从实时数据库处理报告数据库时使用的选项之一。

最新更新