SSIS;即使插入数据库后,行也会重定向到错误

时间:2014-10-10 09:42:55

标签: ssis ssis-2012

我有一个SSIS包来向数据库插入/更新行。首先我使用查找检查行是否已经插入到DB;如果是,我更新该行,否则插入新行。

我的问题是插入时,成功插入了一行,但也重定向到错误。两者如何同时发生?这种情况有时并非总是发生 - 非常不一致。如何追踪导致错误的原因?我在这里使用“重定向行”来获取失败的行。

enter image description here

只有在服务器上部署时才会发生这种情况。使用BIDS运行我的本地计算机工作正常。

3 个答案:

答案 0 :(得分:5)

您的OLE DB目标可能已设置为默认值

enter image description here

快速回顾所有这些值的含义

  • 数据访问模式:您通常需要Table or view - fast loadTable or view name variable - fast load,因为这会执行批量插入。非快速加载选择会导致单例插入,对于任何数据量,您都会质疑那些告诉您SSIS可以非常快速地加载数据的人的理智。
  • 保持身份:只有在您想明确提供身份种子时才需要这样做
  • 保留空值:这指定是否应允许默认值触发
  • 表锁:抢先锁定表。除非您正在处理Hekaton表(新的SQL Server 2014糖果),否则触摸表将涉及锁定。是的,即使您使用NOLOCK提示。插入数据显然会导致锁定,因此我们可以确保遵守ACID。 SQL Server将从一个小锁开始,无论是行级还是页级。如果跨越修改数据的阈值,SQL Server将升级该锁以封装整个表。这是一种性能优化,因为如果没有其他人在数据中拥有肮脏的小爪子,它会更容易工作。罚款是在这次升级期间,我们现在可能需要等待另一个流程完成,以便我们可以获得排他性。如果我们开始变大,我们可能会在其他过程开始之前锁定桌子。 - 检查约束:我们应该禁用约束值的检查。除非您有导入后步骤以确保约束有效,否则请勿取消选中此项。快速加载对域无效的数据是不行的。
  • 每批次行:这是INSERT BULK语句的传递值ROWS_PER_BATCH
  • 最大插入提交大小:FastLoadMaxInsertCommitSize属性指定在提交之前应在事务中保留多少行。 2005年的默认值是0,这意味着一切都会被提交,或者没有提交。根据您的数据量,2008年的默认值20亿可能实际上是相同的。

那是什么

您的插入内容中存在错误数据。有些东西导致插入失败。它可能是第一行,最后一行,两者之间或介于两者之间。实际效果是刀片本身回滚。您设计了包以允许将错误数据路由到平面文件,以便数据管理员可以检查它,清理它并将其重新插入管道。

关键是你需要找到一些值来提供插入性能大小的最佳平衡,相​​对于不良大小,它会更好。为了论证,让我们使用5003的提交大小,因为每个人都喜欢素数,并假设我们的数据源提供10009行数据。其中的三行将违反目标表的完整性,需要由数据管理员进行检查。

这将导致3个总批次被发送到目的地。结果是以下场景之一

  • 错误的行是最后3行,导致只有3行被发送到文本文件,并且有2批10006行被提交到表中。
  • 错误行仅存在于1个完整集中。这将导致5006行写入表,5003行发送到我们的文件
  • 在每个提交集之间拆分错误的行。这会导致写入表中的0行以及文件中的所有数据。

我一直认为墨菲是一个乐观主义者,持有错误文件的磁盘会腐败但我离题了。

理想的是减少可能存在的坏数据空间,同时最大限度地提高一次性插入的良好数据量。实际上,有很多人已经写过这篇文章,但我不赞成使用OLE DB Destination"" Error Redirection with OLE DB Destination"中概述的方法。

我们将以5003的初始提交大小执行插入,成功的行将按原样执行。错误的行将转到第二个OLE DB目标,这次使用较小的提交大小。您是否应立即转到此处的单例插入或以主要提交大小的一半添加中间批量插入尝试存在意见分歧。您可以在此评估流程并找到最佳的数据解决方案。

如果数据仍然在单行级别插入失败,那么您将其写入错误文件/日志。这种方法允许您在知道自己有不良数据的情况下,尽可能以最有效的机制将尽可能多的好数据放入目标表中。

错误的数据附录

然而,插入错误数据的最后一种方法是甚至不尝试插入它。如果您知道必须满足外键,请在数据流中添加一个Lookup组件,以确保只向插件提供好的值。对于NULL也是如此。您已经在检查自己的业务密钥,因此重复项不应成为问题。如果列具有Foo必须以Pity开头的约束,则在数据流中检查它。错误的行全部被分流到派生列任务,它添加了业务友好的错误消息,然后它们降落在Union All,然后所有错误都会转到错误文件。

我还编写了这个逻辑,其中每个检查都有自己的错误列,我只在插入之前拆分了坏数据。这可以防止业务用户修复源数据中的一个错误,只是为了了解另一个错误。哦,还有另一个,请再试一次。是否需要这种级别的数据清理是与您的数据提供者,数据清理人员以及可能与您的老板的对话(因为他们可能想知道您需要花多少时间来为这个可怕的解决方案做出这个解决方案的证据他们不断向你投去的数据)

参考

答案 1 :(得分:1)

我注意到,如果检查锁定表并且还有更新,则会在数据流中的两个流之间出现死锁。所以我们不检查表锁。表现似乎是一样的。

答案 2 :(得分:0)

我的发现可能会帮助那些访问这里的人。

@billinkc发表了广泛的评论;我已经完成了整个过程。在挖掘系统之后,问题出现了不同。

我的SSIS包里面有脚本任务来做一些操作。那个在磁盘中使用一个名为TEMP的文件夹。触发这个SSIS的程序也同时使用相同的TEMP文件夹。现在没有处理文件读/写异常。 这导致脚本任务失败,导致程序包失败错误。由于在脚本任务之前执行INSERT功能,INSERT成功。当脚本失败时,它也将行移动到错误!

我试图捕捉这些"文件错误/异常"它有效!!