我有一个 SSIS 包来插入/更新行到数据库。首先,我使用查找来检查行是否已插入数据库;如果是,我更新该行,否则作为新行插入。
我的问题是插入时,成功插入一行但也重定向到错误。两者怎么可能同时发生?这也发生在某些时候并不总是 - 非常不一致。如何跟踪导致错误的原因?我在这里使用“重定向行”来获取失败的行。
仅当它部署在服务器上时才会发生这种情况。在使用 BIDS 运行我的本地计算机时工作正常。
您的 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 目标进行错误重定向”中概述的方法。
我们将以我们的初始提交大小执行插入,5003
并且成功的行将按原样进行。坏行将转到第二个 OLE DB 目标,这一次提交大小较小。您是否应该立即在此处进行单例插入或添加中间批量插入尝试以您的主要提交大小的一半存在意见分歧。在这里您可以评估您的流程并为您的数据找到最佳解决方案。
如果数据仍然无法在单行级别插入,则将其写入错误文件/日志。当您知道将有坏数据时,这种方法允许您以最有效的机制将尽可能多的好数据放入目标表中。
然而,插入坏数据的最后一种方法是甚至不尝试插入它。如果您知道必须满足外键,请在您的数据流中添加一个查找组件,以确保只有好的值被呈现给插入。NULL 也一样。您已经在检查您的业务密钥,因此重复应该不是问题。如果列有 Foo 必须以 Pity 开头的约束,则在数据流中检查它。坏行都被分流到派生列任务,该任务添加了业务友好的错误消息,然后它们降落在 Union All 中,然后所有错误都进入错误文件。
我还编写了这个逻辑,其中每个检查都有自己的错误列,并且我只在插入之前拆分坏数据。这可以防止业务用户修复源数据中的一个错误,而只是得知还有另一个错误。哦,还有一个,再试一次。是否需要这种级别的数据清理是与您的数据供应商、数据清理人员以及可能是您的老板的对话(因为他们可能想知道您将需要花费多少时间为他们的可怕数据制作这个解决方案继续向你扔)
我注意到,如果您检查锁定表,并且还有更新,您将在数据流中的 2 个流之间出现死锁。所以我们不检查表锁。表现似乎是一样的。
我的发现可能会帮助那些访问这里的人..
@billinkc 发表了广泛的评论;我已经经历了这一切。好吧,后来在挖掘系统之后,问题就有所不同了。
我的 SSIS 包中有脚本任务来执行一些操作。那个使用磁盘中名为 TEMP 的文件夹。触发此 SSIS 的程序也同时使用相同的 TEMP 文件夹。现在没有处理文件读/写异常。这导致脚本任务失败导致包失败错误。由于脚本任务之前携带的INSERT功能,INSERT成功。后来当脚本失败时,它也将行移动到错误!
我尝试捕捉这些“文件错误/异常”并且它有效!