使用SqlBulkCopy时跳过现有记录

4

我正在尝试使用SqlBulkCopy将一张SQL表中的行复制到另一张表中。
在目标表已经包含了与我正在尝试添加的主键相同的元组时,它能够很好地工作。
现在我只需要一个选项,如果目标表中已经存在该元组,则跳过该元组。
请问有人可以指点我正确的方向吗?

目前我的代码看起来像这样:

using(SqlConnection source = new SqlConnection(sourceConnectionstring))
{
    source.Open();

    SqlCommand cmd = new SqlCommand("SELECT * FROM MyTable");

    SqlDataReader reader = cmd.ExecuteReader();

    using(SqlBulkCopy bulkData = new SqlBulkCopy(destinationConnectionstring))
    {
        bulkData.DestinationTableName = "MyTable";

        bulkData.WriteToServer(reader);
    }
}

我想,有一种(可怕的)方法是创建一个仅包含目标表中不存在元组的DataTable……但是难道没有选项(或不同的类?)可以让它简单快捷吗?


5
将您的选择查询更改为仅选择要插入到另一个表中的行。 - Jen R
在使用批量复制之前过滤数据表或者在 SQL 查询中添加 DISTINCT 或 WHERE 子句,这样做为什么会是一个可怕的想法呢? - Jacob H
2个回答

1

我不知道SqlBulkCopy类中是否有跳过重复键的选项。你可以尝试在目标表的主键上设置IGNORE_DUP_KEY选项。这将要求您必须删除主键约束并按照以下方式重新创建它:

IF  EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[YourTable]') AND name = N'YourPrimaryKey')
ALTER TABLE [dbo].[YourTable] DROP CONSTRAINT [YourPrimaryKey]

GO

/****** Object:  Index [PK_PKallowDup]    Script Date: 05/22/2012 10:23:13 ******/
ALTER TABLE [dbo].[YourTable] ADD  CONSTRAINT [YourPrimaryKey] PRIMARY KEY CLUSTERED 
(
    [YourPrimaryKeyColumn] ASC
)WITH (IGNORE_DUP_KEY = ON, PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

0
但是难道没有一个选项(或者是另一个类?)我可以使用来保持简单和快速吗?
不,对于SqlBulkCopy来说没有这样的选项。
免责声明:我是Bulk Operations项目的拥有者。
这个库不是免费的,但提供了你正在寻找的InsertIfNotExists选项。
using(SqlConnection source = new SqlConnection(sourceConnectionstring))
{
    source.Open();

    SqlCommand cmd = new SqlCommand("SELECT * FROM MyTable");

    SqlDataReader reader = cmd.ExecuteReader();

    using(BulkOperation bulkData = new BulkOperation(destinationConnectionstring))
    {
        bulkData.DestinationTableName = "MyTable";

        // INSERT only if row doesn't exist in the destination
        bulkData.InsertIfNotExists = true;
        bulkData.WriteToServer(reader);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接