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

时间:2014-12-10 20:14:37

标签: sql tsql ssis

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

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

enter image description here

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

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

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

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

first batch

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

我相信它会删除并插入第一批9972行,然后再次从内连接SQL中为第二批8207行运行上面的删除,无意中删除刚插入的9972行,并留下我的8207。 / p>

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

DELETE FROM dbo.Destination WHERE OrderID = ?

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

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

您可以使用SSIS工具箱中的Slowly Changing Dimension工具更新行(而不是删除和重新插入)。你只有' Type 1'通过声音改变,因此您不需要使用历史属性插入输出。

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