【问题标题】:Bulk Insert with Table Valued Parameter with duplicate rows带有重复行的表值参数的批量插入
【发布时间】:2017-04-24 20:52:49
【问题描述】:

需要在一个 SQL 表中插入多条记录。如果有重复(已经插入的记录),那么我想忽略它们。

为了将多条记录从我的代码发送到 SQL,我使用的是表值参数。

我在考虑两个选项。

选项 1:对 SQL 表进行 get 调用并检查是否存在重复并返回重复的行键。仅对 SQL 表中不存在的行键执行带表值参数的多次插入。

选项 2:使用表值参数并调用批量插入。在 SQL 中进行重复检测并忽略重复行。

实现的SQL如下:

@tvpNewFMdata 是表值参数。

    INSERT INTO
        [dbo].[FMData]
        (
            [Id],
            [Name],
            [Path],
            [CreatedDate],
            [ModifiedDate]
        )
    SELECT 
        fm.Id, fm.Name, fm.Path, GETUTCDATE(), GETUTCDATE() 
    FROM 
        @tvpNewFMdata AS fm
    WHERE 
        fm.Id NOT IN 
        (
        SELECT 
            [Id] 
        FROM 
            [dbo].[FMdata]
        )

在 SQL 方法中,我先进行选择以检查该行是否存在,仅当不存在时才进行插入。

想要更好地了解哪种方法在性能方面进行了优化。也想了解一下上面的查询是否优化了。

【问题讨论】:

标签: sql sql-server database sql-server-2008 tsql


【解决方案1】:

您的代码看起来不错,但我可能会提出一些建议。

首先,使用CreatedDateModifiedDate 的默认值。这样,您无需在每次插入行时都设置值。

其次,我不是NOT IN 的粉丝,而是更喜欢NOT EXISTS。我更喜欢NOT EXISTS,因为它在子查询返回NULL 值时更直观。但是,我猜IdFMData 中的主键,所以它永远不可能是NULL

第三,Id 应该有一个索引。 . .它将作为主键。

第四,代码不是线程安全的,这意味着同时运行相同的代码两次可能会产生错误。我猜这不是这段代码的问题,但如果是这样,你可以调查table locking hints

除了在Id 上存在索引之外,这些 cmets 都没有解决性能问题。从性能的角度来看,您的代码应该没问题。

【讨论】:

  • Id 是主键,因此有一个索引。关于线程安全,除非我使用正确的锁定提示。
猜你喜欢
  • 2017-05-01
  • 1970-01-01
  • 2011-11-10
  • 2018-04-17
  • 1970-01-01
  • 2017-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多