【问题标题】:Easy way of overwriting old rows in SSIS Package在 SSIS 包中覆盖旧行的简单方法
【发布时间】:2019-03-26 08:52:47
【问题描述】:

我创建了一个带有脚本组件的 SSIS 包,该组件从 JSON API 调用数据并将其插入到 SQL Server 中的表中。我已经设置了添加新行的逻辑,但是我想找到最合适的方法来删除/覆盖旧行。数据每 4 小时提取一次,因此每次运行包时会有大约 1000 行的重叠。

我的第一个想法是在删除重复行(具有最小 ID 号)的数据流任务之后简单地添加一个 SQL 任务。但是,我想知道如何在数据流任务中执行此操作? API 调用每次获取不超过 5000 行,目标表大约有 1m 行,整个项目大约运行。 10 秒。

我的简单数据流任务如下所示:

【问题讨论】:

  • "有更好的方法吗?"对 Stack Overflow 来说有点离题,因为它可以提供固执己见的答案,就像我即将做的那样。一种方法是将所有数据加载到不同的表中,然后重命名旧表和新表。然后截断旧的,并为每个负载重复循环(因此它们有效地交换名称)。不过,这取决于您的桌子的用途;我们几乎无事可做。
  • 我编辑了问题以减少受意见的影响。所以你的意思是我可以创建一个重复交换表和名称的设置?
  • 就像它在锡上所说的那样。加载到表中,交换名称,截断旧表。冲洗并重复。
  • 如果你每次都复制所有数据,你可以使用分区切换将rename/truncate进程变成一个耗时几毫秒的元数据操作。否则,您可以将新数据复制到临时表中,并使用 LEFT JOIN 查找目标表中已存在哪些行以及哪些行是新的。

标签: sql-server ssis


【解决方案1】:

您可以尝试两种主要方法:

  • 对行 ID 运行查找。如果匹配,则使用 UPDATE 语句为每一行运行 OLEDB 命令转换。如果不匹配 - 将行定向到 OLE DB 目标。
    易于实现,简单的逻辑,但大量的 UPDATE 语句会产生性能问题。

  • 在 DB 中创建一个中间表,在运行数据流任务之前对其进行清理,并将数据流中的所有行存储到这个中间表中。然后在下一个任务中 - 执行以下任一操作:

    • MERGE 与主表的中间表。有关MERGE 的更多信息。

    • 在事务中 - 从中​​间存在的主表中删除行,然后执行INSERT INTO <main table> SELECT ... FROM <intermediate table>

我通常更喜欢使用 MERGE 的中间表方法 - 高性能、简单且灵活。 MERGE 语句在并发会话或聚集列存储表中运行时可能会产生负面影响,然后我将中间表与 DELETE...INSERT 命令一起使用

【讨论】:

  • 所以我实际上最终做了第一个。就我而言(我在下面发布的解决方案),我没有太多行可以扫描和更新。所以性能并不是真正的问题。
【解决方案2】:

所以我发现就我的情况(只有相对较少的行要更新的情况)而言,最简单的解决方案是使用 OLE DB 组件,如下所示。

在组件中我添加了一个更新 SQL 语句,其逻辑如下

UPDATE  [dbo].[table]
SET    [value1]=?,
       [value2]=?,
       [value2]=?,
WHERE  [value1]=? 

然后我将参数映射到它们对应的列,并确保我的 where 子句使用查找匹配输出来更新正确的行。该组件确保使用我在查找组件中使用的列更新“查找匹配输出”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    • 2016-03-17
    相关资源
    最近更新 更多