我有一个SSIS包来向数据库插入/更新行。首先我使用查找检查行是否已经插入到DB;如果是,我更新该行,否则插入新行。
我的问题是插入时,成功插入了一行,但也重定向到错误。两者如何同时发生?这种情况有时并非总是发生 - 非常不一致。如何追踪导致错误的原因?我在这里使用“重定向行”来获取失败的行。
只有在服务器上部署时才会发生这种情况。使用BIDS运行我的本地计算机工作正常。
答案 0 :(得分:5)
您的OLE DB目标可能已设置为默认值
快速回顾所有这些值的含义
Table or view - fast load
或Table or view name variable - fast load
,因为这会执行批量插入。非快速加载选择会导致单例插入,对于任何数据量,您都会质疑那些告诉您SSIS可以非常快速地加载数据的人的理智。INSERT BULK
语句的传递值ROWS_PER_BATCH
。您的插入内容中存在错误数据。有些东西导致插入失败。它可能是第一行,最后一行,两者之间或介于两者之间。实际效果是刀片本身回滚。您设计了包以允许将错误数据路由到平面文件,以便数据管理员可以检查它,清理它并将其重新插入管道。
关键是你需要找到一些值来提供插入性能大小的最佳平衡,相对于不良大小,它会更好。为了论证,让我们使用5003
的提交大小,因为每个人都喜欢素数,并假设我们的数据源提供10009行数据。其中的三行将违反目标表的完整性,需要由数据管理员进行检查。
这将导致3个总批次被发送到目的地。结果是以下场景之一
我一直认为墨菲是一个乐观主义者,持有错误文件的磁盘会腐败但我离题了。
理想的是减少可能存在的坏数据空间,同时最大限度地提高一次性插入的良好数据量。实际上,有很多人已经写过这篇文章,但我不赞成使用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成功。当脚本失败时,它也将行移动到错误!
我试图捕捉这些"文件错误/异常"它有效!!