SSIS - 删除现有行然后插入,不完整的结果

Posted

技术标签:

【中文标题】SSIS - 删除现有行然后插入,不完整的结果【英文标题】:SSIS - Delete Existing Rows then Insert, Incomplete Result 【发布时间】:2014-12-10 20:14:36 【问题描述】:

我对 SSIS 比较陌生,知道处理重复是一个经常重复的问题,所以提前感谢您阅读我的文字墙并为我的复杂情况提供任何帮助。

我有一个 18179 行的小表(我们称之为 Destination),需要使用 SSIS 使用平面文件对其进行更新。我正在测试的 18179 行平面文件仅包含 Destination 中存在且已更改的记录。目前,我有一个包,它从平面文件中加载一个临时表(我们称之为 Stage),然后移动到数据流并查找

此数据流采用 Stage 并使用主键 OrderID 从 Stage on Destination 查找 LKP_OrderID 以查看记录是否存在。 如果 OrderID 在 Destination 中不存在,那么它将遵循 New OrderID 路径,并将记录插入到 Destination 中的 DST_OLE_Dest。

这是我遇到问题的地方:如果 OrderID 确实 存在于 Destination 中,那么它遵循现有 OrderID 路径。 CMD_Delete_Duplicates OLE DB 命令执行:

DELETE d
FROM dbo.Destination d
    INNER JOIN dbo.Stage s ON d.OrderID = s.OrderID

这应该会从 Destination 中删除 Stage 中存在的所有记录。然后它应该在 DST_OLE_Desti 处插入来自 Stage 的这些记录的更新版本。 但是,它似乎分 2 批处理 18179 行:在第一批中它处理 9972 行。

然后,在第二批中,它处理剩余的 8207 行。它显示它已将所有 18179 行插入到 Destination,但我只在 Destination 中插入了最后一批 8207 行。

我相信它会删除并插入第一批 9972 行,然后对第二批 8207 行再次运行上述从内部连接 ​​SQL 中删除的操作,无意中删除了刚刚插入的 9972 行并留下了 8207。

我发现将 DefaultBufferSize 最大化为 104857600 字节并增加数据流中的 DefaultBufferMaxRows 以便包一次处理所有 18179 行正确删除并插入所有 18179,但是一旦我的数据超过 104857600 文件大小,这将又是一个问题。我也可以使用 OLE DB 命令转换来运行

DELETE FROM dbo.Destination WHERE OrderID = ?

这应该从 Stage 传递 OrderID 并从存在匹配的 Destination 中删除,但这很耗时,并且对于这个小表大约需要 10 分钟。对于这个问题,还有其他解决方案吗?如果这是一个更好的选择,我将如何进行更新而不是插入和删除?

【问题讨论】:

【参考方案1】:

是的,你的逻辑有问题。您的 OLE DB 命令正在为流经它的每一行触发该删除语句。

相反,您希望该步骤成为数据流的先例(执行 SQL 任务)。这将在您开始加载目标表之前清除目标表中的现有数据。否则,就像您观察到的那样,您将退出新加载的数据。

有不同的方法来处理这个问题。如果删除工作,然后继续它。否则,人们通常会暂存对辅助表的更新,然后使用执行 SQL 任务作为数据流任务的后续任务并执行基于集合的更新。

【讨论】:

就这样做了,它看起来就像一个魅力。谢谢!【参考方案2】:

您可以使用 SSIS 工具箱中的渐变维度工具来更新行(而不是删除并重新插入)。您只有“类型 1”的声音变化,因此您不需要使用历史属性插入输出。

它会自动处理插图中的两个流 - 插入和更新

【讨论】:

以上是关于SSIS - 删除现有行然后插入,不完整的结果的主要内容,如果未能解决你的问题,请参考以下文章

SSIS - 批量插入每批有多少行可供选择?

插入,更新,删除数据

对现有 SSIS 包的更改

TableView:是不是可以在不重新加载 tableview 或部分的情况下删除现有行并插入新行?

SSIS 脚本任务基于路径的结果

如何向表中插入数据以及如何更新删除表中的数据