我正在开发一个将日志记录添加到SSIS包中的项目。我通过实现一些事件处理程序来进行自己的自定义日志记录。我已经实现了OnInformation事件,将时间,源名称和消息写入日志文件。当数据从一个表移动到另一个表时,OnInformation事件将给我一条消息,如:
组件“TABLENAME”(1)“写了87行。
如果其中一行失败,并且假设只有85行被处理出预期的87.我会假设上面的行会读取wrote 85 rows
。在这种情况下,如何跟踪应该处理的行数?我希望看到类似wrote 85 of 87 rows
的内容。基本上,我想我需要知道如何从Source的查询中获取返回的行数。有一个简单的方法吗?
谢谢
答案 0 :(得分:6)
您可以在数据源之后使用Row Count transaformation
并将其保存为变量。这将是要处理的行数。加载到目标后,您应该使用Execute SQL Task
中的Control flow
并使用Select Count(*) from <<DestinationTable>>
并将计数保存到其他变量[您应该使用查询中的Where子句来识别当前负荷]。因此,您将处理数字行以进行记录。
希望这有帮助!
答案 1 :(得分:4)
评论中没有足够的空间来提供反馈。发布一份不完整的答案,因为我需要离开这一天。
你将无法完成你所要求的东西。根据您在Gowdhaman008的答案中的评论,在终结器事件触发之前,变量的值在数据流之外是不可见的(我认为是OnPostExecute)。您可以通过使用脚本任务来计算行和计算事件(自定义或预定义)以报告包进度,从而欺骗并获取数据。实际上,只需捕获OnPipelineRowsSent
事件即可。这将记录通过特定接合点和周围时间的行数。 SSIS Performance Framework另外,您不必对自己的东西进行任何定制工作或维护。开箱即用的功能是一个明确的胜利。
那就是说,在完成之前,你真的不知道有多少行来自一个源。这听起来很愚蠢,我完全同意,但这是事实。想象一个简单的案例,一个OLE DB源,它将直接向OLE DB目的地发送1,000,000行。最有可能的是,并非所有1M行都将在管道中启动,可能只有10k将在第一个缓冲区中。这些缓冲区被推送到目的地,现在您知道已经处理了10k行中的10k行。泡沫,冲洗,重复几次,在这个缓冲区中,一行有一个NULL,它不应该。热潮走向炸药,过程失败。我们有60k行流到管道中,这就是我们所知道的因为失败。
确保我们考虑所有源行的唯一方法是将异步转换放入管道中以阻止所有下游组件,直到所有数据都到达为止。这将消除你从包装中获得良好表现的任何机会。您仍然需要遵守上述更新变量的限制,但FireXEvent消息将准确描述队列中可以处理的行数。
如果你启动了一个显式事务,你可以做一些丑陋的事情,比如执行SQL任务只是为了获得预期的计数,将其写入变量然后记录已处理的行,但是你要双重查询数据并增加由于双泵,阻塞源系统的可能性。这只适用于像数据库这样的东西。相同的概念适用于平面文件,除非您现在需要脚本任务才能首先读取所有行。
这更加丑陋的是一个缓慢的起始数据源,如Web服务。默认缓冲区大小可能导致整个程序包运行的时间比简单需要的时间长,因为我们正在等待数据到达Slow starts
我使用行计数录制我的starting and error counts(以及更多)。这将帮助您考虑所有来自的数据和去向的数据。然后我打开OnPipelineRowsSent
事件,让我查询日志,看看现在有多少行正在流过它。
答案 2 :(得分:2)
你想要的是Row Count transformation。只需在源查询后将其添加到数据流中,并将其输出分配给变量。然后,您可以将该变量写入日志文件。
答案 3 :(得分:0)
这是我目前的工作。这很繁琐,但是可以。
2)我在所有记录上都有一个恒定的“ 1”值。它们实际上是相同的。
3)使用多播步骤,我向两个方向发送数据流。尽管所有条件都相同,但我们仍然必须按该常量值进行排序。
4)使用聚合步骤对该常数进行聚合,然后重新排序以与底部数据流结合(该数据流保留所有实际数据记录而无聚合)。
这样做可以让我拥有初始行数。
如果行数不相同,则说明有问题。
这是无需使用其他数据流步骤即可解决问题的方法的总体思路。
TLDR:
使用多播获取条件之一的行数,按某个常量值排序,然后进行聚合。
进行排序并合并以获取行数。
使用条件拆分,然后再做一次。
如果前行和后行计数相同,请执行此操作。
如果前行和后行计数不同,请这样做。
答案 4 :(得分:-2)
如果您有一个没有错误数据的列,这可能会有所帮助。将第二个平面文件源添加到包中。使用与现有文件源相同的连接。仅选择第一列,并将输出定向到行计数。