如何让SSIS等待文件存在和/或变得可用

时间:2012-05-03 08:00:19

标签: ssis

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

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

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

    1. 使用file in use task但如果任务开始时预期文件不存在(即方案1和2的错误),则会出现错误
    2. 使用file watcher task但似乎忽略了设计中的文件重命名,因此永远不会处理方案1或2
    3. 除了构建script task之外,还有一个自定义任务可以处理所有三种情况吗?

      编辑:SSIS 2008 R2

3 个答案:

答案 0 :(得分:0)

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

如果包2仅在package1完成后运行,情况1和2如何发生?据我所知,package1重命名文件,因此它只会在所有文件都是进程并重命名

时结束

编辑:

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

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

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

完成计数后,只需与TotalNumberOfFiles进行比较。如果相等,请转到下一个任务,否则请暂停一段时间并重新计算

答案 1 :(得分:0)

只有脚本任务可以帮助您。

考虑尽可能在脚本中使用FileSystemWatcher,或者使用可以使用FileSystemWatcher监视文件系统的应用程序/ Windows服务,并在触发事件时调用程序包。

答案 2 :(得分: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