2

场景:Package#1 创建一个包含多条消息(每行一条)的平面文件,该文件被放置在外部系统的“INPUT”文件夹中。该文件由外部系统拾取并处理,响应以相同格式写入“OUTPUT”文件夹中的文件。该文件在外部系统仍在处理消息时开始写入,因此将其写入为 foo.rsppro。当处理完成并写入所有响应消息时,它被重命名为 foo.rsp。

一旦完成(即重命名之后)并使用Package#2 处理该文件,我需要获取该文件,该文件将在Package#1 之后立即开始。当 Package#2 启动时,外部系统可能处于三种状态:

  1. 处理第一条消息尚未完成且尚未写入响应文件,在这种情况下我需要等待 foo.rsppro 被写入,然后重命名为 foo.rsp
  2. 正在处理并写入 foo.rsppro,在这种情况下,我需要等待 foo.rsppro 重命名为 foo.rsp
  3. 处理完成,foo.rsppro 已经编写完成并重命名为 foo.rsp,此时我只需要处理 foo.rsp。

我努力了:

  1. 使用正在使用的文件任务,但如果在任务开始时预期文件不存在,则会出错(即场景 1 和 2 的错误)
  2. 使用文件观察任务,但似乎忽略了文件重命名设计,因此永远不会处理场景 1 或 2

除了构建脚本任务之外,是否有可以处理所有三种场景的自定义任务?

编辑:SSIS 2008 R2

4

3 回答 3

0

嗯,似乎您可以通过在输出文件夹上使用 for each 循环容器并将其设置为只读 .rsp 文件来解决它。这将处理您的 .rsp 文件。

如果包 2 仅在包 1 完成后运行,场景 1 和 2 怎么会发生?据我了解, package1 重命名文件,因此它只会在所有文件都是进程并重命名时结束

编辑:

好的,不用担心,一切都有解决方案。怎么样,你在 package1 上创建一个名为 @TotalNumberOfFiles 的变量,其中包含要处理的文件总数,然后你使用 package 1 来调用 pacakge2 (不确定你是否已经这样做了,但如果不是很简单,只需使用执行 pacakge 任务)并在 package2 上创建一个“父包变量”(如果您从未做过,这也很简单),并且包 2 只是在输出文件夹上有带有 .rsp 扩展名的 @TotalNumberOfFiles 文件时开始处理?

EDIT2:我不知道 jf 有一个命令可以得到它,也许谷歌它,但如果你没有发现你可以添加一个指向输出目录的 foreachloop 容器并在脚本任务上做这样的事情:

Public Sub Main()
        Dts.Variables("User::filesCount").Value = Dts.Variables("User::FilesCount").Value + 1
        Dts.TaskResult = ScriptResults.Success
    End Sub

完成计数后,只需与 TotalNumberOfFiles 进行比较。如果相等,则进行下一个任务,否则休眠一段时间再计数

于 2012-05-03T08:22:00.650 回答
0

在您的情况下,只有脚本任务可以提供帮助。

如果可能,请考虑在脚本中使用 FileSystemWatcher,或者拥有一个应用程序/Windows 服务,该服务可以使用 FileSystemWatcher 监视文件系统并在触发事件时调用您的包。

于 2012-05-03T10:17:25.390 回答
0

最终使用的代码如下。基本上循环直到找到文件或达到指定的最大尝试次数。 Imports System.Threading是必需的Thread.sleep。它可能不是处理器效率最高的方法,但这是 100% 专用硬件,并且包是串行运行的。

'loop until number of required attempts is hit or file is found
        Do Until iCounter = iAttempts Or bFileFound = True

            'Check if the file exists
            If File.Exists(sFilename) Then

                'Switch bFileFound to true
                bFileFound = True

                'Report that file has been found to VERIFY_Input_File_Exists_INT variable
                Dts.Variables("VERIFY_Input_File_Exists_INT").Value = True

                Dts.Events.FireInformation(1, "DEBUG:", sFilename & " found successfully.", "", 0, False)

            Else

                'sleep for specified time
                Thread.Sleep(iInterval * 1000)

                Dts.Events.FireInformation(1, "DEBUG:", sFilename & " not found successfully. Sleeping for " & iInterval & "* 1000", "", 0, False)

            End If

            'increment counter
            iCounter = iCounter + 1

        Loop
于 2012-07-03T14:51:14.543 回答