我使用的是SQL Server 2005中,并创建SSIS中的FTP任务。
有时会有文件到FTP了,有时没有。 如果没有文件,我不想工作,也没有包失败。 我已经改变了箭头从FTP任务去旁边的“完成”,所以包贯穿。 我已经改变了错误的允许数量为4(因为有4个FTP任务,任何的4个目录可能会或可能不会有文件)。
但是,当我在代理作业运行包,它标志着工作作为失败。 由于这将是每15分钟一趟,我不想一堆红色的X在我的工作经历,这将导致当它确实发生我们没有看到一个问题。
如何设置FTP任务的属性,以便没有找到文件到FTP不是一个失败? 我使用的操作是“发送文件”。
下面是一些更多的信息:该文件是我没有任何访问都通过FTP之外的服务器上。 而且,我不知道文件名的时间提前。 用户可以打电话给他们为所欲为。 因此,我不能检查特定的文件,也没有,我想,我可以检查的。 除了通过使用基于该连接的FTP连接和任务。 该文件是在远程服务器上,我想他们在复制到我的服务器,从该远程服务器获取它们。
我可以在脚本任务外壳命令级别的FTP。 也许这就是我需要使用,而不是FTP任务。 (我已经改变使用FTP命令行,以参数文件,从脚本任务调用。当没有文件就搞定了。我觉得这个解决方案是要为我工作。我创造了它没有给出错误动态参数文件,这意味着我不需要在纯文本文件的连接信息,而是可以存储在我的配置文件,它是在一个更安全的地方。)
Answer 1:
我明白,你已经找到了问题的答案。 这是就这个问题谁可能绊倒其他用户。 下面是实现这一目标的一个可能的方式。 Script Task
可以用来找到一个给定模式存在的FTP文件夹路径的文件列表(比如*.txt
)。 下面的示例演示如何可以做到这一点。
一步一步的过程:
上SSIS包,创建一个FTP Connection
命名FTP并且如图截图#1还创建5个变量。 可变RemotePath
包含FTP文件夹路径; LocalPath
包含其中的文件将被downloaed文件夹; FilePattern
包含文件模式来查找文件从FTP服务器下载的列表; FileName
会被填充Foreach loop container
但要避免FTP任务设计时错误,它可以与填充/或DelayValidation
对FTP任务属性可以设置为True。
上SSIS包,放置一个Script Task
, Foreach Loop container
和FTP Task
的内Foreach Loop container
中所示的屏幕截图#2。
取代Main()
的内方法Script Task
与下脚本任务代码部分的代码。 脚本任务将填充变量ListOfFiles匹配给定模式的文件的集合。 这个例子将首先使用模式* .TXT,这样产生的结果,然后后来模式的* .xls,将匹配在FTP服务器上一些文件。
配置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
。
包括using
使用System.Text.RegularExpressions声明;
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;
}
VB代码,可以用在SSIS 2005 and above
。
包括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
截图#1:
屏幕截图2:
屏幕截图3:
屏幕截图4:
截图#5:
屏幕截图6:
截图#7:
屏幕截图8:
截图#9:
屏幕截图10:
屏幕截图11:
屏幕截图12:
屏幕截图13:
Answer 2:
检查此链接 ,描述关于适当地处理任务的错误在SSIS包。
我几乎同样的问题,但是,与检索文件。 我想包时FTP服务器上没有发现文件不失败。 以上的链接停止错误冒泡以及使所述包失败; 东西你会想到FailPackageOnError =假应该做的? :-S
希望这也解决了它为您服务!
Answer 3:
我只是有这个问题,阅读一些答复这里经过,没有什么能跟我的问题和解决方案在这里在复杂性方面显得疯狂。
我的FTP任务失败,因为我没有允许覆盖文件,可以说工作是在一排拉开序幕两次,第一遍会被罚款,因为一些文件被转移了,但如果本地文件已经存在,就会失败。
我的解决方案很简单:
- 右键单击任务 - 属性
- 设置ForceExecutionResult =“成功”
Answer 4:
(我不能接受我自己的答案,但是这是为我工作的解决方案。)
它可能不是最好的解决办法,但这个工程。
我使用脚本任务,有一堆的FTP连接信息变量,以及源和目标目录。 (因为,我们将改变,这是上运行的服务器,它会更容易在配置包更改。)
我动态创建一个文本文件,并写入FTP命令它:
Dim ftpStream As StreamWriter = ftpFile.CreateText()
ftpStream.WriteLine(ftpUser)
ftpStream.WriteLine(ftpPassword)
ftpStream.WriteLine("prompt off")
ftpStream.WriteLine("binary")
ftpStream.WriteLine("cd " & ftpDestDir)
ftpStream.WriteLine("mput " & ftpSourceDir)
ftpStream.WriteLine("quit 130")
ftpStream.Close()
然后,给它足够的时间非常接近后,我开始一个进程做ftp命令:
ftpParameters = "-s:" & ftpParameterLoc & ftpParameterFile & " " & ftpServer
proc = System.Diagnostics.Process.Start("ftp", ftpParameters)
然后,给它的FTP过程中的一些更多的时间来运行之后,我删除临时FTP文件(已在它的连接信息!)。
如果源目录中不存在的文件(该变量的\\驱动器\目录\ *。*映射),那么就没有错误。 如果某些其他错误发生,任务仍然失败,因为它应该。
我是新来的SSIS,这可能是一个杂牌。 但是,它适用于现在。 我想我问的最佳方式,我就肯定不会声称这是它。
正如我指出的那样,我不知道什么是文件命名,或者即使有任何文件存在一样的方式。 如果他们在那里,我想他们。
Answer 5:
我没有打包的答案,但因为没有其他人发布任何...
您应该能够设置一个变量在一个ActiveX脚本任务,然后用它来决定FTP任务是否应该运行。 有一个例子在这里 ,与本地路径的作品。 希望你能适应的概念(或如果可能的话,映射FTP驱动器和这样做的)。
Answer 6:
1)设置FTP任务属性ForceExecutionResult =成功
2)该代码添加到FTP任务OnError事件处理程序。
public void Main()
{
// TODO: Add your code here
int errorCode = (int)Dts.Variables["System::ErrorCode"].Value;
if (errorCode.ToString().Equals("-1073573501"))
{
Dts.Variables["System::Propagate"].Value = false;
}
else
{
Dts.Variables["System::Propagate"].Value = true;
}
Dts.TaskResult = (int)ScriptResults.Success;
}
Answer 7:
把它放在一个Foreach容器,在文件迭代上传哪些。 没有文件,没有FTP,没有失败。
Answer 8:
您可以在失败重定向到一个什么也不做,即只返回true脚本的另一个任务。
要做到这一点,添加新的脚本任务,突出你的FTP任务,第二次绿色连接将出现,这拖到脚本任务,然后双击它。 在价值选择失败降下来了。 显然,您则需要处理真正的失败,在此脚本任务就在作业历史记录仍然显示。
Answer 9:
啊哈,OK - 感谢澄清。 由于FTP任务不能返回一个文件夹列表,将不可能使用ForEach就像我一开始说的 - 那只有当你要上传的文件X量到远程源工作。
要下载文件的X量,你可以去两种方式,要么你可以在脚本任务全部做在.NET中,也可以从.NET脚本任务中通过的ArrayList填充文件名的ArrayList,那么的ForEach ,传递文件名的变量和一个标准的FTP任务下载该变量名。
代码示例,以适应: http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=2472491&SiteID=1
:那么,在上面,你会得到的文件名()和填充从ArrayList中,ArrayList然后使用代码类似分配给Dts.Variables,然后过的ForEach对象是(ArrayList的)变量的对象类型变量的HTTP ://www.sqlservercentral.com/articles/SSIS/64014/
Answer 10:
您可以从eaSkills使用免费的SSIS FTP任务++。 它不会抛出一个错误,如果该文件或文件不存在,它支持通配符并为您提供下载,如果你需要的话删除选项。
这里的链接到专题页面: http://www.easkills.com/ssis/ftptask
Answer 11:
这是为我工作,使用内置的东西,因此无需手动重新写入FTP逻辑另一种解决方案:
1)创建你的包称为可变FTP_Error
2)单击您的FTP任务,然后单击“事件处理程序”选项卡
3)单击页面内创建“FTP任务/的OnError”的事件处理程序 - 每当有与FTP麻烦这会火
4)从工具箱中,脚本任务物品拖动,双击打开了
5)在第一个弹出,ReadOnlyVariables - 添加系统::错误代码,系统:: ErrorDescription中
6)在第一个弹出,ReadWriteVariables - 添加用户:: FTP_Error变量
7)编辑脚本
8)在脚本设置你的FTP_Error变量来保存我们上面有ReadOnlyVariables:
Dts.Variables["FTP_Error"].Value = "ErrorCode:" + Dts.Variables["ErrorCode"].Value.ToString() + ", ErrorDescription=" + Dts.Variables["ErrorDescription"].Value.ToString();
9)保存并关闭脚本
10)点击“确定”脚本任务
11)返回到“控制流”选项卡
12)从FTP任务的OnError去一个新的脚本任务,并编辑
13)ReadOnlyVariables:用户:: FTP_Error从之前
14)现在,当没有对FTP找到的文件,错误代码为-1073573501(你可以在这里找到错误代码引用列表: http://msdn.microsoft.com/en-us/library/ms345164.aspx )
15)在你的脚本,放在逻辑做你想做什么 - 如果你找到一个“找不到文件”的代码,那么也许你说的任务成功。 如果没有,则任务失败。 而当你希望你的正常流动可以处理这个问题:
if (Dts.Variables["FTP_Error"].Value.ToString().Contains("-1073573501"))
{
// file not found - not a problem
Dts.TaskResult = (int)ScriptResults.Success;
}
else
{
// some other error - raise alarm!
Dts.TaskResult = (int)ScriptResults.Failure;
}
并从那里你的成功/失败的流动会做你想用它做什么。
Answer 12:
另一种方法是使用FTP文件枚举
文章来源: How to avoid SSIS FTP task from failing when there are no files to download?