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
我知道您已经找到了问题的答案.这适用于可能偶然发现此问题的其他用户.这是实现这一目标的一种可能方式.Script Task可用于查找给定模式的FTP文件夹路径中存在的文件列表(例如*.txt).下面的例子说明了如何做到这一点.
分步过程:
在SSIS包上,创建一个FTP Connection命名的FTP,并创建5个变量,如屏幕截图#1所示.变量RemotePath包含FTP文件夹路径; LocalPath包含文件将被下载到的文件夹; FilePattern包含文件模式,以查找要从FTP服务器下载的文件列表; FileName将填充Foreach loop container但是为了避免FTP任务设计时错误,它可以填充/或DelayValidationFTP任务上的属性可以设置为True.
上SSIS包,放置Script Task,Foreach Loop container和FTP Task内Foreach Loop container中截图#如图2.
使用" 脚本任务代码"部分下的代码替换其中的Main()方法.Script Task将使用与给定模式匹配的文件集合填充变量ListOfFiles.此示例将首先使用模式*.txt,它不会产生任何结果,然后会使用模式*.xls,它将匹配FTP服务器上的少量文件.Script Task
配置Foreach Loop container如屏幕截图#3和#4所示.此任务将循环遍历变量**ListOfFiles*.如果没有文件,循环容器内的FTP任务将不会执行.如果有文件,则循环容器内的FTP任务将针对FTP服务器上找到的文件数执行任务.
配置FTP Task如屏幕截图#5和#6所示.
屏幕截图#7显示了未找到模式匹配文件时的示例包执行*.txt.
屏幕截图#8显示了执行包C:\temp\ 之前文件夹的内容.
屏幕截图#9显示了为模式找到匹配文件时的示例包执行*.xls.
屏幕截图#10显示了FTP远程路径的内容/Practice/Directory_New.
屏幕截图#11显示了执行包C:\temp\ 后文件夹的内容.
屏幕截图#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:

截图#2:

截图#3:

截图#4:

截图#5:

截图#6:

截图#7:

截图#8:

截图#9:

截图#10:

截图#11:

截图#12:

截图#13:

我刚刚遇到了这个问题,在阅读了这里的一些回复后,没有什么能真正解决我的问题,这里的解决方案在复杂性方面似乎很疯狂。
我的 FTP 任务失败了,因为我不允许覆盖文件,假设该作业连续启动了两次,第一次就可以了,因为某些文件已传输,但如果本地文件已存在,则会失败。
我的解决方案很简单: