如果没有要下载的文件,如何避免SSIS FTP任务失败?

thu*_*eek 18 sql-server ftp ssis

我正在使用SQL Server 2005,并在SSIS中创建ftp任务.

有时会有ftp文件,有时不会.如果没有文件,我不希望任务和包失败.我已经将箭头从ftp任务更改为下一个"完成",因此包运行完毕.我已将允许的错误数量更改为4(因为有4个ftp任务,并且4个目录中的任何一个可能有也可能没有文件).

但是,当我从代理中的作业运行包时,它将作业标记为失败.由于这将每15分钟运行一次,我不希望在我的工作历史中出现一堆红色x,这将导致我们在确实发生时不会发现问题.

如何在ftp任务中设置属性,以便不向ftp查找文件不是故障?我正在使用的操作是"发送文件".

以下是一些更多信息:文件位于服务器上,除了ftp之外我没有任何访问权限.而且,我提前不知道文件名.用户可以随意调用它们.所以我不能检查具体的文件,我认为,我可以检查.除了通过使用基于该连接的ftp连接和任务.这些文件位于远程服务器上,我想将它们复制到我的服务器上,以便从远程服务器上获取它们.

我可以在脚本任务中shell命令级别ftp.也许这就是我需要使用而不是ftp任务.(我已经更改为使用ftp命令行,带有一个参数文件,从脚本任务调用.当没有文件可以获取时它没有错误.我认为这个解决方案对我有用.我正在创建动态参数文件,这意味着我不需要在纯文本文件中有连接信息,而是可以存储在我的配置文件中,该文件位于更安全的位置.)

小智 14

检查此链接,该链接描述了在SSIS包中正常处理任务错误.

我有几乎相同的问题,但检索文件.我希望在FTP服务器上找不到文件时包不会失败.上面的链接会阻止错误冒泡并导致程序包失败; 你会想到FailPackageOnError = false应该做的事情吗?:-S

希望这也能为你解决它!


小智 14

我知道您已经找到了问题的答案.这适用于可能偶然发现此问题的其他用户.这是实现这一目标的一种可能方式.Script Task可用于查找给定模式的FTP文件夹路径中存在的文件列表(例如*.txt).下面的例子说明了如何做到这一点.

分步过程:

  1. 在SSIS包上,创建一个FTP Connection命名的FTP,并创建5个变量,如屏幕截图#1所示.变量RemotePath包含FTP文件夹路径; LocalPath包含文件将被下载到的文件夹; FilePattern包含文件模式,以查找要从FTP服务器下载的文件列表; FileName将填充Foreach loop container但是为了避免FTP任务设计时错误,它可以填充/DelayValidationFTP任务上的属性可以设置为True.

  2. 上SSIS包,放置Script Task,Foreach Loop containerFTP TaskForeach Loop container中截图#如图2.

  3. 使用" 脚本任务代码"部分下的代码替换其中的Main()方法.Script Task将使用与给定模式匹配的文件集合填充变量ListOfFiles.此示例将首先使用模式*.txt,它不会产生任何结果,然后会使用模式*.xls,它将匹配FTP服务器上的少量文件.Script Task

  4. 配置Foreach Loop container如屏幕截图#3和#4所示.此任务将循环遍历变量**ListOfFiles*.如果没有文件,循环容器内的FTP任务将不会执行.如果有文件,则循环容器内的FTP任务将针对FTP服务器上找到的文件数执行任务.

  5. 配置FTP Task如屏幕截图#5和#6所示.

  6. 屏幕截图#7显示了找到模式匹配文件时的示例包执行*.txt.

  7. 屏幕截图#8显示了执行包C:\temp\ 之前文件夹的内容.

  8. 屏幕截图#9显示了为模式找到匹配文件时的示例包执行*.xls.

  9. 屏幕截图#10显示了FTP远程路径的内容/Practice/Directory_New.

  10. 屏幕截图#11显示了执行包C:\temp\ 文件夹的内容.

  11. 屏幕截图#12显示了提供错误远程路径时的程序包故障.

  12. 屏幕截图#13显示了与程序包故障相关的错误消息.

希望有所帮助.

脚本任务代码:

可以使用的C#代码SSIS 2008 and above.

使用System.Text.RegularExpressions包含using语句;

public void Main()
{
    Variables varCollection = null;
    ConnectionManager ftpManager = null;
    FtpClientConnection ftpConnection = null;
    string[] fileNames = null;
    string[] folderNames = null;
    System.Collections.ArrayList listOfFiles = null;
    string remotePath = string.Empty;
    string filePattern = string.Empty;
    Regex regexp;
    int counter;

    Dts.VariableDispenser.LockForWrite("User::RemotePath");
    Dts.VariableDispenser.LockForWrite("User::FilePattern");
    Dts.VariableDispenser.LockForWrite("User::ListOfFiles");
    Dts.VariableDispenser.GetVariables(ref varCollection);

    try
    {
        remotePath = varCollection["User::RemotePath"].Value.ToString();
        filePattern = varCollection["User::FilePattern"].Value.ToString();

        ftpManager = Dts.Connections["FTP"];
        ftpConnection = new FtpClientConnection(ftpManager.AcquireConnection(null));
        ftpConnection.Connect();
        ftpConnection.SetWorkingDirectory(remotePath);
        ftpConnection.GetListing(out folderNames, out fileNames);
        ftpConnection.Close();

        listOfFiles = new System.Collections.ArrayList();
        if (fileNames != null)
        {
            regexp = new Regex("^" + filePattern + "$");
            for (counter = 0; counter <= fileNames.GetUpperBound(0); counter++)
            {
                if (regexp.IsMatch(fileNames[counter]))
                {
                    listOfFiles.Add(remotePath + fileNames[counter]);
                }
            }
        }

        varCollection["User::ListOfFiles"].Value = listOfFiles;
    }
    catch (Exception ex)
    {
        Dts.Events.FireError(-1, string.Empty, ex.ToString(), string.Empty, 0);
        Dts.TaskResult = (int) ScriptResults.Failure;
    }
    finally
    {
        varCollection.Unlock();
        ftpConnection = null;
        ftpManager = null;
    }

    Dts.TaskResult = (int)ScriptResults.Success;
}
Run Code Online (Sandbox Code Playgroud)

可以使用的VB代码SSIS 2005 and above.

包括Imports语句Imports System.Text.RegularExpressions

Public Sub Main()
    Dim varCollection As Variables = Nothing
    Dim ftpManager As ConnectionManager = Nothing
    Dim ftpConnection As FtpClientConnection = Nothing
    Dim fileNames() As String = Nothing
    Dim folderNames() As String = Nothing
    Dim listOfFiles As Collections.ArrayList
    Dim remotePath As String = String.Empty
    Dim filePattern As String = String.Empty
    Dim regexp As Regex
    Dim counter As Integer

    Dts.VariableDispenser.LockForRead("User::RemotePath")
    Dts.VariableDispenser.LockForRead("User::FilePattern")
    Dts.VariableDispenser.LockForWrite("User::ListOfFiles")
    Dts.VariableDispenser.GetVariables(varCollection)

    Try

        remotePath = varCollection("User::RemotePath").Value.ToString()
        filePattern = varCollection("User::FilePattern").Value.ToString()

        ftpManager = Dts.Connections("FTP")
        ftpConnection = New FtpClientConnection(ftpManager.AcquireConnection(Nothing))

        ftpConnection.Connect()
        ftpConnection.SetWorkingDirectory(remotePath)
        ftpConnection.GetListing(folderNames, fileNames)
        ftpConnection.Close()

        listOfFiles = New Collections.ArrayList()
        If fileNames IsNot Nothing Then
            regexp = New Regex("^" & filePattern & "$")
            For counter = 0 To fileNames.GetUpperBound(0)
                If regexp.IsMatch(fileNames(counter)) Then
                    listOfFiles.Add(remotePath & fileNames(counter))
                End If
            Next counter
        End If

        varCollection("User::ListOfFiles").Value = listOfFiles

        Dts.TaskResult = ScriptResults.Success

    Catch ex As Exception
        Dts.Events.FireError(-1, String.Empty, ex.ToString(), String.Empty, 0)
        Dts.TaskResult = ScriptResults.Failure
    Finally
        varCollection.Unlock()
        ftpConnection = Nothing
        ftpManager = Nothing
    End Try

    Dts.TaskResult = ScriptResults.Success
End Sub
Run Code Online (Sandbox Code Playgroud)

截图#1:

1

截图#2:

2

截图#3:

3

截图#4:

4

截图#5:

五

截图#6:

6

截图#7:

7

截图#8:

8

截图#9:

9

截图#10:

10

截图#11:

11

截图#12:

12

截图#13:

13


tri*_*e84 5

我刚刚遇到了这个问题,在阅读了这里的一些回复后,没有什么能真正解决我的问题,这里的解决方案在复杂性方面似乎很疯狂。

我的 FTP 任务失败了,因为我不允许覆盖文件,假设该作业连续启动了两次,第一次就可以了,因为某些文件已传输,但如果本地文件已存在,则会失败。

我的解决方案很简单:

  1. 右键单击任务 - 属性
  2. 设置 ForceExecutionResult = "成功"


Tom*_*m H 1

我没有给你打包的答案,但由于还没有其他人发布任何内容......

您应该能够在 ActiveX 脚本任务中设置一个变量,然后使用该变量来决定是否应运行 FTP 任务。这里有一个适用于本地路径的示例。希望您能够适应这个概念(或者如果可能的话,映射 FTP 驱动器并这样做)。