我正在使用 SSIS 将数据从 Oracle 数据库迁移到 SQL Server 2008 r2 数据库。我的问题是,在某个时候,包会失败,比如 100,000 行中有 40,000 行。我该怎么做,以便下次在更正错误或其他内容后运行包时,我希望它从第 40,001 行重新启动,即发生错误的行。
我曾尝试在 SSIS 中使用检查点,但问题是它们只能在不同的控制流任务之间工作。我想要一些可以在正在传输的行上工作的东西。
我正在使用 SSIS 将数据从 Oracle 数据库迁移到 SQL Server 2008 r2 数据库。我的问题是,在某个时候,包会失败,比如 100,000 行中有 40,000 行。我该怎么做,以便下次在更正错误或其他内容后运行包时,我希望它从第 40,001 行重新启动,即发生错误的行。
我曾尝试在 SSIS 中使用检查点,但问题是它们只能在不同的控制流任务之间工作。我想要一些可以在正在传输的行上工作的东西。
我知道没有原生魔法会“知道”它在第 40,000 行失败,当它重新启动时,它应该开始流式传输第 40,001 行。你是正确的,检查点不是答案并且有很多自己的问题(不能序列化对象类型,循环重新启动等)。
如何解决这个问题是通过良好的设计。如果您的包是在预期它会失败的情况下创建的,那么您应该能够处理这些情况。
有两种我熟悉的方法。第一种方法是在源和目标之间的数据流中添加查找转换。这样做的目的是确定目标系统中存在哪些记录。如果未找到匹配项,则仅将这些行发送到目的地。这是一种非常常见的模式,您还可以检测源和目标之间的变化(如果需要的话)。缺点是您将始终将完整的数据集传输出源系统,然后过滤数据流中的行。如果它在 1,000,000 行中的第 99,999 行失败,您仍然需要将所有 1,000,000 行流式传输回 SSIS,以便它找到尚未发送的 1。
另一种方法是在源的 WHERE 子句中使用动态过滤器。如果您可以假设行是按顺序插入的,那么您可以构建您的 SSIS 包,使其看起来像Execute SQL Task
您SELECT COALESCE(MAX(SomeId), 0) +1 AS startingPoint FROM dbo.MyTable
对目标数据库运行查询的位置,然后将其分配给 SSIS 变量 (@[User::StartingId]) . 然后,您在 Source 中的 select 语句上使用一个表达式,类似于"SELECT * FROM dbo.MyTable T WHERE T.SomeId > " + (DT_WSTR, 10) @[User::StartingId]
现在,当数据流开始时,它将从上次加载数据的地方开始。这种方法的挑战是找到那些您知道数据没有乱序插入的场景。
如果您有问题,需要更好的解释,图片等,请告诉我。此外,上面的代码是徒手编写的,因此可能存在语法错误,但逻辑应该是正确的。